From 8049caa6a145b280dd8f09aacb21eb9c7e012b7f Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Thu, 1 Feb 2018 11:47:38 +0900 Subject: [PATCH 001/153] update Julia Commit d2ab4d80ae --- codex/NEWS.md | 31 ++- codex/base/base.md | 26 +-- codex/base/collections.md | 6 +- codex/base/io-network.md | 4 +- codex/base/punctuation.md | 2 +- codex/devdocs/gc-sa.md | 291 ++++++++++++++++++++++++++ codex/manual/documentation.md | 6 +- codex/manual/environment-variables.md | 4 +- codex/manual/functions.md | 4 +- codex/manual/getting-started.md | 4 +- codex/manual/interfaces.md | 65 +++--- codex/manual/packages.md | 4 +- codex/manual/parallel-computing.md | 17 +- codex/manual/strings.md | 20 +- codex/manual/style-guide.md | 4 +- codex/manual/types.md | 2 +- codex/stdlib/InteractiveUtils.md | 25 +++ codex/stdlib/LinearAlgebra.md | 5 +- codex/stdlib/Markdown.md | 1 + codex/{base/pkg.md => stdlib/Pkg.md} | 36 ++-- codex/stdlib/REPL.md | 2 +- codex/stdlib/UUIDs.md | 7 + codex/stdlib/linearalgebra.md | 5 +- make.jl | 7 +- src/NEWS.md | 31 ++- src/base/base.md | 26 +-- src/base/collections.md | 6 +- src/base/io-network.md | 4 +- src/base/punctuation.md | 2 +- src/devdocs/gc-sa.md | 291 ++++++++++++++++++++++++++ src/manual/documentation.md | 6 +- src/manual/environment-variables.md | 4 +- src/manual/functions.md | 4 +- src/manual/getting-started.md | 6 +- src/manual/interfaces.md | 65 +++--- src/manual/packages.md | 4 +- src/manual/parallel-computing.md | 17 +- src/manual/strings.md | 20 +- src/manual/style-guide.md | 4 +- src/manual/types.md | 2 +- src/stdlib/InteractiveUtils.md | 25 +++ src/stdlib/LinearAlgebra.md | 5 +- src/stdlib/Markdown.md | 1 + src/{base/pkg.md => stdlib/Pkg.md} | 36 ++-- src/stdlib/REPL.md | 2 +- src/stdlib/UUIDs.md | 7 + src/stdlib/linearalgebra.md | 5 +- 47 files changed, 919 insertions(+), 232 deletions(-) create mode 100644 codex/devdocs/gc-sa.md create mode 100644 codex/stdlib/InteractiveUtils.md create mode 100644 codex/stdlib/Markdown.md rename codex/{base/pkg.md => stdlib/Pkg.md} (66%) create mode 100644 codex/stdlib/UUIDs.md create mode 100644 src/devdocs/gc-sa.md create mode 100644 src/stdlib/InteractiveUtils.md create mode 100644 src/stdlib/Markdown.md rename src/{base/pkg.md => stdlib/Pkg.md} (66%) create mode 100644 src/stdlib/UUIDs.md diff --git a/codex/NEWS.md b/codex/NEWS.md index 83b839b..b92a80a 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -196,6 +196,9 @@ Breaking changes This section lists changes that do not have deprecation warnings. + * `readuntil` now does *not* include the delimiter in its result, matching the + behavior of `readline`. Pass `keep=true` to get the old behavior ([#25633](https://github.com/JuliaLang/julia/issues/25633)). + * `getindex(s::String, r::UnitRange{Int})` now throws `UnicodeError` if `last(r)` is not a valid index into `s` ([#22572](https://github.com/JuliaLang/julia/issues/22572)). @@ -305,7 +308,9 @@ This section lists changes that do not have deprecation warnings. This avoids stack overflows in the common case of definitions like `f(x, y) = f(promote(x, y)...)` ([#22801](https://github.com/JuliaLang/julia/issues/22801)). - * `findmin`, `findmax`, `indmin`, and `indmax` used to always return linear indices. + * `indmin` and `indmax` have been renamed to `argmin` and `argmax`, respectively ([#25654](https://github.com/JuliaLang/julia/issues/25654)). + + * `findmin`, `findmax`, `argmin`, and `argmax` used to always return linear indices. They now return `CartesianIndex`es for all but 1-d arrays, and in general return the `keys` of indexed collections (e.g. dictionaries) ([#22907](https://github.com/JuliaLang/julia/issues/22907)). @@ -383,6 +388,10 @@ This section lists changes that do not have deprecation warnings. and higher-dimensional arrays insted of linear indices as was previously the case. Use `LinearIndices(a)[findall(f, a)]` and similar constructs to compute linear indices. + * The `Base.HasShape` iterator trait has gained a type parameter `N` indicating the + number of dimensions, which must correspond to the length of the tuple returned by + `size` ([#25655](https://github.com/JuliaLang/julia/issues/25655)). + * `AbstractSet` objects are now considered equal by `==` and `isequal` if all of their elements are equal ([#25368](https://github.com/JuliaLang/julia/issues/25368)). This has required changing the hashing algorithm for `BitSet`. @@ -511,7 +520,7 @@ Library improvements has been changed to `KeySet{K, <:Associative{K}} <: AbstractSet{K}` ([#24580](https://github.com/JuliaLang/julia/issues/24580)). * New function `ncodeunits(s::AbstractString)` gives the number of code units in a string. - The generic definition is constant time but calls `endof(s)` which may be inefficient. + The generic definition is constant time but calls `lastindex(s)` which may be inefficient. Therefore custom string types may want to define direct `ncodeunits` methods. * `reverseind(s::AbstractString, i::Integer)` now has an efficient generic fallback, so @@ -959,8 +968,15 @@ Deprecated or removed * `findin(a, b)` has been deprecated in favor of `findall(occursin(b), a)` ([#24673](https://github.com/JuliaLang/julia/issues/24673)). + * `module_name` has been deprecated in favor of a new, general `nameof` function. Similarly, + the unexported `Base.function_name` and `Base.datatype_name` have been deprecated in favor + of `nameof` methods ([#25622](https://github.com/JuliaLang/julia/issues/25622)). + * The module `Random.dSFMT` is renamed `Random.DSFMT` ([#25567](https://github.com/JuliaLang/julia/issues/25567)). + * `Random.RandomDevice(unlimited::Bool)` (on non-Windows systems) is deprecated in favor of + `Random.RandomDevice(; unlimited=unlimited)` ([#25668](https://github.com/JuliaLang/julia/issues/25668)). + * The generic implementations of `strides(::AbstractArray)` and `stride(::AbstractArray, ::Int)` have been deprecated. Subtypes of `AbstractArray` that implement the newly introduced strided array interface should define their own `strides` method ([#25321](https://github.com/JuliaLang/julia/issues/25321)). @@ -971,12 +987,23 @@ Deprecated or removed * `rand(t::Tuple{Vararg{Int}})` is deprecated in favor of `rand(Float64, t)` or `rand(t...)`; `rand(::Tuple)` will have another meaning in the future ([#25429](https://github.com/JuliaLang/julia/issues/25429), [#25278](https://github.com/JuliaLang/julia/issues/25278)). + * The `assert` function (and `@assert` macro) have been documented that they are not guaranteed to run under various optimization levels and should therefore not be used to e.g. verify passwords. + * `ObjectIdDict` has been deprecated in favor of `IdDict{Any,Any}` ([#25210](https://github.com/JuliaLang/julia/issues/25210)). * `gc` and `gc_enable` have been deprecated in favor of `GC.gc` and `GC.enable` ([#25616](https://github.com/JuliaLang/julia/issues/25616)). * `Base.@gc_preserve` has been deprecated in favor of `GC.@preserve` ([#25616](https://github.com/JuliaLang/julia/issues/25616)). + * `scale!` has been deprecated in favor of `mul!`, `lmul!`, and `rmul!` ([#25701](https://github.com/JuliaLang/julia/issues/25701), [#25812](https://github.com/JuliaLang/julia/issues/25812)). + + * `endof(a)` has been renamed to `lastindex(a)`, and the `end` keyword in indexing expressions now + lowers to either `lastindex(a)` (in the case with only one index) or `lastindex(a, d)` (in cases + where there is more than one index and `end` appears at dimension `d`) ([#23554](https://github.com/JuliaLang/julia/issues/23554), [#25763](https://github.com/JuliaLang/julia/issues/25763)). + + * `DateTime()`, `Date()`, and `Time()` have been deprecated, instead use `DateTime(1)`, `Date(1)` + and `Time(0)` respectively ([#23724](https://github.com/JuliaLang/julia/issues/23724)). + Command-line option changes --------------------------- diff --git a/codex/base/base.md b/codex/base/base.md index ff24b70..e14de8d 100644 --- a/codex/base/base.md +++ b/codex/base/base.md @@ -19,17 +19,9 @@ Some general notes: ```@docs Base.exit -Base.quit Base.atexit Base.isinteractive -Base.varinfo Base.summarysize -Base.edit(::AbstractString, ::Integer) -Base.edit(::Any) -Base.@edit -Base.less(::AbstractString) -Base.less(::Any) -Base.@less Base.clipboard(::Any) Base.clipboard() Base.require @@ -38,14 +30,9 @@ Base.__precompile__ Base.include Base.include_string Base.include_dependency -Base.Docs.apropos Base.which(::Any, ::Any) -Base.which(::Symbol) -Base.@which Base.methods -Base.methodswith Base.@show -Base.versioninfo ans ``` @@ -89,9 +76,7 @@ Base.Docs Base.Iterators Base.LibGit2 Base.Libc -Base.Markdown Base.Meta -Base.Pkg Base.StackTraces Base.Sys Base.Threads @@ -137,7 +122,6 @@ Base.identity Base.supertype Core.:(<:) Base.:(>:) -Base.subtypes Base.typejoin Base.typeintersect Base.promote_type @@ -192,6 +176,7 @@ Core.Union Union{} Core.UnionAll Core.Tuple +Core.NamedTuple Base.Val Core.Vararg Core.Nothing @@ -342,7 +327,6 @@ Base.isconst Base.nameof(::Function) Base.functionloc(::Any, ::Any) Base.functionloc(::Method) -Base.@functionloc ``` ## Internals @@ -358,14 +342,6 @@ Base.macroexpand Base.@macroexpand Base.@macroexpand1 Base.code_lowered -Base.@code_lowered Base.code_typed -Base.@code_typed -Base.code_warntype -Base.@code_warntype -Base.code_llvm -Base.@code_llvm -Base.code_native -Base.@code_native Base.precompile ``` diff --git a/codex/base/collections.md b/codex/base/collections.md index 4b3dd85..d61babc 100644 --- a/codex/base/collections.md +++ b/codex/base/collections.md @@ -48,6 +48,7 @@ Fully implemented by: * `AbstractString` * [`Set`](@ref) * [`Pair`](@ref) + * [`NamedTuple`](@ref) ## General Collections @@ -70,6 +71,7 @@ Fully implemented by: * [`WeakKeyDict`](@ref) * `AbstractString` * [`Set`](@ref) + * [`NamedTuple`](@ref) ## Iterable Collections @@ -143,7 +145,8 @@ Base.replace! ```@docs Base.getindex Base.setindex! -Base.endof +Base.firstindex +Base.lastindex ``` Fully implemented by: @@ -162,6 +165,7 @@ Partially implemented by: * [`Dict`](@ref) * [`IdDict`](@ref) * [`WeakKeyDict`](@ref) + * [`NamedTuple`](@ref) ## Dictionaries diff --git a/codex/base/io-network.md b/codex/base/io-network.md index 61170a9..1816f7b 100644 --- a/codex/base/io-network.md +++ b/codex/base/io-network.md @@ -59,7 +59,7 @@ Base.showcompact Base.summary Base.print Base.println -Base.print_with_color +Base.printstyled Base.sprint Base.showerror Base.dump @@ -137,6 +137,8 @@ Base.getsockname Base.getpeername Base.IPv4 Base.IPv6 +Base.TCPSocket +Base.UDPSocket Base.bytesavailable Base.accept Base.listenany diff --git a/codex/base/punctuation.md b/codex/base/punctuation.md index 13fab22..19f2604 100644 --- a/codex/base/punctuation.md +++ b/codex/base/punctuation.md @@ -38,7 +38,7 @@ Extended documentation for mathematical symbols & functions is [here](@ref math- | `.` | access named fields in objects/modules (calling [`getproperty`](@ref Base.getproperty) or [`setproperty!`](@ref Base.setproperty!)), also prefixes elementwise function calls (calling [`broadcast`](@ref)) | | `a:b` | range a, a+1, a+2, ..., b (calling [`colon`](@ref)) | | `a:s:b` | range a, a+s, a+2s, ..., b (also calling [`colon`](@ref)) | -| `:` | index an entire dimension (1:endof), see [`Colon`](@ref)) | +| `:` | index an entire dimension (firstindex:lastindex), see [`Colon`](@ref)) | | `::` | type annotation or [`typeassert`](@ref), depending on context | | `:( )` | quoted expression | | `:a` | symbol a | diff --git a/codex/devdocs/gc-sa.md b/codex/devdocs/gc-sa.md new file mode 100644 index 0000000..6c5f5a8 --- /dev/null +++ b/codex/devdocs/gc-sa.md @@ -0,0 +1,291 @@ +# Static analyzer annotations for GC correctness in C code + +## General Overview + +Since Julia's GC is precise, it needs to maintain correct rooting +information for any value that may be referenced at any time GC +may occur. These places are known as `safepoints` and in the +function local context, we extend this designation to any function +call that may recursively end up at a safepoint. + +In generated code, this is taken care of automatically by the GC +root placement pass (see the chapter on GC rooting in the LLVM +codegen devdocs). However, in C code, we need to inform the runtime +of any GC roots manually. This is done using the following macros: + +``` +// The value assigned to any slot passed as an argument to these +// is rooted for the duration of this GC frame. +JL_GC_PUSH{1,...,6}(args...) +// The values assigned into the size `n` array `rts` are rooted +// for the duration of this GC frame. +JL_GC_PUSHARGS(rts, n) +// Pop a GC frame +JL_GC_POP +``` + +If these macros are not used where they need to be, or they are used +incorrectly, the result is silent memory corruption. As such it +is very important that they are placed correctly in all applicable +code. + +As such, we employ static analysis (and in particular the clang static +analyzer) to help ensure that these macros +are used correctly. The remainder of this document gives an overview +of this static analysis and describes the support needed in the julia +code base to make things work. + +## GC Invariants + +There is two simple invariants correctness: +- All GC_PUSH calls need to be followed by an appropriate GC_POP (in practice we enforce this + at the function level) +- If a value was previously not rooted at any safepoint, it may no longer be referenced + afterwards + +Of course the devil is in the details here. In particular to satisfy the second of the above +conditions, we need to know: +- Which calls are safepoints and which are not +- Which values are rooted at any given safepoint and which are not +- When is a value referenced + +For the second point in particular, we need to know which memory locations will be considered +rooting at runtime (i.e. values assigned to such locations are rooted). This includes locations +explicitly designated as such by passing them to one of the `GC_PUSH` macros, globally rooted +locations and values, as well as any location recursively reachable from one of those locations. + +## Static Analysis Algorithm + +The idea itself is very simple, although the implementation is quite a bit more complicated +(mainly due to a large number of special cases and intricacies of C and C++). In essence, +we keep track of all locations that are rooting, all values that are rootable and any +expression (assignments, allocations, etc) affect the rootedness of any rootable values. +Then, at any safepoint, we perform a "symbolic GC" and poison any values that are not rooted +at said location. If these values are later referenced, we emit an error. + +The clang static analyzer works by constructing a graph of states and exploring this graph +for sources of errors. Several nodes in this graph are generated by the analyzer itself +(e.g. for control flow), but the definitions above augment this graph with our own state. + +The static analyzer is interprocedural and can analyze control flow across function boundaries. +However, the static analyzer is not fully recursive and makes heuristic decisions about which +calls to explore (additionally some calls are cross-translation unit and invisible to the analyzer). +In our case, our definition of correctness requires total information. +As such, we need to annotate +the prototypes of all function calls with whatever information the analysis required, +even if that information would otherwise be available by interprocedural static analysis. + +Luckily however, we can still use this interprocedural analysis to ensure that the annotations +we place on a given function are indeed correct given the implementation of said function. + +## The analyzer annotations + +These annotations are found in src/support/analyzer_annotations.h. +The are only active when the analyzer is being used and expand either +to nothing (for prototype annotations) or to no-ops (for function like annotations). + +### JL_NOTSAFEPOINT + +This is perhaps the most common annotation, and should be placed on any function +that is known not to possibly lead to reaching a GC safepoint. In general, it is +only safe for such a function to perform arithmetic, memory accesses and calls to +functions either annotated JL_NOTSAFEPOINT or otherwise known not to be safepoints (e.g. +function in the C standard library, which are hardcoded as such in the analyzer) + +It is valid to keep values unrooted across calls to any function annotated with this +attribute: + +Usage Example: +```c +void jl_get_one() JL_NOTSAFEPOINT { + return 1; +} + +jl_value_t *example() { + jl_value_t *val = jl_alloc_whatever(); + // This is valid, even though `val` is unrooted, because + // jl_get_one is not a safepoint + jl_get_one(); + return val; +} +``` + +### JL_MAYBE_UNROOTED/JL_ROOTS_TEMPORARILY + +When `JL_MAYBE_UNROOTED` is annotated as an argument on a function, +indicates that said argument may be passed, even if it is not rooted. +In the ordinary course of events, +the julia ABI guarantees that callers root values before passing them to +callees. However, some functions do not follow this ABI and allow values +to be passed to them even though they are not rooted. Note however, that +this does not automatically imply that said argument will be preserved. +The `ROOTS_TEMPORARILY` annotation provides the stronger guarantee that, +not only may the value be unrooted when passed, it will also be preserved +across any internal safepoints by the callee. + +Note that JL_NOTSAFEPOINT essentially implies JL_MAYBE_UNROOTED/JL_ROOTS_TEMPORARILY, +because the rootedness of an argument is irrelevant if the function contains +no safepoints. + +One additional point to note is that these annotations apply on both the +caller and the callee side. On the caller side, they lift rootedness +restrictions that are normally required for julia ABI functions. On +the callee side, they have the reverse effect of preventing these arguments +from being considered implicitly rooted. + +If either of these annotations is applied to the function as a whole, it applies +to all arguments of the function. This should generally only be necessary for +varargs functions. + +Usage example: +```c +JL_DLLEXPORT void JL_NORETURN jl_throw(jl_value_t *e JL_MAYBE_UNROOTED); +jl_value_t *jl_alloc_error(); + +void example() { + // The return value of the allocation is unrooted. This would normally + // be an error, but is allowed because of the above annotation. + jl_throw(jl_alloc_error()); +} +``` + +### JL_PROPAGATES_ROOT + +This annotation is commonly found on accessor functions that return one rootable +object stored within another. When annotated on a function argument, it tells +the analyzer that the root for that argument also applies to the value returned +by the function. + +Usage Example: +```c +jl_value_t *jl_svecref(jl_svec_t *t JL_PROPAGATES_ROOT, size_t i) JL_NOTSAFEPOINT; + +size_t example(jl_svec_t *svec) { + jl_value_t *val = jl_svecref(svec, 1) + // This is valid, because, as annotated by the PROPAGATES_ROOT annotation, + // jl_svecref propagates the rooted-ness from `svec` to `val` + jl_gc_safepoint(); + return jl_unbox_long(val); +} +``` + +### JL_ROOTING_ARGUMENT/JL_ROOTED_ARGUMENT + +This is essentially the assignment counterpart to `JL_PROPAGATES_ROOT`. +When assigning a value to a field of another value that is already rooted, +the assigned value will inherit the root of the value it is assigned into. + +Usage Example: +```c +void jl_svecset(void *t JL_ROOTING_ARGUMENT, size_t i, void *x JL_ROOTED_ARGUMENT) JL_NOTSAFEPOINT + + +size_t example(jl_svec_t *svec) { + jl_value_t *val = jl_box_long(10000); + jl_svecset(svec, val); + // This is valid, because the annotations imply that the + // jl_svecset propagates the rooted-ness from `svec` to `val` + jl_gc_safepoint(); + return jl_unbox_long(val); +} +``` + +### JL_GC_DISABLED + +This annotation implies that this function is only called with the GC runtime-disabled. +Functions of this kind are most often encountered during startup and in the GC code itself. +Note that this annotation is checked against the runtime enable/disable calls, so clang will +know if you lie. This is not a good way to disable processing of a given function if the +GC is not actually disabled (use ifdef __clang_analyzer__ for that if you must). + +Usage example: +```c +void jl_do_magic() JL_GC_DISABLED { + // Wildly allocate here with no regard for roots +} + +void example() { + int en = jl_gc_enable(0); + jl_do_magic(); + jl_gc_enable(en); +} +``` + +### JL_REQUIRE_ROOTED_SLOT + +This annotation requires the caller to pass in a slot that is rooted (i.e. values assigned +to this slot will be rooted). + +Usage example: +```c +void jl_do_processing(jl_value_t **slot JL_REQUIRE_ROOTED_SLOT) { + *slot = jl_box_long(1); + // Ok, only, because the slot was annotated as rooting + jl_gc_safepoint(); +} + +void example() { + jl_value_t *slot = NULL; + JL_GC_PUSH1(&slot); + jl_do_processing(&slot); + JL_GC_POP(); +} +``` + +### JL_GLOBALLY_ROOTED + +This annotation implies that a given value is always globally rooted. +It can be applied to global variable declarations, in which case it +will apply to the value of those variables (or values if the declaration +if for an array), or to functions, in which case it will apply to the +return value of such functions (e.g. for functions that always return +some private, globally rooted value). + +Usage example: +``` +extern JL_DLLEXPORT jl_datatype_t *jl_any_type JL_GLOBALLY_ROOTED; +jl_ast_context_t *jl_ast_ctx(fl_context_t *fl) JL_GLOBALLY_ROOTED; +``` + +### JL_ALWAYS_LEAFTYPE + +This annotations is essentially equivalent to JL_GLOBALLY_ROOTED, except that +is should only be used if those values are globally rooted by virtue of being +a leaftype. The rooting of leaftypes is a bit complicated, and we can generally +assume that leaftypes are rooted where they are used, but we may refine this +property in the future, so the separate annotation helps split out the reason +for being globally rooted. + +The analyzer also automatically detects checks for leaftype-ness and will not +complain about missing GC roots on these paths. + +``` +JL_DLLEXPORT jl_value_t *jl_apply_array_type(jl_value_t *type, size_t dim) JL_ALWAYS_LEAFTYPE; +``` + +### JL_GC_PROMISE_ROOTED + +This is a function-like annotation. Any value passed to this annotation will be considered +rooted for the scope of the current function. It is designed as an escape hatch +for analyzer inadequacy or complicated situations. However, it should be used sparingly, +in favor of improving the analyzer itself. + +``` +void example() { + jl_value_t *val = jl_alloc_something(); + if (some_condition) { + // We happen to know for complicated external reasons + // that val is rooted under these conditions + JL_GC_PROMISE_ROOTED(val); + } +} +``` + +## Completeness of analysis + +The analyzer only looks at local information. In particular, e.g. in the `PROPAGATES_ROOT` case +above, it assumes that such memory is only modified in ways it can see, not in any called +functions (unless it happens to decide to consider them in its analysis) and not in any concurrently +running threads. As such, it may miss a few problematic cases, though in practice such concurrent +modification is fairly rare. Improving the analyzer to handle more such cases may be an interesting +topic for future work. diff --git a/codex/manual/documentation.md b/codex/manual/documentation.md index 7bb282b..8cf5dd5 100644 --- a/codex/manual/documentation.md +++ b/codex/manual/documentation.md @@ -616,13 +616,13 @@ the Julia documentation itself. For example: ```julia """ - eigvals!(A,[irange,][vl,][vu]) -> values + accumulate!(op, y, x) -Same as [`eigvals`](@ref), but saves space by overwriting the input `A`, instead of creating a copy. +Cumulative operation `op` on a vector `x`, storing the result in `y`. See also [`accumulate`](@ref). """ ``` -This will create a link in the generated docs to the `eigvals` documentation +This will create a link in the generated docs to the `accumulate` 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. diff --git a/codex/manual/environment-variables.md b/codex/manual/environment-variables.md index ba9569e..ebc4617 100644 --- a/codex/manual/environment-variables.md +++ b/codex/manual/environment-variables.md @@ -10,7 +10,7 @@ a permanent effect. The current value of the same environment variable is determined by evaluating `ENV["JULIA_EDITOR"]`. The environment variables that Julia uses generally start with `JULIA`. If -[`Base.versioninfo`](@ref) is called with `verbose` equal to `true`, then the +[`InteractiveUtils.versioninfo`](@ref) is called with `verbose` equal to `true`, then the output will list defined environment variables relevant for Julia, including those for which `JULIA` appears in the name. @@ -153,7 +153,7 @@ falls back to `/bin/sh` if `$SHELL` is unset. ### `JULIA_EDITOR` -The editor returned by `Base.editor()` and used in, e.g., [`Base.edit`](@ref), +The editor returned by `InteractiveUtils.editor()` and used in, e.g., [`InteractiveUtils.edit`](@ref), referring to the command of the preferred editor, for instance `vim`. `$JULIA_EDITOR` takes precedence over `$VISUAL`, which in turn takes precedence diff --git a/codex/manual/functions.md b/codex/manual/functions.md index c4ce2e9..9ee63d8 100644 --- a/codex/manual/functions.md +++ b/codex/manual/functions.md @@ -164,7 +164,6 @@ A few special expressions correspond to calls to functions with non-obvious name | `[A; B; C; ...]` | [`vcat`](@ref) | | `[A B; C D; ...]` | [`hvcat`](@ref) | | `A'` | [`adjoint`](@ref) | -| `A.'` | [`transpose`](@ref) | | `1:n` | [`colon`](@ref) | | `A[i]` | [`getindex`](@ref) | | `A[i] = x` | [`setindex!`](@ref) | @@ -692,7 +691,8 @@ the results (see [Pre-allocating outputs](@ref)). A convenient syntax for this i is equivalent to `broadcast!(identity, X, ...)` except that, as above, the `broadcast!` loop is fused with any nested "dot" calls. For example, `X .= sin.(Y)` is equivalent to `broadcast!(sin, X, Y)`, overwriting `X` with `sin.(Y)` in-place. If the left-hand side is an array-indexing expression, -e.g. `X[2:end] .= sin.(Y)`, then it translates to `broadcast!` on a `view`, e.g. `broadcast!(sin, view(X, 2:endof(X)), Y)`, +e.g. `X[2:end] .= sin.(Y)`, then it translates to `broadcast!` on a `view`, e.g. +`broadcast!(sin, view(X, 2:lastindex(X)), Y)`, so that the left-hand side is updated in-place. Since adding dots to many operations and function calls in an expression diff --git a/codex/manual/getting-started.md b/codex/manual/getting-started.md index 5df3e86..842cff0 100644 --- a/codex/manual/getting-started.md +++ b/codex/manual/getting-started.md @@ -117,8 +117,8 @@ julia [switches] -- [programfile] [args...] -i Interactive mode; REPL runs and isinteractive() is true -q, --quiet Quiet startup: no banner, suppress REPL warnings - --banner={yes|no} Enable or disable startup banner - --color={yes|no} Enable or disable color text + --banner={yes|no|auto} Enable or disable startup banner + --color={yes|no|auto} Enable or disable color text --history-file={yes|no} Load or save history --depwarn={yes|no|error} Enable or disable syntax and method deprecation warnings ("error" turns warnings into errors) diff --git a/codex/manual/interfaces.md b/codex/manual/interfaces.md index 89e8c66..236641c 100644 --- a/codex/manual/interfaces.md +++ b/codex/manual/interfaces.md @@ -115,9 +115,12 @@ Now, when we ask Julia to [`collect`](@ref) all the elements into an array it ca of the right size instead of blindly [`push!`](@ref)ing each element into a `Vector{Any}`: ```jldoctest squaretype -julia> collect(Squares(10))' # transposed to save space -1×10 RowVector{Int64,Array{Int64,1}}: - 1 4 9 16 25 36 49 64 81 100 +julia> collect(Squares(4)) +4-element Array{Int64,1}: + 1 + 4 + 9 + 16 ``` While we can rely upon generic implementations, we can also extend specific methods where we know @@ -150,9 +153,12 @@ julia> Base.next(::Iterators.Reverse{Squares}, state) = (state*state, state-1) julia> Base.done(::Iterators.Reverse{Squares}, state) = state < 1 -julia> collect(Iterators.reverse(Squares(10)))' # transposed to save space -1×10 RowVector{Int64,Array{Int64,1}}: - 100 81 64 49 36 25 16 9 4 1 +julia> collect(Iterators.reverse(Squares(4))) +4-element Array{Int64,1}: + 16 + 9 + 4 + 1 ``` ## Indexing @@ -161,7 +167,8 @@ julia> collect(Iterators.reverse(Squares(10)))' # transposed to save space |:-------------------- |:-------------------------------- | | `getindex(X, i)` | `X[i]`, indexed element access | | `setindex!(X, v, i)` | `X[i] = v`, indexed assignment | -| `endof(X)` | The last index, used in `X[end]` | +| `firstindex(X)` | The first index | +| `lastindex(X)` | The last index, used in `X[end]` | 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` @@ -177,11 +184,12 @@ julia> Squares(100)[23] 529 ``` -Additionally, to support the syntax `S[end]`, we must define [`endof`](@ref) to specify the last valid -index: +Additionally, to support the syntax `S[end]`, we must define [`lastindex`](@ref) to specify the last +valid index. It is recommended to also define [`firstindex`](@ref) to specify the first valid index: ```jldoctest squaretype -julia> Base.endof(S::Squares) = length(S) +julia> Base.firstindex(S::Squares) = 1 +julia> Base.lastindex(S::Squares) = length(S) julia> Squares(23)[end] 529 @@ -275,28 +283,31 @@ methods are all it takes for `SquaresVector` to be an iterable, indexable, and c array: ```jldoctest squarevectype -julia> s = SquaresVector(7) -7-element SquaresVector: +julia> s = SquaresVector(4) +4-element SquaresVector: 1 4 9 16 - 25 - 36 - 49 -julia> s[s .> 20] -3-element Array{Int64,1}: - 25 - 36 - 49 +julia> s[s .> 8] +2-element Array{Int64,1}: + 9 + 16 -julia> s \ [1 2; 3 4; 5 6; 7 8; 9 10; 11 12; 13 14] -1×2 RowVector{Float64,Array{Float64,1}}: - 0.305389 0.335329 +julia> s + s +4-element Array{Int64,1}: + 2 + 8 + 18 + 32 -julia> s ⋅ s # dot(s, s) -4676 +julia> sin.(s) +4-element Array{Float64,1}: + 0.8414709848078965 + -0.7568024953079282 + 0.4121184852417566 + -0.2879033166650653 ``` As a more complicated example, let's define our own toy N-dimensional sparse-like array type built @@ -382,8 +393,8 @@ julia> A[SquaresVector(3)] 4.0 9.0 -julia> dot(A[:,1],A[:,2]) -32.0 +julia> mean(A) +5.0 ``` If you are defining an array type that allows non-traditional indexing (indices that start at diff --git a/codex/manual/packages.md b/codex/manual/packages.md index fc50a29..105686e 100644 --- a/codex/manual/packages.md +++ b/codex/manual/packages.md @@ -3,8 +3,8 @@ Julia has a built-in package manager for installing add-on functionality written in Julia. It can also install external libraries using your operating system's standard system for doing so, or by compiling from source. The list of registered Julia packages can be found at [http://pkg.julialang.org](http://pkg.julialang.org). -All package manager commands are found in the `Pkg` module, included in Julia's `Base` -install. +All package manager commands are found in the `Pkg` standard library which becomes available after using +`import Pkg`. First we'll go over the mechanics of the `Pkg` family of commands and then we'll provide some guidance on how to get your package registered. Be sure to read the section below on package naming diff --git a/codex/manual/parallel-computing.md b/codex/manual/parallel-computing.md index 85257e6..514e36d 100644 --- a/codex/manual/parallel-computing.md +++ b/codex/manual/parallel-computing.md @@ -284,15 +284,12 @@ snippet: ```julia-repl A = rand(10,10) -remotecall_fetch(()->norm(A), 2) +remotecall_fetch(()->sum(A), 2) ``` -In this case [`norm`](@ref) is a function that takes 2D array as a parameter, and MUST be defined in -the remote process. You could use any function other than `norm` as long as it is defined in the remote -process and accepts the appropriate parameter. - +In this case [`sum`](@ref) MUST be defined in the remote process. Note that `A` is a global variable defined in the local workspace. Worker 2 does not have a variable called -`A` under `Main`. The act of shipping the closure `()->norm(A)` to worker 2 results in `Main.A` being defined +`A` under `Main`. The act of shipping the closure `()->sum(A)` to worker 2 results in `Main.A` being defined on 2. `Main.A` continues to exist on worker 2 even after the call `remotecall_fetch` returns. Remote calls with embedded global references (under `Main` module only) manage globals as follows: @@ -306,9 +303,9 @@ with embedded global references (under `Main` module only) manage globals as fol ```julia A = rand(10,10) - remotecall_fetch(()->norm(A), 2) # worker 2 + remotecall_fetch(()->sum(A), 2) # worker 2 A = rand(10,10) - remotecall_fetch(()->norm(A), 3) # worker 3 + remotecall_fetch(()->sum(A), 3) # worker 3 A = nothing ``` @@ -1083,7 +1080,7 @@ manner: * In this way a mesh network is established, wherein every worker is directly connected with every other worker. -While the default transport layer uses plain `TCPSocket`, it is possible for a Julia cluster to +While the default transport layer uses plain [`TCPSocket`](@ref), it is possible for a Julia cluster to provide its own transport. Julia provides two in-built cluster managers: @@ -1225,7 +1222,7 @@ connected to. For example, consider a Julia cluster of 32 processes in an all-to * Each Julia process thus has 31 communication tasks. * Each task handles all incoming messages from a single remote worker in a message-processing loop. - * The message-processing loop waits on an `IO` object (for example, a `TCPSocket` in the default + * The message-processing loop waits on an `IO` object (for example, a [`TCPSocket`](@ref) in the default implementation), reads an entire message, processes it and waits for the next one. * Sending messages to a process is done directly from any Julia task--not just communication tasks--again, via the appropriate `IO` object. diff --git a/codex/manual/strings.md b/codex/manual/strings.md index 7949d57..2f680f7 100644 --- a/codex/manual/strings.md +++ b/codex/manual/strings.md @@ -178,12 +178,15 @@ julia> str[end] '\n': ASCII/Unicode U+000a (category Cc: Other, control) ``` -All indexing in Julia is 1-based: the first element of any integer-indexed object is found at +Many Julia objects, including strings, can be indexed with integers. The index of the first +element is returned by [`firstindex(str)`](@ref), and the index of the last element +with [`lastindex(str)`](@ref). The keyword`end` can be used inside an indexing +operation as shorthand for the last index along the given dimension. +Most indexing in Julia is 1-based: the first element of many integer-indexed objects is found at index 1. (As we will see below, this does not necessarily mean that the last element is found at index `n`, where `n` is the length of the string.) -In any indexing expression, the keyword `end` can be used as a shorthand for the last index (computed -by [`endof(str)`](@ref)). You can perform arithmetic and other operations with `end`, just like +You can perform arithmetic and other operations with `end`, just like a normal value: ```jldoctest helloworldstring @@ -302,14 +305,14 @@ julia> s[1:4] ``` Because of variable-length encodings, the number of characters in a string (given by [`length(s)`](@ref)) -is not always the same as the last index. If you iterate through the indices 1 through [`endof(s)`](@ref) +is not always the same as the last index. If you iterate through the indices 1 through [`lastindex(s)`](@ref) and index into `s`, the sequence of characters returned when errors aren't thrown is the sequence -of characters comprising the string `s`. Thus we have the identity that `length(s) <= endof(s)`, +of characters comprising the string `s`. Thus we have the identity that `length(s) <= lastindex(s)`, since each character in a string must have its own index. The following is an inefficient and verbose way to iterate through the characters of `s`: ```jldoctest unicodestring -julia> for i = 1:endof(s) +julia> for i = begindex(s):lastindex(s) try println(s[i]) catch @@ -562,13 +565,14 @@ julia> join(["apples", "bananas", "pineapples"], ", ", " and ") Some other useful functions include: - * [`endof(str)`](@ref) gives the maximal (byte) index that can be used to index into `str`. + * [`firstindex(str)`](@ref) gives the minimal (byte) index that can be used to index into `str` (always 1 for strings, not necessarily true for other containers). + * [`lastindex(str)`](@ref) gives the maximal (byte) index that can be used to index into `str`. * [`length(str)`](@ref) the number of characters in `str`. * [`length(str, i, j)`](@ref) the number of valid character indices in `str` from `i` to `j`. * [`i = start(str)`](@ref start) gives the first valid index at which a character can be found in `str` (typically 1). * [`c, j = next(str,i)`](@ref next) returns next character at or after the index `i` and the next valid - character index following that. With [`start`](@ref) and [`endof`](@ref), can be used to iterate + character index following that. With [`start`](@ref) and [`lastindex`](@ref), can be used to iterate through the characters in `str`. * [`thisind(str, i)`](@ref) given an arbitrary index into a string find the first index of the character into which the index points. * [`nextind(str, i, n=1)`](@ref) find the start of the `n`th character starting after index `i`. diff --git a/codex/manual/style-guide.md b/codex/manual/style-guide.md index f2a24be..cb59a41 100644 --- a/codex/manual/style-guide.md +++ b/codex/manual/style-guide.md @@ -92,7 +92,7 @@ Instead of: ```julia function double(a::AbstractArray{<:Number}) - for i = 1:endof(a) + for i = firstindex(a):lastindex(a) a[i] *= 2 end return a @@ -103,7 +103,7 @@ use: ```julia function double!(a::AbstractArray{<:Number}) - for i = 1:endof(a) + for i = firstindex(a):lastindex(a) a[i] *= 2 end return a diff --git a/codex/manual/types.md b/codex/manual/types.md index 21b1671..81cb5a7 100644 --- a/codex/manual/types.md +++ b/codex/manual/types.md @@ -907,7 +907,7 @@ alias for `Tuple{Vararg{T,N}}`, i.e. a tuple type containing exactly `N` element ### Named Tuple Types -Named tuples are instances of the `NamedTuple` type, which has two parameters: a tuple of +Named tuples are instances of the [`NamedTuple`](@ref) type, which has two parameters: a tuple of symbols giving the field names, and a tuple type giving the field types. ```jldoctest diff --git a/codex/stdlib/InteractiveUtils.md b/codex/stdlib/InteractiveUtils.md new file mode 100644 index 0000000..39555d3 --- /dev/null +++ b/codex/stdlib/InteractiveUtils.md @@ -0,0 +1,25 @@ +# Interactive Utilities + +```@docs +InteractiveUtils.apropos +InteractiveUtils.varinfo +InteractiveUtils.versioninfo +InteractiveUtils.methodswith +InteractiveUtils.subtypes +InteractiveUtils.edit(::AbstractString, ::Integer) +InteractiveUtils.edit(::Any) +InteractiveUtils.@edit +InteractiveUtils.less(::AbstractString) +InteractiveUtils.less(::Any) +InteractiveUtils.@less +InteractiveUtils.@which +InteractiveUtils.@functionloc +InteractiveUtils.@code_lowered +InteractiveUtils.@code_typed +InteractiveUtils.code_warntype +InteractiveUtils.@code_warntype +InteractiveUtils.code_llvm +InteractiveUtils.@code_llvm +InteractiveUtils.code_native +InteractiveUtils.@code_native +``` diff --git a/codex/stdlib/LinearAlgebra.md b/codex/stdlib/LinearAlgebra.md index 2bdd802..00d677f 100644 --- a/codex/stdlib/LinearAlgebra.md +++ b/codex/stdlib/LinearAlgebra.md @@ -354,7 +354,6 @@ LinearAlgebra.tril! LinearAlgebra.diagind LinearAlgebra.diag LinearAlgebra.diagm -LinearAlgebra.scale! LinearAlgebra.rank LinearAlgebra.norm LinearAlgebra.vecnorm @@ -410,8 +409,6 @@ LinearAlgebra.istril LinearAlgebra.istriu LinearAlgebra.isdiag LinearAlgebra.ishermitian -LinearAlgebra.RowVector -LinearAlgebra.ConjArray Base.transpose LinearAlgebra.transpose! Base.adjoint @@ -430,6 +427,8 @@ below (e.g. `mul!`) according to the usual Julia convention. ```@docs LinearAlgebra.mul! +LinearAlgebra.lmul! +LinearAlgebra.rmul! LinearAlgebra.ldiv! LinearAlgebra.rdiv! ``` diff --git a/codex/stdlib/Markdown.md b/codex/stdlib/Markdown.md new file mode 100644 index 0000000..7d82df3 --- /dev/null +++ b/codex/stdlib/Markdown.md @@ -0,0 +1 @@ +# Markdown diff --git a/codex/base/pkg.md b/codex/stdlib/Pkg.md similarity index 66% rename from codex/base/pkg.md rename to codex/stdlib/Pkg.md index 4cc3bf7..b7cd686 100644 --- a/codex/base/pkg.md +++ b/codex/stdlib/Pkg.md @@ -9,22 +9,22 @@ package. See [PkgDev README](https://github.com/JuliaLang/PkgDev.jl/blob/master/ the documentation of those functions. ```@docs -Base.Pkg.dir -Base.Pkg.init -Base.Pkg.resolve -Base.Pkg.edit -Base.Pkg.add -Base.Pkg.rm -Base.Pkg.clone -Base.Pkg.setprotocol! -Base.Pkg.available -Base.Pkg.installed -Base.Pkg.status -Base.Pkg.update -Base.Pkg.checkout -Base.Pkg.pin -Base.Pkg.free -Base.Pkg.build -Base.Pkg.test -Base.Pkg.dependents +Pkg.dir +Pkg.init +Pkg.resolve +Pkg.edit +Pkg.add +Pkg.rm +Pkg.clone +Pkg.setprotocol! +Pkg.available +Pkg.installed +Pkg.status +Pkg.update +Pkg.checkout +Pkg.pin +Pkg.free +Pkg.build +Pkg.test +Pkg.dependents ``` diff --git a/codex/stdlib/REPL.md b/codex/stdlib/REPL.md index fd43037..158b077 100644 --- a/codex/stdlib/REPL.md +++ b/codex/stdlib/REPL.md @@ -314,7 +314,7 @@ Fields for output from functions can also be completed: ```julia-repl julia> split("","")[1].[TAB] -endof offset string +lastindex offset string ``` The completion of fields for output from functions uses type inference, and it can only suggest diff --git a/codex/stdlib/UUIDs.md b/codex/stdlib/UUIDs.md new file mode 100644 index 0000000..616ac63 --- /dev/null +++ b/codex/stdlib/UUIDs.md @@ -0,0 +1,7 @@ +# UUIDs + +```@docs +UUIDs.uuid1 +UUIDs.uuid4 +UUIDs.uuid_version +``` diff --git a/codex/stdlib/linearalgebra.md b/codex/stdlib/linearalgebra.md index 2bdd802..00d677f 100644 --- a/codex/stdlib/linearalgebra.md +++ b/codex/stdlib/linearalgebra.md @@ -354,7 +354,6 @@ LinearAlgebra.tril! LinearAlgebra.diagind LinearAlgebra.diag LinearAlgebra.diagm -LinearAlgebra.scale! LinearAlgebra.rank LinearAlgebra.norm LinearAlgebra.vecnorm @@ -410,8 +409,6 @@ LinearAlgebra.istril LinearAlgebra.istriu LinearAlgebra.isdiag LinearAlgebra.ishermitian -LinearAlgebra.RowVector -LinearAlgebra.ConjArray Base.transpose LinearAlgebra.transpose! Base.adjoint @@ -430,6 +427,8 @@ below (e.g. `mul!`) according to the usual Julia convention. ```@docs LinearAlgebra.mul! +LinearAlgebra.lmul! +LinearAlgebra.rmul! LinearAlgebra.ldiv! LinearAlgebra.rdiv! ``` diff --git a/make.jl b/make.jl index 97e387c..ee44af5 100644 --- a/make.jl +++ b/make.jl @@ -2,6 +2,7 @@ ENV["JULIA_PKGDIR"] = joinpath(@__DIR__, "deps") if "deps" in ARGS +using Pkg Pkg.init() cp(joinpath(@__DIR__, "REQUIRE"), Pkg.dir("REQUIRE"); remove_destination = true) Pkg.update() @@ -86,7 +87,6 @@ const PAGES = [ "base/io-network.md", "base/punctuation.md", "base/sort.md", - "base/pkg.md", "base/iterators.md", "base/c.md", "base/libc.md", @@ -135,11 +135,11 @@ end makedocs( build = joinpath(pwd(), "_build/html/ko"), modules = [Base, Core, BuildSysImg, [Base.root_module(Base, stdlib.stdlib) for stdlib in STDLIB_DOCS]...], - clean = false, + clean = false, # true doctest = "doctest" in ARGS, linkcheck = "linkcheck" in ARGS, linkcheck_ignore = ["https://bugs.kde.org/show_bug.cgi?id=136779"], # fails to load from nanosoldier? - strict = false, + strict = false, # true checkdocs = :none, format = "pdf" in ARGS ? :latex : :html, sitename = "줄리아 언어", @@ -147,4 +147,5 @@ makedocs( analytics = "UA-110655381-2", # juliakorea 추척 ID pages = PAGES, html_prettyurls = ("deploy" in ARGS), + html_canonical = ("deploy" in ARGS) ? "http://juliakorea.github.io/ko/" : nothing, # juliakorea 주소 (TODO: stable 버전 추가) ) diff --git a/src/NEWS.md b/src/NEWS.md index f61a1f5..0848509 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -184,6 +184,9 @@ Breaking changes This section lists changes that do not have deprecation warnings. + * `readuntil` now does *not* include the delimiter in its result, matching the + behavior of `readline`. Pass `keep=true` to get the old behavior ([#25633](https://github.com/JuliaLang/julia/issues/25633)). + * `getindex(s::String, r::UnitRange{Int})` now throws `UnicodeError` if `last(r)` is not a valid index into `s` ([#22572](https://github.com/JuliaLang/julia/issues/22572)). @@ -293,7 +296,9 @@ This section lists changes that do not have deprecation warnings. This avoids stack overflows in the common case of definitions like `f(x, y) = f(promote(x, y)...)` ([#22801](https://github.com/JuliaLang/julia/issues/22801)). - * `findmin`, `findmax`, `indmin`, and `indmax` used to always return linear indices. + * `indmin` and `indmax` have been renamed to `argmin` and `argmax`, respectively ([#25654](https://github.com/JuliaLang/julia/issues/25654)). + + * `findmin`, `findmax`, `argmin`, and `argmax` used to always return linear indices. They now return `CartesianIndex`es for all but 1-d arrays, and in general return the `keys` of indexed collections (e.g. dictionaries) ([#22907](https://github.com/JuliaLang/julia/issues/22907)). @@ -371,6 +376,10 @@ This section lists changes that do not have deprecation warnings. and higher-dimensional arrays insted of linear indices as was previously the case. Use `LinearIndices(a)[findall(f, a)]` and similar constructs to compute linear indices. + * The `Base.HasShape` iterator trait has gained a type parameter `N` indicating the + number of dimensions, which must correspond to the length of the tuple returned by + `size` ([#25655](https://github.com/JuliaLang/julia/issues/25655)). + * `AbstractSet` objects are now considered equal by `==` and `isequal` if all of their elements are equal ([#25368](https://github.com/JuliaLang/julia/issues/25368)). This has required changing the hashing algorithm for `BitSet`. @@ -499,7 +508,7 @@ Library improvements has been changed to `KeySet{K, <:Associative{K}} <: AbstractSet{K}` ([#24580](https://github.com/JuliaLang/julia/issues/24580)). * New function `ncodeunits(s::AbstractString)` gives the number of code units in a string. - The generic definition is constant time but calls `endof(s)` which may be inefficient. + The generic definition is constant time but calls `lastindex(s)` which may be inefficient. Therefore custom string types may want to define direct `ncodeunits` methods. * `reverseind(s::AbstractString, i::Integer)` now has an efficient generic fallback, so @@ -947,8 +956,15 @@ Deprecated or removed * `findin(a, b)` has been deprecated in favor of `findall(occursin(b), a)` ([#24673](https://github.com/JuliaLang/julia/issues/24673)). + * `module_name` has been deprecated in favor of a new, general `nameof` function. Similarly, + the unexported `Base.function_name` and `Base.datatype_name` have been deprecated in favor + of `nameof` methods ([#25622](https://github.com/JuliaLang/julia/issues/25622)). + * The module `Random.dSFMT` is renamed `Random.DSFMT` ([#25567](https://github.com/JuliaLang/julia/issues/25567)). + * `Random.RandomDevice(unlimited::Bool)` (on non-Windows systems) is deprecated in favor of + `Random.RandomDevice(; unlimited=unlimited)` ([#25668](https://github.com/JuliaLang/julia/issues/25668)). + * The generic implementations of `strides(::AbstractArray)` and `stride(::AbstractArray, ::Int)` have been deprecated. Subtypes of `AbstractArray` that implement the newly introduced strided array interface should define their own `strides` method ([#25321](https://github.com/JuliaLang/julia/issues/25321)). @@ -959,12 +975,23 @@ Deprecated or removed * `rand(t::Tuple{Vararg{Int}})` is deprecated in favor of `rand(Float64, t)` or `rand(t...)`; `rand(::Tuple)` will have another meaning in the future ([#25429](https://github.com/JuliaLang/julia/issues/25429), [#25278](https://github.com/JuliaLang/julia/issues/25278)). + * The `assert` function (and `@assert` macro) have been documented that they are not guaranteed to run under various optimization levels and should therefore not be used to e.g. verify passwords. + * `ObjectIdDict` has been deprecated in favor of `IdDict{Any,Any}` ([#25210](https://github.com/JuliaLang/julia/issues/25210)). * `gc` and `gc_enable` have been deprecated in favor of `GC.gc` and `GC.enable` ([#25616](https://github.com/JuliaLang/julia/issues/25616)). * `Base.@gc_preserve` has been deprecated in favor of `GC.@preserve` ([#25616](https://github.com/JuliaLang/julia/issues/25616)). + * `scale!` has been deprecated in favor of `mul!`, `lmul!`, and `rmul!` ([#25701](https://github.com/JuliaLang/julia/issues/25701), [#25812](https://github.com/JuliaLang/julia/issues/25812)). + + * `endof(a)` has been renamed to `lastindex(a)`, and the `end` keyword in indexing expressions now + lowers to either `lastindex(a)` (in the case with only one index) or `lastindex(a, d)` (in cases + where there is more than one index and `end` appears at dimension `d`) ([#23554](https://github.com/JuliaLang/julia/issues/23554), [#25763](https://github.com/JuliaLang/julia/issues/25763)). + + * `DateTime()`, `Date()`, and `Time()` have been deprecated, instead use `DateTime(1)`, `Date(1)` + and `Time(0)` respectively ([#23724](https://github.com/JuliaLang/julia/issues/23724)). + Command-line option changes --------------------------- diff --git a/src/base/base.md b/src/base/base.md index ff24b70..e14de8d 100644 --- a/src/base/base.md +++ b/src/base/base.md @@ -19,17 +19,9 @@ Some general notes: ```@docs Base.exit -Base.quit Base.atexit Base.isinteractive -Base.varinfo Base.summarysize -Base.edit(::AbstractString, ::Integer) -Base.edit(::Any) -Base.@edit -Base.less(::AbstractString) -Base.less(::Any) -Base.@less Base.clipboard(::Any) Base.clipboard() Base.require @@ -38,14 +30,9 @@ Base.__precompile__ Base.include Base.include_string Base.include_dependency -Base.Docs.apropos Base.which(::Any, ::Any) -Base.which(::Symbol) -Base.@which Base.methods -Base.methodswith Base.@show -Base.versioninfo ans ``` @@ -89,9 +76,7 @@ Base.Docs Base.Iterators Base.LibGit2 Base.Libc -Base.Markdown Base.Meta -Base.Pkg Base.StackTraces Base.Sys Base.Threads @@ -137,7 +122,6 @@ Base.identity Base.supertype Core.:(<:) Base.:(>:) -Base.subtypes Base.typejoin Base.typeintersect Base.promote_type @@ -192,6 +176,7 @@ Core.Union Union{} Core.UnionAll Core.Tuple +Core.NamedTuple Base.Val Core.Vararg Core.Nothing @@ -342,7 +327,6 @@ Base.isconst Base.nameof(::Function) Base.functionloc(::Any, ::Any) Base.functionloc(::Method) -Base.@functionloc ``` ## Internals @@ -358,14 +342,6 @@ Base.macroexpand Base.@macroexpand Base.@macroexpand1 Base.code_lowered -Base.@code_lowered Base.code_typed -Base.@code_typed -Base.code_warntype -Base.@code_warntype -Base.code_llvm -Base.@code_llvm -Base.code_native -Base.@code_native Base.precompile ``` diff --git a/src/base/collections.md b/src/base/collections.md index 4b3dd85..d61babc 100644 --- a/src/base/collections.md +++ b/src/base/collections.md @@ -48,6 +48,7 @@ Fully implemented by: * `AbstractString` * [`Set`](@ref) * [`Pair`](@ref) + * [`NamedTuple`](@ref) ## General Collections @@ -70,6 +71,7 @@ Fully implemented by: * [`WeakKeyDict`](@ref) * `AbstractString` * [`Set`](@ref) + * [`NamedTuple`](@ref) ## Iterable Collections @@ -143,7 +145,8 @@ Base.replace! ```@docs Base.getindex Base.setindex! -Base.endof +Base.firstindex +Base.lastindex ``` Fully implemented by: @@ -162,6 +165,7 @@ Partially implemented by: * [`Dict`](@ref) * [`IdDict`](@ref) * [`WeakKeyDict`](@ref) + * [`NamedTuple`](@ref) ## Dictionaries diff --git a/src/base/io-network.md b/src/base/io-network.md index 61170a9..1816f7b 100644 --- a/src/base/io-network.md +++ b/src/base/io-network.md @@ -59,7 +59,7 @@ Base.showcompact Base.summary Base.print Base.println -Base.print_with_color +Base.printstyled Base.sprint Base.showerror Base.dump @@ -137,6 +137,8 @@ Base.getsockname Base.getpeername Base.IPv4 Base.IPv6 +Base.TCPSocket +Base.UDPSocket Base.bytesavailable Base.accept Base.listenany diff --git a/src/base/punctuation.md b/src/base/punctuation.md index 13fab22..19f2604 100644 --- a/src/base/punctuation.md +++ b/src/base/punctuation.md @@ -38,7 +38,7 @@ Extended documentation for mathematical symbols & functions is [here](@ref math- | `.` | access named fields in objects/modules (calling [`getproperty`](@ref Base.getproperty) or [`setproperty!`](@ref Base.setproperty!)), also prefixes elementwise function calls (calling [`broadcast`](@ref)) | | `a:b` | range a, a+1, a+2, ..., b (calling [`colon`](@ref)) | | `a:s:b` | range a, a+s, a+2s, ..., b (also calling [`colon`](@ref)) | -| `:` | index an entire dimension (1:endof), see [`Colon`](@ref)) | +| `:` | index an entire dimension (firstindex:lastindex), see [`Colon`](@ref)) | | `::` | type annotation or [`typeassert`](@ref), depending on context | | `:( )` | quoted expression | | `:a` | symbol a | diff --git a/src/devdocs/gc-sa.md b/src/devdocs/gc-sa.md new file mode 100644 index 0000000..6c5f5a8 --- /dev/null +++ b/src/devdocs/gc-sa.md @@ -0,0 +1,291 @@ +# Static analyzer annotations for GC correctness in C code + +## General Overview + +Since Julia's GC is precise, it needs to maintain correct rooting +information for any value that may be referenced at any time GC +may occur. These places are known as `safepoints` and in the +function local context, we extend this designation to any function +call that may recursively end up at a safepoint. + +In generated code, this is taken care of automatically by the GC +root placement pass (see the chapter on GC rooting in the LLVM +codegen devdocs). However, in C code, we need to inform the runtime +of any GC roots manually. This is done using the following macros: + +``` +// The value assigned to any slot passed as an argument to these +// is rooted for the duration of this GC frame. +JL_GC_PUSH{1,...,6}(args...) +// The values assigned into the size `n` array `rts` are rooted +// for the duration of this GC frame. +JL_GC_PUSHARGS(rts, n) +// Pop a GC frame +JL_GC_POP +``` + +If these macros are not used where they need to be, or they are used +incorrectly, the result is silent memory corruption. As such it +is very important that they are placed correctly in all applicable +code. + +As such, we employ static analysis (and in particular the clang static +analyzer) to help ensure that these macros +are used correctly. The remainder of this document gives an overview +of this static analysis and describes the support needed in the julia +code base to make things work. + +## GC Invariants + +There is two simple invariants correctness: +- All GC_PUSH calls need to be followed by an appropriate GC_POP (in practice we enforce this + at the function level) +- If a value was previously not rooted at any safepoint, it may no longer be referenced + afterwards + +Of course the devil is in the details here. In particular to satisfy the second of the above +conditions, we need to know: +- Which calls are safepoints and which are not +- Which values are rooted at any given safepoint and which are not +- When is a value referenced + +For the second point in particular, we need to know which memory locations will be considered +rooting at runtime (i.e. values assigned to such locations are rooted). This includes locations +explicitly designated as such by passing them to one of the `GC_PUSH` macros, globally rooted +locations and values, as well as any location recursively reachable from one of those locations. + +## Static Analysis Algorithm + +The idea itself is very simple, although the implementation is quite a bit more complicated +(mainly due to a large number of special cases and intricacies of C and C++). In essence, +we keep track of all locations that are rooting, all values that are rootable and any +expression (assignments, allocations, etc) affect the rootedness of any rootable values. +Then, at any safepoint, we perform a "symbolic GC" and poison any values that are not rooted +at said location. If these values are later referenced, we emit an error. + +The clang static analyzer works by constructing a graph of states and exploring this graph +for sources of errors. Several nodes in this graph are generated by the analyzer itself +(e.g. for control flow), but the definitions above augment this graph with our own state. + +The static analyzer is interprocedural and can analyze control flow across function boundaries. +However, the static analyzer is not fully recursive and makes heuristic decisions about which +calls to explore (additionally some calls are cross-translation unit and invisible to the analyzer). +In our case, our definition of correctness requires total information. +As such, we need to annotate +the prototypes of all function calls with whatever information the analysis required, +even if that information would otherwise be available by interprocedural static analysis. + +Luckily however, we can still use this interprocedural analysis to ensure that the annotations +we place on a given function are indeed correct given the implementation of said function. + +## The analyzer annotations + +These annotations are found in src/support/analyzer_annotations.h. +The are only active when the analyzer is being used and expand either +to nothing (for prototype annotations) or to no-ops (for function like annotations). + +### JL_NOTSAFEPOINT + +This is perhaps the most common annotation, and should be placed on any function +that is known not to possibly lead to reaching a GC safepoint. In general, it is +only safe for such a function to perform arithmetic, memory accesses and calls to +functions either annotated JL_NOTSAFEPOINT or otherwise known not to be safepoints (e.g. +function in the C standard library, which are hardcoded as such in the analyzer) + +It is valid to keep values unrooted across calls to any function annotated with this +attribute: + +Usage Example: +```c +void jl_get_one() JL_NOTSAFEPOINT { + return 1; +} + +jl_value_t *example() { + jl_value_t *val = jl_alloc_whatever(); + // This is valid, even though `val` is unrooted, because + // jl_get_one is not a safepoint + jl_get_one(); + return val; +} +``` + +### JL_MAYBE_UNROOTED/JL_ROOTS_TEMPORARILY + +When `JL_MAYBE_UNROOTED` is annotated as an argument on a function, +indicates that said argument may be passed, even if it is not rooted. +In the ordinary course of events, +the julia ABI guarantees that callers root values before passing them to +callees. However, some functions do not follow this ABI and allow values +to be passed to them even though they are not rooted. Note however, that +this does not automatically imply that said argument will be preserved. +The `ROOTS_TEMPORARILY` annotation provides the stronger guarantee that, +not only may the value be unrooted when passed, it will also be preserved +across any internal safepoints by the callee. + +Note that JL_NOTSAFEPOINT essentially implies JL_MAYBE_UNROOTED/JL_ROOTS_TEMPORARILY, +because the rootedness of an argument is irrelevant if the function contains +no safepoints. + +One additional point to note is that these annotations apply on both the +caller and the callee side. On the caller side, they lift rootedness +restrictions that are normally required for julia ABI functions. On +the callee side, they have the reverse effect of preventing these arguments +from being considered implicitly rooted. + +If either of these annotations is applied to the function as a whole, it applies +to all arguments of the function. This should generally only be necessary for +varargs functions. + +Usage example: +```c +JL_DLLEXPORT void JL_NORETURN jl_throw(jl_value_t *e JL_MAYBE_UNROOTED); +jl_value_t *jl_alloc_error(); + +void example() { + // The return value of the allocation is unrooted. This would normally + // be an error, but is allowed because of the above annotation. + jl_throw(jl_alloc_error()); +} +``` + +### JL_PROPAGATES_ROOT + +This annotation is commonly found on accessor functions that return one rootable +object stored within another. When annotated on a function argument, it tells +the analyzer that the root for that argument also applies to the value returned +by the function. + +Usage Example: +```c +jl_value_t *jl_svecref(jl_svec_t *t JL_PROPAGATES_ROOT, size_t i) JL_NOTSAFEPOINT; + +size_t example(jl_svec_t *svec) { + jl_value_t *val = jl_svecref(svec, 1) + // This is valid, because, as annotated by the PROPAGATES_ROOT annotation, + // jl_svecref propagates the rooted-ness from `svec` to `val` + jl_gc_safepoint(); + return jl_unbox_long(val); +} +``` + +### JL_ROOTING_ARGUMENT/JL_ROOTED_ARGUMENT + +This is essentially the assignment counterpart to `JL_PROPAGATES_ROOT`. +When assigning a value to a field of another value that is already rooted, +the assigned value will inherit the root of the value it is assigned into. + +Usage Example: +```c +void jl_svecset(void *t JL_ROOTING_ARGUMENT, size_t i, void *x JL_ROOTED_ARGUMENT) JL_NOTSAFEPOINT + + +size_t example(jl_svec_t *svec) { + jl_value_t *val = jl_box_long(10000); + jl_svecset(svec, val); + // This is valid, because the annotations imply that the + // jl_svecset propagates the rooted-ness from `svec` to `val` + jl_gc_safepoint(); + return jl_unbox_long(val); +} +``` + +### JL_GC_DISABLED + +This annotation implies that this function is only called with the GC runtime-disabled. +Functions of this kind are most often encountered during startup and in the GC code itself. +Note that this annotation is checked against the runtime enable/disable calls, so clang will +know if you lie. This is not a good way to disable processing of a given function if the +GC is not actually disabled (use ifdef __clang_analyzer__ for that if you must). + +Usage example: +```c +void jl_do_magic() JL_GC_DISABLED { + // Wildly allocate here with no regard for roots +} + +void example() { + int en = jl_gc_enable(0); + jl_do_magic(); + jl_gc_enable(en); +} +``` + +### JL_REQUIRE_ROOTED_SLOT + +This annotation requires the caller to pass in a slot that is rooted (i.e. values assigned +to this slot will be rooted). + +Usage example: +```c +void jl_do_processing(jl_value_t **slot JL_REQUIRE_ROOTED_SLOT) { + *slot = jl_box_long(1); + // Ok, only, because the slot was annotated as rooting + jl_gc_safepoint(); +} + +void example() { + jl_value_t *slot = NULL; + JL_GC_PUSH1(&slot); + jl_do_processing(&slot); + JL_GC_POP(); +} +``` + +### JL_GLOBALLY_ROOTED + +This annotation implies that a given value is always globally rooted. +It can be applied to global variable declarations, in which case it +will apply to the value of those variables (or values if the declaration +if for an array), or to functions, in which case it will apply to the +return value of such functions (e.g. for functions that always return +some private, globally rooted value). + +Usage example: +``` +extern JL_DLLEXPORT jl_datatype_t *jl_any_type JL_GLOBALLY_ROOTED; +jl_ast_context_t *jl_ast_ctx(fl_context_t *fl) JL_GLOBALLY_ROOTED; +``` + +### JL_ALWAYS_LEAFTYPE + +This annotations is essentially equivalent to JL_GLOBALLY_ROOTED, except that +is should only be used if those values are globally rooted by virtue of being +a leaftype. The rooting of leaftypes is a bit complicated, and we can generally +assume that leaftypes are rooted where they are used, but we may refine this +property in the future, so the separate annotation helps split out the reason +for being globally rooted. + +The analyzer also automatically detects checks for leaftype-ness and will not +complain about missing GC roots on these paths. + +``` +JL_DLLEXPORT jl_value_t *jl_apply_array_type(jl_value_t *type, size_t dim) JL_ALWAYS_LEAFTYPE; +``` + +### JL_GC_PROMISE_ROOTED + +This is a function-like annotation. Any value passed to this annotation will be considered +rooted for the scope of the current function. It is designed as an escape hatch +for analyzer inadequacy or complicated situations. However, it should be used sparingly, +in favor of improving the analyzer itself. + +``` +void example() { + jl_value_t *val = jl_alloc_something(); + if (some_condition) { + // We happen to know for complicated external reasons + // that val is rooted under these conditions + JL_GC_PROMISE_ROOTED(val); + } +} +``` + +## Completeness of analysis + +The analyzer only looks at local information. In particular, e.g. in the `PROPAGATES_ROOT` case +above, it assumes that such memory is only modified in ways it can see, not in any called +functions (unless it happens to decide to consider them in its analysis) and not in any concurrently +running threads. As such, it may miss a few problematic cases, though in practice such concurrent +modification is fairly rare. Improving the analyzer to handle more such cases may be an interesting +topic for future work. diff --git a/src/manual/documentation.md b/src/manual/documentation.md index 7bb282b..8cf5dd5 100644 --- a/src/manual/documentation.md +++ b/src/manual/documentation.md @@ -616,13 +616,13 @@ the Julia documentation itself. For example: ```julia """ - eigvals!(A,[irange,][vl,][vu]) -> values + accumulate!(op, y, x) -Same as [`eigvals`](@ref), but saves space by overwriting the input `A`, instead of creating a copy. +Cumulative operation `op` on a vector `x`, storing the result in `y`. See also [`accumulate`](@ref). """ ``` -This will create a link in the generated docs to the `eigvals` documentation +This will create a link in the generated docs to the `accumulate` 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. diff --git a/src/manual/environment-variables.md b/src/manual/environment-variables.md index ba9569e..ebc4617 100644 --- a/src/manual/environment-variables.md +++ b/src/manual/environment-variables.md @@ -10,7 +10,7 @@ a permanent effect. The current value of the same environment variable is determined by evaluating `ENV["JULIA_EDITOR"]`. The environment variables that Julia uses generally start with `JULIA`. If -[`Base.versioninfo`](@ref) is called with `verbose` equal to `true`, then the +[`InteractiveUtils.versioninfo`](@ref) is called with `verbose` equal to `true`, then the output will list defined environment variables relevant for Julia, including those for which `JULIA` appears in the name. @@ -153,7 +153,7 @@ falls back to `/bin/sh` if `$SHELL` is unset. ### `JULIA_EDITOR` -The editor returned by `Base.editor()` and used in, e.g., [`Base.edit`](@ref), +The editor returned by `InteractiveUtils.editor()` and used in, e.g., [`InteractiveUtils.edit`](@ref), referring to the command of the preferred editor, for instance `vim`. `$JULIA_EDITOR` takes precedence over `$VISUAL`, which in turn takes precedence diff --git a/src/manual/functions.md b/src/manual/functions.md index c4ce2e9..9ee63d8 100644 --- a/src/manual/functions.md +++ b/src/manual/functions.md @@ -164,7 +164,6 @@ A few special expressions correspond to calls to functions with non-obvious name | `[A; B; C; ...]` | [`vcat`](@ref) | | `[A B; C D; ...]` | [`hvcat`](@ref) | | `A'` | [`adjoint`](@ref) | -| `A.'` | [`transpose`](@ref) | | `1:n` | [`colon`](@ref) | | `A[i]` | [`getindex`](@ref) | | `A[i] = x` | [`setindex!`](@ref) | @@ -692,7 +691,8 @@ the results (see [Pre-allocating outputs](@ref)). A convenient syntax for this i is equivalent to `broadcast!(identity, X, ...)` except that, as above, the `broadcast!` loop is fused with any nested "dot" calls. For example, `X .= sin.(Y)` is equivalent to `broadcast!(sin, X, Y)`, overwriting `X` with `sin.(Y)` in-place. If the left-hand side is an array-indexing expression, -e.g. `X[2:end] .= sin.(Y)`, then it translates to `broadcast!` on a `view`, e.g. `broadcast!(sin, view(X, 2:endof(X)), Y)`, +e.g. `X[2:end] .= sin.(Y)`, then it translates to `broadcast!` on a `view`, e.g. +`broadcast!(sin, view(X, 2:lastindex(X)), Y)`, so that the left-hand side is updated in-place. Since adding dots to many operations and function calls in an expression diff --git a/src/manual/getting-started.md b/src/manual/getting-started.md index dd3992a..127408f 100644 --- a/src/manual/getting-started.md +++ b/src/manual/getting-started.md @@ -95,12 +95,12 @@ julia [switches] -- [programfile] [args...] -p, --procs {N|auto} N개의 worker 프로세스를 추가로 생성한다. "auto"는 현재 Julia를 실행하는 컴퓨터의 최대 코어수만큼 worker 프로세스를 생성한다. - --machine-file 에 나열된 호스트에서 worker 프로세스를 실행한다. + --machine-file 에 나열된 호스트에서 worker 프로세스를 실행한다. -i 대화형 모드; PEPL을 돌리며 ininteractive()는 true이다. -q, --quiet 시작할 때 배너, REPL 경고를 제거한다. - --banner={yes|no} 시작 배너 사용/사용하지 않는다. - --color={yes|no} 모든 텍스트에 색상을 표시하거나 표시하지 않는다. + --banner={yes|no|auto} 시작 배너 사용/사용하지 않는다. + --color={yes|no|auto} 모든 텍스트에 색상을 표시하거나 표시하지 않는다. --history-file={yes|no} 작업내역을 저장하거나 로드한다. --depwarn={yes|no|error} 문법과 함수가 폐기됐다는 경고를 활성화/비활성화 한다.("error"는 경고를 에러로 바꾼다.) diff --git a/src/manual/interfaces.md b/src/manual/interfaces.md index 89e8c66..236641c 100644 --- a/src/manual/interfaces.md +++ b/src/manual/interfaces.md @@ -115,9 +115,12 @@ Now, when we ask Julia to [`collect`](@ref) all the elements into an array it ca of the right size instead of blindly [`push!`](@ref)ing each element into a `Vector{Any}`: ```jldoctest squaretype -julia> collect(Squares(10))' # transposed to save space -1×10 RowVector{Int64,Array{Int64,1}}: - 1 4 9 16 25 36 49 64 81 100 +julia> collect(Squares(4)) +4-element Array{Int64,1}: + 1 + 4 + 9 + 16 ``` While we can rely upon generic implementations, we can also extend specific methods where we know @@ -150,9 +153,12 @@ julia> Base.next(::Iterators.Reverse{Squares}, state) = (state*state, state-1) julia> Base.done(::Iterators.Reverse{Squares}, state) = state < 1 -julia> collect(Iterators.reverse(Squares(10)))' # transposed to save space -1×10 RowVector{Int64,Array{Int64,1}}: - 100 81 64 49 36 25 16 9 4 1 +julia> collect(Iterators.reverse(Squares(4))) +4-element Array{Int64,1}: + 16 + 9 + 4 + 1 ``` ## Indexing @@ -161,7 +167,8 @@ julia> collect(Iterators.reverse(Squares(10)))' # transposed to save space |:-------------------- |:-------------------------------- | | `getindex(X, i)` | `X[i]`, indexed element access | | `setindex!(X, v, i)` | `X[i] = v`, indexed assignment | -| `endof(X)` | The last index, used in `X[end]` | +| `firstindex(X)` | The first index | +| `lastindex(X)` | The last index, used in `X[end]` | 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` @@ -177,11 +184,12 @@ julia> Squares(100)[23] 529 ``` -Additionally, to support the syntax `S[end]`, we must define [`endof`](@ref) to specify the last valid -index: +Additionally, to support the syntax `S[end]`, we must define [`lastindex`](@ref) to specify the last +valid index. It is recommended to also define [`firstindex`](@ref) to specify the first valid index: ```jldoctest squaretype -julia> Base.endof(S::Squares) = length(S) +julia> Base.firstindex(S::Squares) = 1 +julia> Base.lastindex(S::Squares) = length(S) julia> Squares(23)[end] 529 @@ -275,28 +283,31 @@ methods are all it takes for `SquaresVector` to be an iterable, indexable, and c array: ```jldoctest squarevectype -julia> s = SquaresVector(7) -7-element SquaresVector: +julia> s = SquaresVector(4) +4-element SquaresVector: 1 4 9 16 - 25 - 36 - 49 -julia> s[s .> 20] -3-element Array{Int64,1}: - 25 - 36 - 49 +julia> s[s .> 8] +2-element Array{Int64,1}: + 9 + 16 -julia> s \ [1 2; 3 4; 5 6; 7 8; 9 10; 11 12; 13 14] -1×2 RowVector{Float64,Array{Float64,1}}: - 0.305389 0.335329 +julia> s + s +4-element Array{Int64,1}: + 2 + 8 + 18 + 32 -julia> s ⋅ s # dot(s, s) -4676 +julia> sin.(s) +4-element Array{Float64,1}: + 0.8414709848078965 + -0.7568024953079282 + 0.4121184852417566 + -0.2879033166650653 ``` As a more complicated example, let's define our own toy N-dimensional sparse-like array type built @@ -382,8 +393,8 @@ julia> A[SquaresVector(3)] 4.0 9.0 -julia> dot(A[:,1],A[:,2]) -32.0 +julia> mean(A) +5.0 ``` If you are defining an array type that allows non-traditional indexing (indices that start at diff --git a/src/manual/packages.md b/src/manual/packages.md index fc50a29..105686e 100644 --- a/src/manual/packages.md +++ b/src/manual/packages.md @@ -3,8 +3,8 @@ Julia has a built-in package manager for installing add-on functionality written in Julia. It can also install external libraries using your operating system's standard system for doing so, or by compiling from source. The list of registered Julia packages can be found at [http://pkg.julialang.org](http://pkg.julialang.org). -All package manager commands are found in the `Pkg` module, included in Julia's `Base` -install. +All package manager commands are found in the `Pkg` standard library which becomes available after using +`import Pkg`. First we'll go over the mechanics of the `Pkg` family of commands and then we'll provide some guidance on how to get your package registered. Be sure to read the section below on package naming diff --git a/src/manual/parallel-computing.md b/src/manual/parallel-computing.md index 85257e6..514e36d 100644 --- a/src/manual/parallel-computing.md +++ b/src/manual/parallel-computing.md @@ -284,15 +284,12 @@ snippet: ```julia-repl A = rand(10,10) -remotecall_fetch(()->norm(A), 2) +remotecall_fetch(()->sum(A), 2) ``` -In this case [`norm`](@ref) is a function that takes 2D array as a parameter, and MUST be defined in -the remote process. You could use any function other than `norm` as long as it is defined in the remote -process and accepts the appropriate parameter. - +In this case [`sum`](@ref) MUST be defined in the remote process. Note that `A` is a global variable defined in the local workspace. Worker 2 does not have a variable called -`A` under `Main`. The act of shipping the closure `()->norm(A)` to worker 2 results in `Main.A` being defined +`A` under `Main`. The act of shipping the closure `()->sum(A)` to worker 2 results in `Main.A` being defined on 2. `Main.A` continues to exist on worker 2 even after the call `remotecall_fetch` returns. Remote calls with embedded global references (under `Main` module only) manage globals as follows: @@ -306,9 +303,9 @@ with embedded global references (under `Main` module only) manage globals as fol ```julia A = rand(10,10) - remotecall_fetch(()->norm(A), 2) # worker 2 + remotecall_fetch(()->sum(A), 2) # worker 2 A = rand(10,10) - remotecall_fetch(()->norm(A), 3) # worker 3 + remotecall_fetch(()->sum(A), 3) # worker 3 A = nothing ``` @@ -1083,7 +1080,7 @@ manner: * In this way a mesh network is established, wherein every worker is directly connected with every other worker. -While the default transport layer uses plain `TCPSocket`, it is possible for a Julia cluster to +While the default transport layer uses plain [`TCPSocket`](@ref), it is possible for a Julia cluster to provide its own transport. Julia provides two in-built cluster managers: @@ -1225,7 +1222,7 @@ connected to. For example, consider a Julia cluster of 32 processes in an all-to * Each Julia process thus has 31 communication tasks. * Each task handles all incoming messages from a single remote worker in a message-processing loop. - * The message-processing loop waits on an `IO` object (for example, a `TCPSocket` in the default + * The message-processing loop waits on an `IO` object (for example, a [`TCPSocket`](@ref) in the default implementation), reads an entire message, processes it and waits for the next one. * Sending messages to a process is done directly from any Julia task--not just communication tasks--again, via the appropriate `IO` object. diff --git a/src/manual/strings.md b/src/manual/strings.md index 7949d57..2f680f7 100644 --- a/src/manual/strings.md +++ b/src/manual/strings.md @@ -178,12 +178,15 @@ julia> str[end] '\n': ASCII/Unicode U+000a (category Cc: Other, control) ``` -All indexing in Julia is 1-based: the first element of any integer-indexed object is found at +Many Julia objects, including strings, can be indexed with integers. The index of the first +element is returned by [`firstindex(str)`](@ref), and the index of the last element +with [`lastindex(str)`](@ref). The keyword`end` can be used inside an indexing +operation as shorthand for the last index along the given dimension. +Most indexing in Julia is 1-based: the first element of many integer-indexed objects is found at index 1. (As we will see below, this does not necessarily mean that the last element is found at index `n`, where `n` is the length of the string.) -In any indexing expression, the keyword `end` can be used as a shorthand for the last index (computed -by [`endof(str)`](@ref)). You can perform arithmetic and other operations with `end`, just like +You can perform arithmetic and other operations with `end`, just like a normal value: ```jldoctest helloworldstring @@ -302,14 +305,14 @@ julia> s[1:4] ``` Because of variable-length encodings, the number of characters in a string (given by [`length(s)`](@ref)) -is not always the same as the last index. If you iterate through the indices 1 through [`endof(s)`](@ref) +is not always the same as the last index. If you iterate through the indices 1 through [`lastindex(s)`](@ref) and index into `s`, the sequence of characters returned when errors aren't thrown is the sequence -of characters comprising the string `s`. Thus we have the identity that `length(s) <= endof(s)`, +of characters comprising the string `s`. Thus we have the identity that `length(s) <= lastindex(s)`, since each character in a string must have its own index. The following is an inefficient and verbose way to iterate through the characters of `s`: ```jldoctest unicodestring -julia> for i = 1:endof(s) +julia> for i = begindex(s):lastindex(s) try println(s[i]) catch @@ -562,13 +565,14 @@ julia> join(["apples", "bananas", "pineapples"], ", ", " and ") Some other useful functions include: - * [`endof(str)`](@ref) gives the maximal (byte) index that can be used to index into `str`. + * [`firstindex(str)`](@ref) gives the minimal (byte) index that can be used to index into `str` (always 1 for strings, not necessarily true for other containers). + * [`lastindex(str)`](@ref) gives the maximal (byte) index that can be used to index into `str`. * [`length(str)`](@ref) the number of characters in `str`. * [`length(str, i, j)`](@ref) the number of valid character indices in `str` from `i` to `j`. * [`i = start(str)`](@ref start) gives the first valid index at which a character can be found in `str` (typically 1). * [`c, j = next(str,i)`](@ref next) returns next character at or after the index `i` and the next valid - character index following that. With [`start`](@ref) and [`endof`](@ref), can be used to iterate + character index following that. With [`start`](@ref) and [`lastindex`](@ref), can be used to iterate through the characters in `str`. * [`thisind(str, i)`](@ref) given an arbitrary index into a string find the first index of the character into which the index points. * [`nextind(str, i, n=1)`](@ref) find the start of the `n`th character starting after index `i`. diff --git a/src/manual/style-guide.md b/src/manual/style-guide.md index f2a24be..cb59a41 100644 --- a/src/manual/style-guide.md +++ b/src/manual/style-guide.md @@ -92,7 +92,7 @@ Instead of: ```julia function double(a::AbstractArray{<:Number}) - for i = 1:endof(a) + for i = firstindex(a):lastindex(a) a[i] *= 2 end return a @@ -103,7 +103,7 @@ use: ```julia function double!(a::AbstractArray{<:Number}) - for i = 1:endof(a) + for i = firstindex(a):lastindex(a) a[i] *= 2 end return a diff --git a/src/manual/types.md b/src/manual/types.md index 21b1671..81cb5a7 100644 --- a/src/manual/types.md +++ b/src/manual/types.md @@ -907,7 +907,7 @@ alias for `Tuple{Vararg{T,N}}`, i.e. a tuple type containing exactly `N` element ### Named Tuple Types -Named tuples are instances of the `NamedTuple` type, which has two parameters: a tuple of +Named tuples are instances of the [`NamedTuple`](@ref) type, which has two parameters: a tuple of symbols giving the field names, and a tuple type giving the field types. ```jldoctest diff --git a/src/stdlib/InteractiveUtils.md b/src/stdlib/InteractiveUtils.md new file mode 100644 index 0000000..39555d3 --- /dev/null +++ b/src/stdlib/InteractiveUtils.md @@ -0,0 +1,25 @@ +# Interactive Utilities + +```@docs +InteractiveUtils.apropos +InteractiveUtils.varinfo +InteractiveUtils.versioninfo +InteractiveUtils.methodswith +InteractiveUtils.subtypes +InteractiveUtils.edit(::AbstractString, ::Integer) +InteractiveUtils.edit(::Any) +InteractiveUtils.@edit +InteractiveUtils.less(::AbstractString) +InteractiveUtils.less(::Any) +InteractiveUtils.@less +InteractiveUtils.@which +InteractiveUtils.@functionloc +InteractiveUtils.@code_lowered +InteractiveUtils.@code_typed +InteractiveUtils.code_warntype +InteractiveUtils.@code_warntype +InteractiveUtils.code_llvm +InteractiveUtils.@code_llvm +InteractiveUtils.code_native +InteractiveUtils.@code_native +``` diff --git a/src/stdlib/LinearAlgebra.md b/src/stdlib/LinearAlgebra.md index 2bdd802..00d677f 100644 --- a/src/stdlib/LinearAlgebra.md +++ b/src/stdlib/LinearAlgebra.md @@ -354,7 +354,6 @@ LinearAlgebra.tril! LinearAlgebra.diagind LinearAlgebra.diag LinearAlgebra.diagm -LinearAlgebra.scale! LinearAlgebra.rank LinearAlgebra.norm LinearAlgebra.vecnorm @@ -410,8 +409,6 @@ LinearAlgebra.istril LinearAlgebra.istriu LinearAlgebra.isdiag LinearAlgebra.ishermitian -LinearAlgebra.RowVector -LinearAlgebra.ConjArray Base.transpose LinearAlgebra.transpose! Base.adjoint @@ -430,6 +427,8 @@ below (e.g. `mul!`) according to the usual Julia convention. ```@docs LinearAlgebra.mul! +LinearAlgebra.lmul! +LinearAlgebra.rmul! LinearAlgebra.ldiv! LinearAlgebra.rdiv! ``` diff --git a/src/stdlib/Markdown.md b/src/stdlib/Markdown.md new file mode 100644 index 0000000..7d82df3 --- /dev/null +++ b/src/stdlib/Markdown.md @@ -0,0 +1 @@ +# Markdown diff --git a/src/base/pkg.md b/src/stdlib/Pkg.md similarity index 66% rename from src/base/pkg.md rename to src/stdlib/Pkg.md index 4cc3bf7..b7cd686 100644 --- a/src/base/pkg.md +++ b/src/stdlib/Pkg.md @@ -9,22 +9,22 @@ package. See [PkgDev README](https://github.com/JuliaLang/PkgDev.jl/blob/master/ the documentation of those functions. ```@docs -Base.Pkg.dir -Base.Pkg.init -Base.Pkg.resolve -Base.Pkg.edit -Base.Pkg.add -Base.Pkg.rm -Base.Pkg.clone -Base.Pkg.setprotocol! -Base.Pkg.available -Base.Pkg.installed -Base.Pkg.status -Base.Pkg.update -Base.Pkg.checkout -Base.Pkg.pin -Base.Pkg.free -Base.Pkg.build -Base.Pkg.test -Base.Pkg.dependents +Pkg.dir +Pkg.init +Pkg.resolve +Pkg.edit +Pkg.add +Pkg.rm +Pkg.clone +Pkg.setprotocol! +Pkg.available +Pkg.installed +Pkg.status +Pkg.update +Pkg.checkout +Pkg.pin +Pkg.free +Pkg.build +Pkg.test +Pkg.dependents ``` diff --git a/src/stdlib/REPL.md b/src/stdlib/REPL.md index fd43037..158b077 100644 --- a/src/stdlib/REPL.md +++ b/src/stdlib/REPL.md @@ -314,7 +314,7 @@ Fields for output from functions can also be completed: ```julia-repl julia> split("","")[1].[TAB] -endof offset string +lastindex offset string ``` The completion of fields for output from functions uses type inference, and it can only suggest diff --git a/src/stdlib/UUIDs.md b/src/stdlib/UUIDs.md new file mode 100644 index 0000000..616ac63 --- /dev/null +++ b/src/stdlib/UUIDs.md @@ -0,0 +1,7 @@ +# UUIDs + +```@docs +UUIDs.uuid1 +UUIDs.uuid4 +UUIDs.uuid_version +``` diff --git a/src/stdlib/linearalgebra.md b/src/stdlib/linearalgebra.md index 2bdd802..00d677f 100644 --- a/src/stdlib/linearalgebra.md +++ b/src/stdlib/linearalgebra.md @@ -354,7 +354,6 @@ LinearAlgebra.tril! LinearAlgebra.diagind LinearAlgebra.diag LinearAlgebra.diagm -LinearAlgebra.scale! LinearAlgebra.rank LinearAlgebra.norm LinearAlgebra.vecnorm @@ -410,8 +409,6 @@ LinearAlgebra.istril LinearAlgebra.istriu LinearAlgebra.isdiag LinearAlgebra.ishermitian -LinearAlgebra.RowVector -LinearAlgebra.ConjArray Base.transpose LinearAlgebra.transpose! Base.adjoint @@ -430,6 +427,8 @@ below (e.g. `mul!`) according to the usual Julia convention. ```@docs LinearAlgebra.mul! +LinearAlgebra.lmul! +LinearAlgebra.rmul! LinearAlgebra.ldiv! LinearAlgebra.rdiv! ``` From 4831825cf795be797162e19539c24b9d87918cb5 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Thu, 1 Feb 2018 13:21:17 +0900 Subject: [PATCH 002/153] =?UTF-8?q?ko/latest=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- make.jl | 6 +++--- src/manual/unicode-input.md | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/make.jl b/make.jl index ee44af5..3506869 100644 --- a/make.jl +++ b/make.jl @@ -133,7 +133,7 @@ for stdlib in STDLIB_DOCS end makedocs( - build = joinpath(pwd(), "_build/html/ko"), + build = joinpath(pwd(), "_build/html/ko/latest"), modules = [Base, Core, BuildSysImg, [Base.root_module(Base, stdlib.stdlib) for stdlib in STDLIB_DOCS]...], clean = false, # true doctest = "doctest" in ARGS, @@ -146,6 +146,6 @@ makedocs( authors = "The Julia Project", analytics = "UA-110655381-2", # juliakorea 추척 ID pages = PAGES, - html_prettyurls = ("deploy" in ARGS), - html_canonical = ("deploy" in ARGS) ? "http://juliakorea.github.io/ko/" : nothing, # juliakorea 주소 (TODO: stable 버전 추가) + html_prettyurls = true, + html_canonical = "https://juliakorea.github.io/ko/latest/" ) diff --git a/src/manual/unicode-input.md b/src/manual/unicode-input.md index e1acf8f..e0659c7 100644 --- a/src/manual/unicode-input.md +++ b/src/manual/unicode-input.md @@ -32,7 +32,7 @@ function tab_completions(symbols...) end function unicode_data() - file = normpath(@__DIR__, "..", "..", "..", "..", "UnicodeData.txt") + file = normpath(@__DIR__, "..", "..", "..", "..", "..", "UnicodeData.txt") names = Dict{UInt32, String}() open(file) do unidata for line in readlines(unidata) From 4f75b2411fd05b403f83b296e20ba5debbb97bfb Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Tue, 6 Feb 2018 07:33:22 +0900 Subject: [PATCH 003/153] update Julia Commit 4b90831838 --- codex/NEWS.md | 20 ++++- codex/base/base.md | 2 +- codex/base/collections.md | 4 +- codex/devdocs/libgit2.md | 160 -------------------------------------- codex/index.md | 1 - codex/manual/functions.md | 11 +++ codex/manual/types.md | 2 +- make.jl | 1 - src/NEWS.md | 20 ++++- src/base/base.md | 2 +- src/base/collections.md | 4 +- src/devdocs/libgit2.md | 160 -------------------------------------- src/index.md | 1 - src/manual/functions.md | 11 +++ src/manual/types.md | 2 +- 15 files changed, 66 insertions(+), 335 deletions(-) delete mode 100644 codex/devdocs/libgit2.md delete mode 100644 src/devdocs/libgit2.md diff --git a/codex/NEWS.md b/codex/NEWS.md index b92a80a..f768c81 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -44,6 +44,9 @@ New language features * Values for `Enum`s can now be specified inside of a `begin` block when using the `@enum` macro ([#25424](https://github.com/JuliaLang/julia/issues/25424)). + * Keyword arguments can be required: if a default value is omitted, then an + exception is thrown if the caller does not assign the keyword a value ([#25830](https://github.com/JuliaLang/julia/issues/25830)). + Language changes ---------------- @@ -57,6 +60,10 @@ Language changes * The syntax `1.+2` is deprecated, since it is ambiguous: it could mean either `1 .+ 2` (the current meaning) or `1. + 2` ([#19089](https://github.com/JuliaLang/julia/issues/19089)). + * Mutable structs with no fields are no longer singletons; it is now possible to make + multiple instances of them that can be distinguished by `===` ([#25854](https://github.com/JuliaLang/julia/issues/25854)). + Zero-size immutable structs are still singletons. + * In string and character literals, backslash `\` may no longer precede unrecognized escape characters ([#22800](https://github.com/JuliaLang/julia/issues/22800)). @@ -199,6 +206,9 @@ This section lists changes that do not have deprecation warnings. * `readuntil` now does *not* include the delimiter in its result, matching the behavior of `readline`. Pass `keep=true` to get the old behavior ([#25633](https://github.com/JuliaLang/julia/issues/25633)). + * `countlines` now always counts the last non-empty line even if it does not + end with EOL, matching the behavior of `eachline` and `readlines` ([#25845](https://github.com/JuliaLang/julia/issues/25845)). + * `getindex(s::String, r::UnitRange{Int})` now throws `UnicodeError` if `last(r)` is not a valid index into `s` ([#22572](https://github.com/JuliaLang/julia/issues/22572)). @@ -404,6 +414,9 @@ This section lists changes that do not have deprecation warnings. to get the old behavior (only "space" characters are considered as word separators), use the keyword `wordsep=isspace`. + * `writedlm` in the standard library module DelimitedFiles now writes numeric values + using `print` rather than `print_shortest` ([#25745](https://github.com/JuliaLang/julia/issues/25745)). + * The `tempname` function used to create a file on Windows but not on other platforms. It now never creates a file ([#9053](https://github.com/JuliaLang/julia/issues/9053)). @@ -451,7 +464,7 @@ Library improvements * The function `randn` now accepts complex arguments (`Complex{T <: AbstractFloat}`) ([#21973](https://github.com/JuliaLang/julia/issues/21973)). - * `parse(Complex{T}, string)` can parse complex numbers in common formats ([#24713](https://github.com/JuliaLang/julia/issues/24713)). + * `parse(Complex{T}, string)` can parse complex numbers in some common formats ([#24713](https://github.com/JuliaLang/julia/issues/24713)). * The function `rand` can now pick up random elements from strings, associatives and sets ([#22228](https://github.com/JuliaLang/julia/issues/22228), [#21960](https://github.com/JuliaLang/julia/issues/21960), [#18155](https://github.com/JuliaLang/julia/issues/18155), [#22224](https://github.com/JuliaLang/julia/issues/22224)). @@ -695,7 +708,7 @@ Deprecated or removed in favor of `replace(s::AbstractString, pat => r; [count])` ([#25165](https://github.com/JuliaLang/julia/issues/25165)). Moreover, `count` cannot be negative anymore (use `typemax(Int)` instead ([#22325](https://github.com/JuliaLang/julia/issues/22325)). - * `read(io, type, dims)` is deprecated to `read!(io, Array{type}(dims))` ([#21450](https://github.com/JuliaLang/julia/issues/21450)). + * `read(io, type, dims)` is deprecated to `read!(io, Array{type}(uninitialized, dims))` ([#21450](https://github.com/JuliaLang/julia/issues/21450)). * `read(::IO, ::Ref)` is now a method of `read!`, since it mutates its `Ref` argument ([#21592](https://github.com/JuliaLang/julia/issues/21592)). @@ -995,6 +1008,9 @@ Deprecated or removed * `Base.@gc_preserve` has been deprecated in favor of `GC.@preserve` ([#25616](https://github.com/JuliaLang/julia/issues/25616)). + * `print_shortest` has been discontinued, but is still available in the `Base.Grisu` + submodule ([#25745](https://github.com/JuliaLang/julia/issues/25745)). + * `scale!` has been deprecated in favor of `mul!`, `lmul!`, and `rmul!` ([#25701](https://github.com/JuliaLang/julia/issues/25701), [#25812](https://github.com/JuliaLang/julia/issues/25812)). * `endof(a)` has been renamed to `lastindex(a)`, and the `end` keyword in indexing expressions now diff --git a/codex/base/base.md b/codex/base/base.md index e14de8d..bdb3264 100644 --- a/codex/base/base.md +++ b/codex/base/base.md @@ -74,7 +74,6 @@ primitive type ```@docs Base.Docs Base.Iterators -Base.LibGit2 Base.Libc Base.Meta Base.StackTraces @@ -298,6 +297,7 @@ Base.ParseError Core.StackOverflowError Base.SystemError Core.TypeError +Core.UndefKeywordError Core.UndefRefError Core.UndefVarError Base.InitError diff --git a/codex/base/collections.md b/codex/base/collections.md index d61babc..43ba36a 100644 --- a/codex/base/collections.md +++ b/codex/base/collections.md @@ -228,7 +228,7 @@ Partially implemented by: * [`Array`](@ref) * [`BitArray`](@ref) * [`ImmutableDict`](@ref Base.ImmutableDict) - * [`Iterators.IndexValue`](@ref) + * [`Iterators.Pairs`](@ref) ## Set-Like Collections @@ -279,5 +279,5 @@ Fully implemented by: ```@docs Base.Pair -Iterators.IndexValue +Iterators.Pairs ``` diff --git a/codex/devdocs/libgit2.md b/codex/devdocs/libgit2.md deleted file mode 100644 index 4b238bd..0000000 --- a/codex/devdocs/libgit2.md +++ /dev/null @@ -1,160 +0,0 @@ -# Base.LibGit2 - -The LibGit2 module provides bindings to [libgit2](https://libgit2.github.com/), a portable C library that -implements core functionality for the [Git](https://git-scm.com/) version control system. -These bindings are currently used to power Julia's package manager. -It is expected that this module will eventually be moved into a separate package. - -### Functionality - -Some of this documentation assumes some prior knowledge of the libgit2 API. -For more information on some of the objects and methods referenced here, consult the upstream -[libgit2 API reference](https://libgit2.github.com/libgit2/#v0.25.1). - -```@docs -Base.LibGit2.Buffer -Base.LibGit2.CheckoutOptions -Base.LibGit2.CloneOptions -Base.LibGit2.DescribeOptions -Base.LibGit2.DescribeFormatOptions -Base.LibGit2.DiffDelta -Base.LibGit2.DiffFile -Base.LibGit2.DiffOptionsStruct -Base.LibGit2.FetchHead -Base.LibGit2.FetchOptions -Base.LibGit2.GitAnnotated -Base.LibGit2.GitBlame -Base.LibGit2.GitBlob -Base.LibGit2.GitCommit -Base.LibGit2.GitHash -Base.LibGit2.GitObject -Base.LibGit2.GitRemote -Base.LibGit2.GitRemoteAnon -Base.LibGit2.GitRepo -Base.LibGit2.GitRepoExt -Base.LibGit2.GitRevWalker -Base.LibGit2.GitShortHash -Base.LibGit2.GitSignature -Base.LibGit2.GitStatus -Base.LibGit2.GitTag -Base.LibGit2.GitTree -Base.LibGit2.IndexEntry -Base.LibGit2.IndexTime -Base.LibGit2.BlameOptions -Base.LibGit2.MergeOptions -Base.LibGit2.ProxyOptions -Base.LibGit2.PushOptions -Base.LibGit2.RebaseOperation -Base.LibGit2.RebaseOptions -Base.LibGit2.RemoteCallbacks -Base.LibGit2.SignatureStruct -Base.LibGit2.StatusEntry -Base.LibGit2.StatusOptions -Base.LibGit2.StrArrayStruct -Base.LibGit2.TimeStruct -Base.LibGit2.add! -Base.LibGit2.add_fetch! -Base.LibGit2.add_push! -Base.LibGit2.addblob! -Base.LibGit2.author -Base.LibGit2.authors -Base.LibGit2.branch -Base.LibGit2.branch! -Base.LibGit2.checkout! -Base.LibGit2.clone -Base.LibGit2.commit -Base.LibGit2.committer -Base.LibGit2.count(::Function, ::Base.LibGit2.GitRevWalker; ::Base.LibGit2.GitHash, ::Cint, ::Bool) -Base.LibGit2.counthunks -Base.LibGit2.create_branch -Base.LibGit2.credentials_callback -Base.LibGit2.credentials_cb -Base.LibGit2.default_signature -Base.LibGit2.delete_branch -Base.LibGit2.diff_files -Base.LibGit2.entryid -Base.LibGit2.entrytype -Base.LibGit2.fetch -Base.LibGit2.fetchheads -Base.LibGit2.fetch_refspecs -Base.LibGit2.fetchhead_foreach_cb -Base.LibGit2.merge_base -Base.LibGit2.merge!(::Base.LibGit2.GitRepo; ::Any...) -Base.LibGit2.merge!(::Base.LibGit2.GitRepo, ::Vector{Base.LibGit2.GitAnnotated}; ::Base.LibGit2.MergeOptions, ::Base.LibGit2.CheckoutOptions) -Base.LibGit2.merge!(::Base.LibGit2.GitRepo, ::Vector{Base.LibGit2.GitAnnotated}, ::Bool; ::Base.LibGit2.MergeOptions, ::Base.LibGit2.CheckoutOptions) -Base.LibGit2.ffmerge! -Base.LibGit2.fullname -Base.LibGit2.features -Base.LibGit2.filename -Base.LibGit2.filemode -Base.LibGit2.gitdir -Base.LibGit2.git_url -Base.LibGit2.@githash_str -Base.LibGit2.head -Base.LibGit2.head! -Base.LibGit2.head_oid -Base.LibGit2.headname -Base.LibGit2.init -Base.LibGit2.is_ancestor_of -Base.LibGit2.isbinary -Base.LibGit2.iscommit -Base.LibGit2.isdiff -Base.LibGit2.isdirty -Base.LibGit2.isorphan -Base.LibGit2.isset -Base.LibGit2.iszero -Base.LibGit2.lookup_branch -Base.LibGit2.map(::Function, ::Base.LibGit2.GitRevWalker; ::Base.LibGit2.GitHash, ::AbstractString, ::Cint, ::Bool) -Base.LibGit2.mirror_callback -Base.LibGit2.mirror_cb -Base.LibGit2.message -Base.LibGit2.merge_analysis -Base.LibGit2.name -Base.LibGit2.need_update -Base.LibGit2.objtype -Base.LibGit2.path -Base.LibGit2.peel -Base.LibGit2.posixpath -Base.LibGit2.push -Base.LibGit2.push!(::Base.LibGit2.GitRevWalker, ::Base.LibGit2.GitHash) -Base.LibGit2.push_head! -Base.LibGit2.push_refspecs -Base.LibGit2.raw -Base.LibGit2.read_tree! -Base.LibGit2.rebase! -Base.LibGit2.ref_list -Base.LibGit2.reftype -Base.LibGit2.remotes -Base.LibGit2.remove! -Base.LibGit2.reset -Base.LibGit2.reset! -Base.LibGit2.restore -Base.LibGit2.revcount -Base.LibGit2.set_remote_url -Base.LibGit2.shortname -Base.LibGit2.snapshot -Base.LibGit2.status -Base.LibGit2.stage -Base.LibGit2.tag_create -Base.LibGit2.tag_delete -Base.LibGit2.tag_list -Base.LibGit2.target -Base.LibGit2.toggle -Base.LibGit2.transact -Base.LibGit2.treewalk -Base.LibGit2.upstream -Base.LibGit2.update! -Base.LibGit2.url -Base.LibGit2.version -Base.LibGit2.with -Base.LibGit2.with_warn -Base.LibGit2.workdir -Base.LibGit2.GitObject(::Base.LibGit2.GitTreeEntry) -Base.LibGit2.UserPasswordCredential -Base.LibGit2.SSHCredential -Base.LibGit2.isfilled -Base.LibGit2.CachedCredentials -Base.LibGit2.CredentialPayload -Base.LibGit2.approve -Base.LibGit2.reject -``` diff --git a/codex/index.md b/codex/index.md index 3dca8a7..7998f37 100644 --- a/codex/index.md +++ b/codex/index.md @@ -115,7 +115,6 @@ Please read the [release notes](NEWS.md) to see what has changed since the last * [Bounds checking](@ref) * [Proper maintenance and care of multi-threading locks](@ref) * [Arrays with custom indices](@ref) - * [Base.LibGit2](@ref) * [Module loading](@ref) * [Inference](@ref) * Developing/debugging Julia's C code diff --git a/codex/manual/functions.md b/codex/manual/functions.md index 9ee63d8..df9696f 100644 --- a/codex/manual/functions.md +++ b/codex/manual/functions.md @@ -518,6 +518,17 @@ function f(x; y=0, kwargs...) end ``` +If a keyword argument is not assigned a default value in the method definition, +then it is *required*: an [`UndefKeywordError`](@ref) exception will be thrown +if the caller does not assign it a value: +```julia +function f(x; y) + ### +end +f(3, y=5) # ok, y is assigned +f(3) # throws UndefKeywordError(:y) +``` + Inside `f`, `kwargs` will be a named tuple. Named tuples (as well as dictionaries) can be passed as keyword arguments using a semicolon in a call, e.g. `f(x, z=1; kwargs...)`. diff --git a/codex/manual/types.md b/codex/manual/types.md index 81cb5a7..e30405b 100644 --- a/codex/manual/types.md +++ b/codex/manual/types.md @@ -387,7 +387,7 @@ to point to different objects. Where required, mutable composite objects can be declared with the keyword `mutable struct`, to be discussed in the next section. -Composite types with no fields are singletons; there can be only one instance of such types: +Immutable composite types with no fields are singletons; there can be only one instance of such types: ```jldoctest julia> struct NoFields diff --git a/make.jl b/make.jl index 3506869..41b1b08 100644 --- a/make.jl +++ b/make.jl @@ -115,7 +115,6 @@ const PAGES = [ "devdocs/boundscheck.md", "devdocs/locks.md", "devdocs/offset-arrays.md", - "devdocs/libgit2.md", "devdocs/require.md", "devdocs/inference.md", ], diff --git a/src/NEWS.md b/src/NEWS.md index 0848509..53596fd 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -32,6 +32,9 @@ * `@enum` 매크로를 쓸 때 `begin` 블럭으로 `Enum` 값을 특정할 수 있습니다 ([#25424](https://github.com/JuliaLang/julia/issues/25424)). + * 키워드 인자를 요구할 수 있습니다: 기본값을 생략한 경우, 호출하는 쪽에서 키워드 값을 지정하지 않으면 + 예외를 던집니다 ([#25830](https://github.com/JuliaLang/julia/issues/25830)). + Language changes ---------------- @@ -45,6 +48,10 @@ Language changes * The syntax `1.+2` is deprecated, since it is ambiguous: it could mean either `1 .+ 2` (the current meaning) or `1. + 2` ([#19089](https://github.com/JuliaLang/julia/issues/19089)). + * Mutable structs with no fields are no longer singletons; it is now possible to make + multiple instances of them that can be distinguished by `===` ([#25854](https://github.com/JuliaLang/julia/issues/25854)). + Zero-size immutable structs are still singletons. + * In string and character literals, backslash `\` may no longer precede unrecognized escape characters ([#22800](https://github.com/JuliaLang/julia/issues/22800)). @@ -187,6 +194,9 @@ This section lists changes that do not have deprecation warnings. * `readuntil` now does *not* include the delimiter in its result, matching the behavior of `readline`. Pass `keep=true` to get the old behavior ([#25633](https://github.com/JuliaLang/julia/issues/25633)). + * `countlines` now always counts the last non-empty line even if it does not + end with EOL, matching the behavior of `eachline` and `readlines` ([#25845](https://github.com/JuliaLang/julia/issues/25845)). + * `getindex(s::String, r::UnitRange{Int})` now throws `UnicodeError` if `last(r)` is not a valid index into `s` ([#22572](https://github.com/JuliaLang/julia/issues/22572)). @@ -392,6 +402,9 @@ This section lists changes that do not have deprecation warnings. to get the old behavior (only "space" characters are considered as word separators), use the keyword `wordsep=isspace`. + * `writedlm` in the standard library module DelimitedFiles now writes numeric values + using `print` rather than `print_shortest` ([#25745](https://github.com/JuliaLang/julia/issues/25745)). + * The `tempname` function used to create a file on Windows but not on other platforms. It now never creates a file ([#9053](https://github.com/JuliaLang/julia/issues/9053)). @@ -439,7 +452,7 @@ Library improvements * The function `randn` now accepts complex arguments (`Complex{T <: AbstractFloat}`) ([#21973](https://github.com/JuliaLang/julia/issues/21973)). - * `parse(Complex{T}, string)` can parse complex numbers in common formats ([#24713](https://github.com/JuliaLang/julia/issues/24713)). + * `parse(Complex{T}, string)` can parse complex numbers in some common formats ([#24713](https://github.com/JuliaLang/julia/issues/24713)). * The function `rand` can now pick up random elements from strings, associatives and sets ([#22228](https://github.com/JuliaLang/julia/issues/22228), [#21960](https://github.com/JuliaLang/julia/issues/21960), [#18155](https://github.com/JuliaLang/julia/issues/18155), [#22224](https://github.com/JuliaLang/julia/issues/22224)). @@ -683,7 +696,7 @@ Deprecated or removed in favor of `replace(s::AbstractString, pat => r; [count])` ([#25165](https://github.com/JuliaLang/julia/issues/25165)). Moreover, `count` cannot be negative anymore (use `typemax(Int)` instead ([#22325](https://github.com/JuliaLang/julia/issues/22325)). - * `read(io, type, dims)` is deprecated to `read!(io, Array{type}(dims))` ([#21450](https://github.com/JuliaLang/julia/issues/21450)). + * `read(io, type, dims)` is deprecated to `read!(io, Array{type}(uninitialized, dims))` ([#21450](https://github.com/JuliaLang/julia/issues/21450)). * `read(::IO, ::Ref)` is now a method of `read!`, since it mutates its `Ref` argument ([#21592](https://github.com/JuliaLang/julia/issues/21592)). @@ -983,6 +996,9 @@ Deprecated or removed * `Base.@gc_preserve` has been deprecated in favor of `GC.@preserve` ([#25616](https://github.com/JuliaLang/julia/issues/25616)). + * `print_shortest` has been discontinued, but is still available in the `Base.Grisu` + submodule ([#25745](https://github.com/JuliaLang/julia/issues/25745)). + * `scale!` has been deprecated in favor of `mul!`, `lmul!`, and `rmul!` ([#25701](https://github.com/JuliaLang/julia/issues/25701), [#25812](https://github.com/JuliaLang/julia/issues/25812)). * `endof(a)` has been renamed to `lastindex(a)`, and the `end` keyword in indexing expressions now diff --git a/src/base/base.md b/src/base/base.md index e14de8d..bdb3264 100644 --- a/src/base/base.md +++ b/src/base/base.md @@ -74,7 +74,6 @@ primitive type ```@docs Base.Docs Base.Iterators -Base.LibGit2 Base.Libc Base.Meta Base.StackTraces @@ -298,6 +297,7 @@ Base.ParseError Core.StackOverflowError Base.SystemError Core.TypeError +Core.UndefKeywordError Core.UndefRefError Core.UndefVarError Base.InitError diff --git a/src/base/collections.md b/src/base/collections.md index d61babc..43ba36a 100644 --- a/src/base/collections.md +++ b/src/base/collections.md @@ -228,7 +228,7 @@ Partially implemented by: * [`Array`](@ref) * [`BitArray`](@ref) * [`ImmutableDict`](@ref Base.ImmutableDict) - * [`Iterators.IndexValue`](@ref) + * [`Iterators.Pairs`](@ref) ## Set-Like Collections @@ -279,5 +279,5 @@ Fully implemented by: ```@docs Base.Pair -Iterators.IndexValue +Iterators.Pairs ``` diff --git a/src/devdocs/libgit2.md b/src/devdocs/libgit2.md deleted file mode 100644 index 4b238bd..0000000 --- a/src/devdocs/libgit2.md +++ /dev/null @@ -1,160 +0,0 @@ -# Base.LibGit2 - -The LibGit2 module provides bindings to [libgit2](https://libgit2.github.com/), a portable C library that -implements core functionality for the [Git](https://git-scm.com/) version control system. -These bindings are currently used to power Julia's package manager. -It is expected that this module will eventually be moved into a separate package. - -### Functionality - -Some of this documentation assumes some prior knowledge of the libgit2 API. -For more information on some of the objects and methods referenced here, consult the upstream -[libgit2 API reference](https://libgit2.github.com/libgit2/#v0.25.1). - -```@docs -Base.LibGit2.Buffer -Base.LibGit2.CheckoutOptions -Base.LibGit2.CloneOptions -Base.LibGit2.DescribeOptions -Base.LibGit2.DescribeFormatOptions -Base.LibGit2.DiffDelta -Base.LibGit2.DiffFile -Base.LibGit2.DiffOptionsStruct -Base.LibGit2.FetchHead -Base.LibGit2.FetchOptions -Base.LibGit2.GitAnnotated -Base.LibGit2.GitBlame -Base.LibGit2.GitBlob -Base.LibGit2.GitCommit -Base.LibGit2.GitHash -Base.LibGit2.GitObject -Base.LibGit2.GitRemote -Base.LibGit2.GitRemoteAnon -Base.LibGit2.GitRepo -Base.LibGit2.GitRepoExt -Base.LibGit2.GitRevWalker -Base.LibGit2.GitShortHash -Base.LibGit2.GitSignature -Base.LibGit2.GitStatus -Base.LibGit2.GitTag -Base.LibGit2.GitTree -Base.LibGit2.IndexEntry -Base.LibGit2.IndexTime -Base.LibGit2.BlameOptions -Base.LibGit2.MergeOptions -Base.LibGit2.ProxyOptions -Base.LibGit2.PushOptions -Base.LibGit2.RebaseOperation -Base.LibGit2.RebaseOptions -Base.LibGit2.RemoteCallbacks -Base.LibGit2.SignatureStruct -Base.LibGit2.StatusEntry -Base.LibGit2.StatusOptions -Base.LibGit2.StrArrayStruct -Base.LibGit2.TimeStruct -Base.LibGit2.add! -Base.LibGit2.add_fetch! -Base.LibGit2.add_push! -Base.LibGit2.addblob! -Base.LibGit2.author -Base.LibGit2.authors -Base.LibGit2.branch -Base.LibGit2.branch! -Base.LibGit2.checkout! -Base.LibGit2.clone -Base.LibGit2.commit -Base.LibGit2.committer -Base.LibGit2.count(::Function, ::Base.LibGit2.GitRevWalker; ::Base.LibGit2.GitHash, ::Cint, ::Bool) -Base.LibGit2.counthunks -Base.LibGit2.create_branch -Base.LibGit2.credentials_callback -Base.LibGit2.credentials_cb -Base.LibGit2.default_signature -Base.LibGit2.delete_branch -Base.LibGit2.diff_files -Base.LibGit2.entryid -Base.LibGit2.entrytype -Base.LibGit2.fetch -Base.LibGit2.fetchheads -Base.LibGit2.fetch_refspecs -Base.LibGit2.fetchhead_foreach_cb -Base.LibGit2.merge_base -Base.LibGit2.merge!(::Base.LibGit2.GitRepo; ::Any...) -Base.LibGit2.merge!(::Base.LibGit2.GitRepo, ::Vector{Base.LibGit2.GitAnnotated}; ::Base.LibGit2.MergeOptions, ::Base.LibGit2.CheckoutOptions) -Base.LibGit2.merge!(::Base.LibGit2.GitRepo, ::Vector{Base.LibGit2.GitAnnotated}, ::Bool; ::Base.LibGit2.MergeOptions, ::Base.LibGit2.CheckoutOptions) -Base.LibGit2.ffmerge! -Base.LibGit2.fullname -Base.LibGit2.features -Base.LibGit2.filename -Base.LibGit2.filemode -Base.LibGit2.gitdir -Base.LibGit2.git_url -Base.LibGit2.@githash_str -Base.LibGit2.head -Base.LibGit2.head! -Base.LibGit2.head_oid -Base.LibGit2.headname -Base.LibGit2.init -Base.LibGit2.is_ancestor_of -Base.LibGit2.isbinary -Base.LibGit2.iscommit -Base.LibGit2.isdiff -Base.LibGit2.isdirty -Base.LibGit2.isorphan -Base.LibGit2.isset -Base.LibGit2.iszero -Base.LibGit2.lookup_branch -Base.LibGit2.map(::Function, ::Base.LibGit2.GitRevWalker; ::Base.LibGit2.GitHash, ::AbstractString, ::Cint, ::Bool) -Base.LibGit2.mirror_callback -Base.LibGit2.mirror_cb -Base.LibGit2.message -Base.LibGit2.merge_analysis -Base.LibGit2.name -Base.LibGit2.need_update -Base.LibGit2.objtype -Base.LibGit2.path -Base.LibGit2.peel -Base.LibGit2.posixpath -Base.LibGit2.push -Base.LibGit2.push!(::Base.LibGit2.GitRevWalker, ::Base.LibGit2.GitHash) -Base.LibGit2.push_head! -Base.LibGit2.push_refspecs -Base.LibGit2.raw -Base.LibGit2.read_tree! -Base.LibGit2.rebase! -Base.LibGit2.ref_list -Base.LibGit2.reftype -Base.LibGit2.remotes -Base.LibGit2.remove! -Base.LibGit2.reset -Base.LibGit2.reset! -Base.LibGit2.restore -Base.LibGit2.revcount -Base.LibGit2.set_remote_url -Base.LibGit2.shortname -Base.LibGit2.snapshot -Base.LibGit2.status -Base.LibGit2.stage -Base.LibGit2.tag_create -Base.LibGit2.tag_delete -Base.LibGit2.tag_list -Base.LibGit2.target -Base.LibGit2.toggle -Base.LibGit2.transact -Base.LibGit2.treewalk -Base.LibGit2.upstream -Base.LibGit2.update! -Base.LibGit2.url -Base.LibGit2.version -Base.LibGit2.with -Base.LibGit2.with_warn -Base.LibGit2.workdir -Base.LibGit2.GitObject(::Base.LibGit2.GitTreeEntry) -Base.LibGit2.UserPasswordCredential -Base.LibGit2.SSHCredential -Base.LibGit2.isfilled -Base.LibGit2.CachedCredentials -Base.LibGit2.CredentialPayload -Base.LibGit2.approve -Base.LibGit2.reject -``` diff --git a/src/index.md b/src/index.md index f52f498..c2fd3df 100644 --- a/src/index.md +++ b/src/index.md @@ -117,7 +117,6 @@ * [Bounds checking](@ref) * [Proper maintenance and care of multi-threading locks](@ref) * [Arrays with custom indices](@ref) - * [Base.LibGit2](@ref) * [Module loading](@ref) * [Inference](@ref) * Developing/debugging Julia's C code diff --git a/src/manual/functions.md b/src/manual/functions.md index 9ee63d8..df9696f 100644 --- a/src/manual/functions.md +++ b/src/manual/functions.md @@ -518,6 +518,17 @@ function f(x; y=0, kwargs...) end ``` +If a keyword argument is not assigned a default value in the method definition, +then it is *required*: an [`UndefKeywordError`](@ref) exception will be thrown +if the caller does not assign it a value: +```julia +function f(x; y) + ### +end +f(3, y=5) # ok, y is assigned +f(3) # throws UndefKeywordError(:y) +``` + Inside `f`, `kwargs` will be a named tuple. Named tuples (as well as dictionaries) can be passed as keyword arguments using a semicolon in a call, e.g. `f(x, z=1; kwargs...)`. diff --git a/src/manual/types.md b/src/manual/types.md index 81cb5a7..e30405b 100644 --- a/src/manual/types.md +++ b/src/manual/types.md @@ -387,7 +387,7 @@ to point to different objects. Where required, mutable composite objects can be declared with the keyword `mutable struct`, to be discussed in the next section. -Composite types with no fields are singletons; there can be only one instance of such types: +Immutable composite types with no fields are singletons; there can be only one instance of such types: ```jldoctest julia> struct NoFields From 81dffa72c152ad2e4180d4ce2742176149acaa6a Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Fri, 9 Feb 2018 00:01:04 +0900 Subject: [PATCH 004/153] update Julia Commit f8acac74c5 --- codex/NEWS.md | 7 +++++ codex/devdocs/ast.md | 2 +- codex/manual/constructors.md | 51 ++++++++++++++++++----------------- codex/manual/documentation.md | 16 ++++++----- codex/manual/stacktraces.md | 8 +++--- src/NEWS.md | 7 +++++ src/devdocs/ast.md | 2 +- src/manual/constructors.md | 51 ++++++++++++++++++----------------- src/manual/documentation.md | 16 ++++++----- src/manual/stacktraces.md | 8 +++--- 10 files changed, 98 insertions(+), 70 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index f768c81..bf3d561 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -746,6 +746,10 @@ Deprecated or removed * The unexported type `AbstractIOBuffer` has been renamed to `GenericIOBuffer` ([#17360](https://github.com/JuliaLang/julia/issues/17360) [#22796](https://github.com/JuliaLang/julia/issues/22796)). + * `IOBuffer(data::AbstractVector{UInt8}, read::Bool, write::Bool, maxsize::Integer)`, + `IOBuffer(read::Bool, write::Bool)`, and `IOBuffer(maxsize::Integer)` are + deprecated in favor of constructors taking keyword arguments ([#25872](https://github.com/JuliaLang/julia/issues/25872)). + * `Display` has been renamed to `AbstractDisplay` ([#24831](https://github.com/JuliaLang/julia/issues/24831)). * Remaining vectorized methods over `SparseVector`s, particularly `floor`, `ceil`, @@ -1020,6 +1024,9 @@ Deprecated or removed * `DateTime()`, `Date()`, and `Time()` have been deprecated, instead use `DateTime(1)`, `Date(1)` and `Time(0)` respectively ([#23724](https://github.com/JuliaLang/julia/issues/23724)). + * The fallback method `^(x, p::Integer)` is deprecated. If your type relied on this definition, + add a method such as `^(x::MyType, p::Integer) = Base.power_by_squaring(x, p)` ([#23332](https://github.com/JuliaLang/julia/issues/23332)). + Command-line option changes --------------------------- diff --git a/codex/devdocs/ast.md b/codex/devdocs/ast.md index 65639f5..d299e7c 100644 --- a/codex/devdocs/ast.md +++ b/codex/devdocs/ast.md @@ -35,7 +35,7 @@ The following data types exist in lowered form: * `LineNumberNode` - Contains a single number, specifying the line number the next statement came from. + Contains a number and a file name, specifying the line number the next statement came from. * `LabelNode` diff --git a/codex/manual/constructors.md b/codex/manual/constructors.md index 7aef476..153d6e3 100644 --- a/codex/manual/constructors.md +++ b/codex/manual/constructors.md @@ -406,8 +406,10 @@ defining sophisticated behavior is typically quite simple. ## Case Study: Rational Perhaps the best way to tie all these pieces together is to present a real world example of a -parametric composite type and its constructor methods. To that end, here is the (slightly modified) beginning of [`rational.jl`](https://github.com/JuliaLang/julia/blob/master/base/rational.jl), -which implements Julia's [Rational Numbers](@ref): +parametric composite type and its constructor methods. To that end, we implement our own rational number type +`OurRational`, similar to Julia's built-in [`Rational`](@ref) type, defined in +[`rational.jl`](https://github.com/JuliaLang/julia/blob/master/base/rational.jl): + ```jldoctest rational julia> struct OurRational{T<:Integer} <: Real @@ -433,27 +435,27 @@ OurRational julia> OurRational(n::Integer) = OurRational(n,one(n)) OurRational -julia> //(n::Integer, d::Integer) = OurRational(n,d) -// (generic function with 1 method) +julia> ⊘(n::Integer, d::Integer) = OurRational(n,d) +⊘ (generic function with 1 method) -julia> //(x::OurRational, y::Integer) = x.num // (x.den*y) -// (generic function with 2 methods) +julia> ⊘(x::OurRational, y::Integer) = x.num ⊘ (x.den*y) +⊘ (generic function with 2 methods) -julia> //(x::Integer, y::OurRational) = (x*y.den) // y.num -// (generic function with 3 methods) +julia> ⊘(x::Integer, y::OurRational) = (x*y.den) ⊘ y.num +⊘ (generic function with 3 methods) -julia> //(x::Complex, y::Real) = complex(real(x)//y, imag(x)//y) -// (generic function with 4 methods) +julia> ⊘(x::Complex, y::Real) = complex(real(x) ⊘ y, imag(x) ⊘ y) +⊘ (generic function with 4 methods) -julia> //(x::Real, y::Complex) = x*y'//real(y*y') -// (generic function with 5 methods) +julia> ⊘(x::Real, y::Complex) = (x*y') ⊘ real(y*y') +⊘ (generic function with 5 methods) -julia> function //(x::Complex, y::Complex) +julia> function ⊘(x::Complex, y::Complex) xy = x*y' yy = real(y*y') - complex(real(xy)//yy, imag(xy)//yy) + complex(real(xy) ⊘ yy, imag(xy) ⊘ yy) end -// (generic function with 6 methods) +⊘ (generic function with 6 methods) ``` The first line -- `struct OurRational{T<:Integer} <: Real` -- declares that `OurRational` takes one @@ -477,29 +479,30 @@ have different types: it promotes them to a common type and then delegates const outer constructor for arguments of matching type. The third outer constructor turns integer values into rationals by supplying a value of `1` as the denominator. -Following the outer constructor definitions, we have a number of methods for the [`//`](@ref) -operator, which provides a syntax for writing rationals. Before these definitions, [`//`](@ref) +Following the outer constructor definitions, we defined a number of methods for the `⊘` +operator, which provides a syntax for writing rationals (e.g. `1 ⊘ 2`). Julia's `Rational` +type uses the [`//`](@ref) operator for this purpose. Before these definitions, `⊘` is a completely undefined operator with only syntax and no meaning. Afterwards, it behaves just as described in [Rational Numbers](@ref) -- its entire behavior is defined in these few lines. -The first and most basic definition just makes `a//b` construct a `OurRational` by applying the -`OurRational` constructor to `a` and `b` when they are integers. When one of the operands of [`//`](@ref) +The first and most basic definition just makes `a ⊘ b` construct a `OurRational` by applying the +`OurRational` constructor to `a` and `b` when they are integers. When one of the operands of `⊘` is already a rational number, we construct a new rational for the resulting ratio slightly differently; this behavior is actually identical to division of a rational with an integer. Finally, applying -[`//`](@ref) to complex integral values creates an instance of `Complex{OurRational}` -- a complex +`⊘` to complex integral values creates an instance of `Complex{OurRational}` -- a complex number whose real and imaginary parts are rationals: ```jldoctest rational -julia> ans = (1 + 2im)//(1 - 2im); +julia> z = (1 + 2im) ⊘ (1 - 2im); -julia> typeof(ans) +julia> typeof(z) Complex{OurRational{Int64}} -julia> ans <: Complex{OurRational} +julia> typeof(z) <: Complex{OurRational} false ``` -Thus, although the [`//`](@ref) operator usually returns an instance of `OurRational`, if either +Thus, although the [`⊘`](@ref) operator usually returns an instance of `OurRational`, if either of its arguments are complex integers, it will return an instance of `Complex{OurRational}` instead. The interested reader should consider perusing the rest of [`rational.jl`](https://github.com/JuliaLang/julia/blob/master/base/rational.jl): it is short, self-contained, and implements an entire basic Julia type. diff --git a/codex/manual/documentation.md b/codex/manual/documentation.md index 8cf5dd5..ae4e503 100644 --- a/codex/manual/documentation.md +++ b/codex/manual/documentation.md @@ -881,9 +881,8 @@ cannot span multiple rows or columns of the table. #### Admonitions -Specially formatted blocks with titles such as "Notes", "Warning", or "Tips" are known as admonitions -and are used when some part of a document needs special attention. They can be defined using the -following `!!!` syntax: +Specially formatted blocks, known as admonitions, can be used to highlight particular remarks. +They can be defined using the following `!!!` syntax: ``` !!! note @@ -897,9 +896,14 @@ following `!!!` syntax: This warning admonition has a custom title: `"Beware!"`. ``` -Admonitions, like most other toplevel elements, can contain other toplevel elements. When no title -text, specified after the admonition type in double quotes, is included then the title used will -be the type of the block, i.e. `"Note"` in the case of the `note` admonition. +The type of the admonition can be any word, but some types produce special styling, +namely (in order of decreasing severity): `danger`, `warning`, `info`/`note`, and `tip`. + +A custom title for the box can be provided as a string (in double quotes) after the admonition type. +If no title text is specified after the admonition type, then the title used will be the type of the block, +i.e. `"Note"` in the case of the `note` admonition. + +Admonitions, like most other toplevel elements, can contain other toplevel elements. ## Markdown Syntax Extensions diff --git a/codex/manual/stacktraces.md b/codex/manual/stacktraces.md index 56d21d9..2cc3d3a 100644 --- a/codex/manual/stacktraces.md +++ b/codex/manual/stacktraces.md @@ -16,8 +16,8 @@ julia> stacktrace() (::Base.REPL.##1#2{Base.REPL.REPLBackend})() at event.jl:73 ``` -Calling [`stacktrace()`](@ref) returns a vector of [`StackFrame`](@ref) s. For ease of use, the -alias [`StackTrace`](@ref) can be used in place of `Vector{StackFrame}`. (Examples with `[...]` +Calling [`stacktrace()`](@ref) returns a vector of [`StackTraces.StackFrame`](@ref) s. For ease of use, the +alias [`StackTraces.StackTrace`](@ref) can be used in place of `Vector{StackFrame}`. (Examples with `[...]` indicate that output may vary depending on how the code is run.) ```julia-repl @@ -66,7 +66,7 @@ julia> example() ## Extracting useful information -Each [`StackFrame`](@ref) contains the function name, file name, line number, lambda info, a flag +Each [`StackTraces.StackFrame`](@ref) contains the function name, file name, line number, lambda info, a flag indicating whether the frame has been inlined, a flag indicating whether it is a C function (by default C functions do not appear in the stack trace), and an integer representation of the pointer returned by [`backtrace`](@ref): @@ -257,7 +257,7 @@ julia> stacktrace(trace, true) ip:0xffffffffffffffff ``` -Individual pointers returned by [`backtrace`](@ref) can be translated into [`StackFrame`](@ref) +Individual pointers returned by [`backtrace`](@ref) can be translated into [`StackTraces.StackFrame`](@ref) s by passing them into [`StackTraces.lookup`](@ref): ```julia-repl diff --git a/src/NEWS.md b/src/NEWS.md index 53596fd..ed421da 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -734,6 +734,10 @@ Deprecated or removed * The unexported type `AbstractIOBuffer` has been renamed to `GenericIOBuffer` ([#17360](https://github.com/JuliaLang/julia/issues/17360) [#22796](https://github.com/JuliaLang/julia/issues/22796)). + * `IOBuffer(data::AbstractVector{UInt8}, read::Bool, write::Bool, maxsize::Integer)`, + `IOBuffer(read::Bool, write::Bool)`, and `IOBuffer(maxsize::Integer)` are + deprecated in favor of constructors taking keyword arguments ([#25872](https://github.com/JuliaLang/julia/issues/25872)). + * `Display` has been renamed to `AbstractDisplay` ([#24831](https://github.com/JuliaLang/julia/issues/24831)). * Remaining vectorized methods over `SparseVector`s, particularly `floor`, `ceil`, @@ -1008,6 +1012,9 @@ Deprecated or removed * `DateTime()`, `Date()`, and `Time()` have been deprecated, instead use `DateTime(1)`, `Date(1)` and `Time(0)` respectively ([#23724](https://github.com/JuliaLang/julia/issues/23724)). + * The fallback method `^(x, p::Integer)` is deprecated. If your type relied on this definition, + add a method such as `^(x::MyType, p::Integer) = Base.power_by_squaring(x, p)` ([#23332](https://github.com/JuliaLang/julia/issues/23332)). + Command-line option changes --------------------------- diff --git a/src/devdocs/ast.md b/src/devdocs/ast.md index 65639f5..d299e7c 100644 --- a/src/devdocs/ast.md +++ b/src/devdocs/ast.md @@ -35,7 +35,7 @@ The following data types exist in lowered form: * `LineNumberNode` - Contains a single number, specifying the line number the next statement came from. + Contains a number and a file name, specifying the line number the next statement came from. * `LabelNode` diff --git a/src/manual/constructors.md b/src/manual/constructors.md index 7aef476..153d6e3 100644 --- a/src/manual/constructors.md +++ b/src/manual/constructors.md @@ -406,8 +406,10 @@ defining sophisticated behavior is typically quite simple. ## Case Study: Rational Perhaps the best way to tie all these pieces together is to present a real world example of a -parametric composite type and its constructor methods. To that end, here is the (slightly modified) beginning of [`rational.jl`](https://github.com/JuliaLang/julia/blob/master/base/rational.jl), -which implements Julia's [Rational Numbers](@ref): +parametric composite type and its constructor methods. To that end, we implement our own rational number type +`OurRational`, similar to Julia's built-in [`Rational`](@ref) type, defined in +[`rational.jl`](https://github.com/JuliaLang/julia/blob/master/base/rational.jl): + ```jldoctest rational julia> struct OurRational{T<:Integer} <: Real @@ -433,27 +435,27 @@ OurRational julia> OurRational(n::Integer) = OurRational(n,one(n)) OurRational -julia> //(n::Integer, d::Integer) = OurRational(n,d) -// (generic function with 1 method) +julia> ⊘(n::Integer, d::Integer) = OurRational(n,d) +⊘ (generic function with 1 method) -julia> //(x::OurRational, y::Integer) = x.num // (x.den*y) -// (generic function with 2 methods) +julia> ⊘(x::OurRational, y::Integer) = x.num ⊘ (x.den*y) +⊘ (generic function with 2 methods) -julia> //(x::Integer, y::OurRational) = (x*y.den) // y.num -// (generic function with 3 methods) +julia> ⊘(x::Integer, y::OurRational) = (x*y.den) ⊘ y.num +⊘ (generic function with 3 methods) -julia> //(x::Complex, y::Real) = complex(real(x)//y, imag(x)//y) -// (generic function with 4 methods) +julia> ⊘(x::Complex, y::Real) = complex(real(x) ⊘ y, imag(x) ⊘ y) +⊘ (generic function with 4 methods) -julia> //(x::Real, y::Complex) = x*y'//real(y*y') -// (generic function with 5 methods) +julia> ⊘(x::Real, y::Complex) = (x*y') ⊘ real(y*y') +⊘ (generic function with 5 methods) -julia> function //(x::Complex, y::Complex) +julia> function ⊘(x::Complex, y::Complex) xy = x*y' yy = real(y*y') - complex(real(xy)//yy, imag(xy)//yy) + complex(real(xy) ⊘ yy, imag(xy) ⊘ yy) end -// (generic function with 6 methods) +⊘ (generic function with 6 methods) ``` The first line -- `struct OurRational{T<:Integer} <: Real` -- declares that `OurRational` takes one @@ -477,29 +479,30 @@ have different types: it promotes them to a common type and then delegates const outer constructor for arguments of matching type. The third outer constructor turns integer values into rationals by supplying a value of `1` as the denominator. -Following the outer constructor definitions, we have a number of methods for the [`//`](@ref) -operator, which provides a syntax for writing rationals. Before these definitions, [`//`](@ref) +Following the outer constructor definitions, we defined a number of methods for the `⊘` +operator, which provides a syntax for writing rationals (e.g. `1 ⊘ 2`). Julia's `Rational` +type uses the [`//`](@ref) operator for this purpose. Before these definitions, `⊘` is a completely undefined operator with only syntax and no meaning. Afterwards, it behaves just as described in [Rational Numbers](@ref) -- its entire behavior is defined in these few lines. -The first and most basic definition just makes `a//b` construct a `OurRational` by applying the -`OurRational` constructor to `a` and `b` when they are integers. When one of the operands of [`//`](@ref) +The first and most basic definition just makes `a ⊘ b` construct a `OurRational` by applying the +`OurRational` constructor to `a` and `b` when they are integers. When one of the operands of `⊘` is already a rational number, we construct a new rational for the resulting ratio slightly differently; this behavior is actually identical to division of a rational with an integer. Finally, applying -[`//`](@ref) to complex integral values creates an instance of `Complex{OurRational}` -- a complex +`⊘` to complex integral values creates an instance of `Complex{OurRational}` -- a complex number whose real and imaginary parts are rationals: ```jldoctest rational -julia> ans = (1 + 2im)//(1 - 2im); +julia> z = (1 + 2im) ⊘ (1 - 2im); -julia> typeof(ans) +julia> typeof(z) Complex{OurRational{Int64}} -julia> ans <: Complex{OurRational} +julia> typeof(z) <: Complex{OurRational} false ``` -Thus, although the [`//`](@ref) operator usually returns an instance of `OurRational`, if either +Thus, although the [`⊘`](@ref) operator usually returns an instance of `OurRational`, if either of its arguments are complex integers, it will return an instance of `Complex{OurRational}` instead. The interested reader should consider perusing the rest of [`rational.jl`](https://github.com/JuliaLang/julia/blob/master/base/rational.jl): it is short, self-contained, and implements an entire basic Julia type. diff --git a/src/manual/documentation.md b/src/manual/documentation.md index 8cf5dd5..ae4e503 100644 --- a/src/manual/documentation.md +++ b/src/manual/documentation.md @@ -881,9 +881,8 @@ cannot span multiple rows or columns of the table. #### Admonitions -Specially formatted blocks with titles such as "Notes", "Warning", or "Tips" are known as admonitions -and are used when some part of a document needs special attention. They can be defined using the -following `!!!` syntax: +Specially formatted blocks, known as admonitions, can be used to highlight particular remarks. +They can be defined using the following `!!!` syntax: ``` !!! note @@ -897,9 +896,14 @@ following `!!!` syntax: This warning admonition has a custom title: `"Beware!"`. ``` -Admonitions, like most other toplevel elements, can contain other toplevel elements. When no title -text, specified after the admonition type in double quotes, is included then the title used will -be the type of the block, i.e. `"Note"` in the case of the `note` admonition. +The type of the admonition can be any word, but some types produce special styling, +namely (in order of decreasing severity): `danger`, `warning`, `info`/`note`, and `tip`. + +A custom title for the box can be provided as a string (in double quotes) after the admonition type. +If no title text is specified after the admonition type, then the title used will be the type of the block, +i.e. `"Note"` in the case of the `note` admonition. + +Admonitions, like most other toplevel elements, can contain other toplevel elements. ## Markdown Syntax Extensions diff --git a/src/manual/stacktraces.md b/src/manual/stacktraces.md index 56d21d9..2cc3d3a 100644 --- a/src/manual/stacktraces.md +++ b/src/manual/stacktraces.md @@ -16,8 +16,8 @@ julia> stacktrace() (::Base.REPL.##1#2{Base.REPL.REPLBackend})() at event.jl:73 ``` -Calling [`stacktrace()`](@ref) returns a vector of [`StackFrame`](@ref) s. For ease of use, the -alias [`StackTrace`](@ref) can be used in place of `Vector{StackFrame}`. (Examples with `[...]` +Calling [`stacktrace()`](@ref) returns a vector of [`StackTraces.StackFrame`](@ref) s. For ease of use, the +alias [`StackTraces.StackTrace`](@ref) can be used in place of `Vector{StackFrame}`. (Examples with `[...]` indicate that output may vary depending on how the code is run.) ```julia-repl @@ -66,7 +66,7 @@ julia> example() ## Extracting useful information -Each [`StackFrame`](@ref) contains the function name, file name, line number, lambda info, a flag +Each [`StackTraces.StackFrame`](@ref) contains the function name, file name, line number, lambda info, a flag indicating whether the frame has been inlined, a flag indicating whether it is a C function (by default C functions do not appear in the stack trace), and an integer representation of the pointer returned by [`backtrace`](@ref): @@ -257,7 +257,7 @@ julia> stacktrace(trace, true) ip:0xffffffffffffffff ``` -Individual pointers returned by [`backtrace`](@ref) can be translated into [`StackFrame`](@ref) +Individual pointers returned by [`backtrace`](@ref) can be translated into [`StackTraces.StackFrame`](@ref) s by passing them into [`StackTraces.lookup`](@ref): ```julia-repl From 8562a19ff86f0fed191409e21b23863c45eee64f Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Wed, 14 Feb 2018 22:53:40 +0900 Subject: [PATCH 005/153] update Julia Commit 755f6a57c7 --- codex/NEWS.md | 14 ++++ codex/index.md | 1 + codex/manual/documentation.md | 38 ++++----- codex/stdlib/REPL.md | 149 +++++++++++++++++++++++++++++++++- codex/stdlib/SHA.md | 47 +++++++++++ src/NEWS.md | 14 ++++ src/index.md | 1 + src/manual/documentation.md | 38 ++++----- src/stdlib/REPL.md | 149 +++++++++++++++++++++++++++++++++- src/stdlib/SHA.md | 47 +++++++++++ 10 files changed, 458 insertions(+), 40 deletions(-) create mode 100644 codex/stdlib/SHA.md create mode 100644 src/stdlib/SHA.md diff --git a/codex/NEWS.md b/codex/NEWS.md index bf3d561..f996a6c 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -269,6 +269,9 @@ This section lists changes that do not have deprecation warnings. `Tridiagonal{T,V<:AbstractVector{T}}` and `SymTridiagonal{T,V<:AbstractVector{T}}` respectively ([#22718](https://github.com/JuliaLang/julia/issues/22718), [#22925](https://github.com/JuliaLang/julia/issues/22925), [#23035](https://github.com/JuliaLang/julia/issues/23035), [#23154](https://github.com/JuliaLang/julia/issues/23154)). + * The immediate supertype of `BitArray` is now simply `AbstractArray`. `BitArray` is no longer + considered a subtype of `DenseArray` and `StridedArray` ([#25858](https://github.com/JuliaLang/julia/issues/25858)). + * When called with an argument that contains `NaN` elements, `findmin` and `findmax` now return the first `NaN` found and its corresponding index. Previously, `NaN` elements were ignored. The new behavior matches that of `min`, `max`, `minimum`, and `maximum`. @@ -420,6 +423,9 @@ This section lists changes that do not have deprecation warnings. * The `tempname` function used to create a file on Windows but not on other platforms. It now never creates a file ([#9053](https://github.com/JuliaLang/julia/issues/9053)). + * The `fieldnames` and `propertynames` functions now return a tuple rather than + an array ([#25725](https://github.com/JuliaLang/julia/issues/25725)). + Library improvements -------------------- @@ -433,6 +439,9 @@ Library improvements * Jump to first/last history entries in the REPL via "Alt-<" and "Alt->" ([#22829](https://github.com/JuliaLang/julia/issues/22829)). + * REPL LaTeX-like tab completions have been simplified for several Unicode characters, + e.g. `𝔸` is now `\bbA` rather than `\BbbA` ([#25980](https://github.com/JuliaLang/julia/issues/25980)). + * The function `chop` now accepts two arguments `head` and `tail` allowing to specify number of characters to remove from the head and tail of the string ([#24126](https://github.com/JuliaLang/julia/issues/24126)). @@ -581,6 +590,9 @@ Library improvements like other `AbstractDict` subtypes and its constructors mirror the ones of `Dict`. ([#25210](https://github.com/JuliaLang/julia/issues/25210)) + * `IOBuffer` can take the `sizehint` keyword argument to suggest a capacity of + the buffer ([#25944](https://github.com/JuliaLang/julia/issues/25944)). + Compiler/Runtime improvements ----------------------------- @@ -1027,6 +1039,8 @@ Deprecated or removed * The fallback method `^(x, p::Integer)` is deprecated. If your type relied on this definition, add a method such as `^(x::MyType, p::Integer) = Base.power_by_squaring(x, p)` ([#23332](https://github.com/JuliaLang/julia/issues/23332)). + * `wait` and `fetch` on `Task` now resemble the interface of `Future` + Command-line option changes --------------------------- diff --git a/codex/index.md b/codex/index.md index 7998f37..7faecc1 100644 --- a/codex/index.md +++ b/codex/index.md @@ -79,6 +79,7 @@ Please read the [release notes](NEWS.md) to see what has changed since the last * [The Julia REPL](@ref) * [Base64](@ref) * [CRC32c](@ref) + * [SHA](@ref) * [Dates and Time](@ref stdlib-dates) * [Delimited Files](@ref) * [Distributed Computing](@ref) diff --git a/codex/manual/documentation.md b/codex/manual/documentation.md index ae4e503..dbc068c 100644 --- a/codex/manual/documentation.md +++ b/codex/manual/documentation.md @@ -3,9 +3,10 @@ Julia enables package developers and users to document functions, types and other objects easily via a built-in documentation system since Julia 0.4. -The basic syntax is very simple: any string appearing at the top-level right before an object +The basic syntax is simple: any string appearing at the top-level right before an object (function, macro, type or instance) will be interpreted as documenting it (these are called *docstrings*). -Here is a very simple example: +Note that no blank lines or comments may intervene between a docstring and the documented object. +Here is a basic example: ```julia "Tell whether there are too foo items in the array." @@ -248,6 +249,20 @@ The `@doc` macro associates its first argument with its second in a per-module d macro simply creates an object representing the Markdown content. In the future it is likely to do more advanced things such as allowing for relative image or link paths. +To make it easier to write documentation, the parser treats the macro name `@doc` specially: +if a call to `@doc` has one argument, but another expression appears after a single line +break, then that additional expression is added as an argument to the macro. +Therefore the following syntax is parsed as a 2-argument call to `@doc`: + +```julia +@doc raw""" +... +""" +f(x) = x +``` + +This makes it easy to use an arbitrary object (here a `raw` string) as a docstring. + When used for retrieving documentation, the `@doc` macro (or equally, the `doc` function) will search all `META` dictionaries for metadata relevant to the given object and return it. The returned object (some Markdown content, for example) will by default display itself intelligently. This @@ -308,24 +323,9 @@ y = MyType("y") A comprehensive overview of all documentable Julia syntax. -In the following examples `"..."` is used to illustrate an arbitrary docstring which may be one -of the follow four variants and contain arbitrary text: - -```julia -"..." - -doc"..." - -""" -... -""" - -doc""" -... -""" -``` +In the following examples `"..."` is used to illustrate an arbitrary docstring. -`@doc_str` should only be used when the docstring contains `$` or `\` characters that should not +`doc""` should only be used when the docstring contains `$` or `\` characters that should not be parsed by Julia such as LaTeX syntax or Julia source code examples containing interpolation. ### Functions and Methods diff --git a/codex/stdlib/REPL.md b/codex/stdlib/REPL.md index 158b077..ff828c3 100644 --- a/codex/stdlib/REPL.md +++ b/codex/stdlib/REPL.md @@ -366,7 +366,154 @@ ENV["JULIA_WARN_COLOR"] = :yellow ENV["JULIA_INFO_COLOR"] = :cyan ``` -## References +# TerminalMenus + +TerminalMenus is a submodule of the Julia REPL and enables small, low-profile interactive menus in the terminal. + +## Examples + +```julia +import REPL +using REPL.TerminalMenus + +options = ["apple", "orange", "grape", "strawberry", + "blueberry", "peach", "lemon", "lime"] + +``` + +### RadioMenu + +The RadioMenu allows the user to select one option from the list. The `request` +function displays the interactive menu and returns the index of the selected +choice. If a user presses 'q' or `ctrl-c`, `request` will return a `-1`. + + +```julia +# `pagesize` is the number of items to be displayed at a time. +# The UI will scroll if the number of options is greater +# than the `pagesize` +menu = RadioMenu(options, pagesize=4) + +# `request` displays the menu and returns the index after the +# user has selected a choice +choice = request("Choose your favorite fruit:", menu) + +if choice != -1 + println("Your favorite fruit is ", options[choice], "!") +else + println("Menu canceled.") +end + +``` + +Output: + +``` +Choose your favorite fruit: +^ grape + strawberry + > blueberry +v peach +Your favorite fruit is blueberry! +``` + +### MultiSelectMenu + +The MultiSelectMenu allows users to select many choices from a list. + +```julia +# here we use the default `pagesize` 10 +menu = MultiSelectMenu(options) + +# `request` returns a `Set` of selected indices +# if the menu us canceled (ctrl-c or q), return an empty set +choices = request("Select the fruits you like:", menu) + +if length(choices) > 0 + println("You like the following fruits:") + for i in choices + println(" - ", options[i]) + end +else + println("Menu canceled.") +end +``` + +Output: + +``` +Select the fruits you like: +[press: d=done, a=all, n=none] + [ ] apple + > [X] orange + [X] grape + [ ] strawberry + [ ] blueberry + [X] peach + [ ] lemon + [ ] lime +You like the following fruits: + - orange + - grape + - peach +``` + +## Customization / Configuation + +All interface customization is done through the keyword only +`TerminalMenus.config()` function. + +### Arguments + + - `charset::Symbol=:na`: ui characters to use (`:ascii` or `:unicode`); overridden by other arguments + - `cursor::Char='>'|'→'`: character to use for cursor + - `up_arrow::Char='^'|'↑'`: character to use for up arrow + - `down_arrow::Char='v'|'↓'`: character to use for down arrow + - `checked::String="[X]"|"✓"`: string to use for checked + - `unchecked::String="[ ]"|"⬚")`: string to use for unchecked + - `scroll::Symbol=:na`: If `:wrap` then wrap the cursor around top and bottom, if :`nowrap` do not wrap cursor + - `supress_output::Bool=false`: For testing. If true, menu will not be printed to console. + - `ctrl_c_interrupt::Bool=true`: If `false`, return empty on ^C, if `true` throw InterruptException() on ^C + +### Examples + +```julia +julia> menu = MultiSelectMenu(options, pagesize=5); + +julia> request(menu) # ASCII is used by default +[press: d=done, a=all, n=none] + [ ] apple + [X] orange + [ ] grape + > [X] strawberry +v [ ] blueberry +Set([4, 2]) + +julia> TerminalMenus.config(charset=:unicode) + +julia> request(menu) +[press: d=done, a=all, n=none] + ⬚ apple + ✓ orange + ⬚ grape + → ✓ strawberry +↓ ⬚ blueberry +Set([4, 2]) + +julia> TerminalMenus.config(checked="YEP!", unchecked="NOPE", cursor='⧐') + +julia> request(menu) +[press: d=done, a=all, n=none] + NOPE apple + YEP! orange + NOPE grape + ⧐ YEP! strawberry +↓ NOPE blueberry +Set([4, 2]) + +``` + +# References ```@docs Base.atreplinit diff --git a/codex/stdlib/SHA.md b/codex/stdlib/SHA.md new file mode 100644 index 0000000..a12a423 --- /dev/null +++ b/codex/stdlib/SHA.md @@ -0,0 +1,47 @@ +# SHA + + +Usage is very straightforward: +```julia +julia> using SHA + +julia> bytes2hex(sha256("test")) +"9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08" +``` + +Each exported function (at the time of this writing, SHA-1, SHA-2 224, 256, 384 and 512, and SHA-3 224, 256, 384 and 512 functions are implemented) takes in either an `Array{UInt8}`, a `ByteString` or an `IO` object. This makes it trivial to checksum a file: + +```julia +shell> cat /tmp/test.txt +test +julia> using SHA + +julia> open("/tmp/test.txt") do f + sha2_256(f) + end +32-element Array{UInt8,1}: + 0x9f + 0x86 + 0xd0 + 0x81 + 0x88 + 0x4c + 0x7d + 0x65 + ⋮ + 0x5d + 0x6c + 0x15 + 0xb0 + 0xf0 + 0x0a + 0x08 +``` + +Note the lack of a newline at the end of `/tmp/text.txt`. Julia automatically inserts a newline before the `julia>` prompt. + +Due to the colloquial usage of `sha256` to refer to `sha2_256`, convenience functions are provided, mapping `shaxxx()` function calls to `sha2_xxx()`. For SHA-3, no such colloquialisms exist and the user must use the full `sha3_xxx()` names. + +`shaxxx()` takes `AbstractString` and array-like objects (`NTuple` and `Array`) with elements of type `UInt8`. + +Note that, at the time of this writing, the SHA3 code is not optimized, and as such is roughly an order of magnitude slower than SHA2. diff --git a/src/NEWS.md b/src/NEWS.md index ed421da..4c1798a 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -257,6 +257,9 @@ This section lists changes that do not have deprecation warnings. `Tridiagonal{T,V<:AbstractVector{T}}` and `SymTridiagonal{T,V<:AbstractVector{T}}` respectively ([#22718](https://github.com/JuliaLang/julia/issues/22718), [#22925](https://github.com/JuliaLang/julia/issues/22925), [#23035](https://github.com/JuliaLang/julia/issues/23035), [#23154](https://github.com/JuliaLang/julia/issues/23154)). + * The immediate supertype of `BitArray` is now simply `AbstractArray`. `BitArray` is no longer + considered a subtype of `DenseArray` and `StridedArray` ([#25858](https://github.com/JuliaLang/julia/issues/25858)). + * When called with an argument that contains `NaN` elements, `findmin` and `findmax` now return the first `NaN` found and its corresponding index. Previously, `NaN` elements were ignored. The new behavior matches that of `min`, `max`, `minimum`, and `maximum`. @@ -408,6 +411,9 @@ This section lists changes that do not have deprecation warnings. * The `tempname` function used to create a file on Windows but not on other platforms. It now never creates a file ([#9053](https://github.com/JuliaLang/julia/issues/9053)). + * The `fieldnames` and `propertynames` functions now return a tuple rather than + an array ([#25725](https://github.com/JuliaLang/julia/issues/25725)). + Library improvements -------------------- @@ -421,6 +427,9 @@ Library improvements * Jump to first/last history entries in the REPL via "Alt-<" and "Alt->" ([#22829](https://github.com/JuliaLang/julia/issues/22829)). + * REPL LaTeX-like tab completions have been simplified for several Unicode characters, + e.g. `𝔸` is now `\bbA` rather than `\BbbA` ([#25980](https://github.com/JuliaLang/julia/issues/25980)). + * The function `chop` now accepts two arguments `head` and `tail` allowing to specify number of characters to remove from the head and tail of the string ([#24126](https://github.com/JuliaLang/julia/issues/24126)). @@ -569,6 +578,9 @@ Library improvements like other `AbstractDict` subtypes and its constructors mirror the ones of `Dict`. ([#25210](https://github.com/JuliaLang/julia/issues/25210)) + * `IOBuffer` can take the `sizehint` keyword argument to suggest a capacity of + the buffer ([#25944](https://github.com/JuliaLang/julia/issues/25944)). + Compiler/Runtime improvements ----------------------------- @@ -1015,6 +1027,8 @@ Deprecated or removed * The fallback method `^(x, p::Integer)` is deprecated. If your type relied on this definition, add a method such as `^(x::MyType, p::Integer) = Base.power_by_squaring(x, p)` ([#23332](https://github.com/JuliaLang/julia/issues/23332)). + * `wait` and `fetch` on `Task` now resemble the interface of `Future` + Command-line option changes --------------------------- diff --git a/src/index.md b/src/index.md index c2fd3df..a4a79aa 100644 --- a/src/index.md +++ b/src/index.md @@ -81,6 +81,7 @@ * [The Julia REPL](@ref) * [Base64](@ref) * [CRC32c](@ref) + * [SHA](@ref) * [Dates and Time](@ref stdlib-dates) * [Delimited Files](@ref) * [Distributed Computing](@ref) diff --git a/src/manual/documentation.md b/src/manual/documentation.md index ae4e503..dbc068c 100644 --- a/src/manual/documentation.md +++ b/src/manual/documentation.md @@ -3,9 +3,10 @@ Julia enables package developers and users to document functions, types and other objects easily via a built-in documentation system since Julia 0.4. -The basic syntax is very simple: any string appearing at the top-level right before an object +The basic syntax is simple: any string appearing at the top-level right before an object (function, macro, type or instance) will be interpreted as documenting it (these are called *docstrings*). -Here is a very simple example: +Note that no blank lines or comments may intervene between a docstring and the documented object. +Here is a basic example: ```julia "Tell whether there are too foo items in the array." @@ -248,6 +249,20 @@ The `@doc` macro associates its first argument with its second in a per-module d macro simply creates an object representing the Markdown content. In the future it is likely to do more advanced things such as allowing for relative image or link paths. +To make it easier to write documentation, the parser treats the macro name `@doc` specially: +if a call to `@doc` has one argument, but another expression appears after a single line +break, then that additional expression is added as an argument to the macro. +Therefore the following syntax is parsed as a 2-argument call to `@doc`: + +```julia +@doc raw""" +... +""" +f(x) = x +``` + +This makes it easy to use an arbitrary object (here a `raw` string) as a docstring. + When used for retrieving documentation, the `@doc` macro (or equally, the `doc` function) will search all `META` dictionaries for metadata relevant to the given object and return it. The returned object (some Markdown content, for example) will by default display itself intelligently. This @@ -308,24 +323,9 @@ y = MyType("y") A comprehensive overview of all documentable Julia syntax. -In the following examples `"..."` is used to illustrate an arbitrary docstring which may be one -of the follow four variants and contain arbitrary text: - -```julia -"..." - -doc"..." - -""" -... -""" - -doc""" -... -""" -``` +In the following examples `"..."` is used to illustrate an arbitrary docstring. -`@doc_str` should only be used when the docstring contains `$` or `\` characters that should not +`doc""` should only be used when the docstring contains `$` or `\` characters that should not be parsed by Julia such as LaTeX syntax or Julia source code examples containing interpolation. ### Functions and Methods diff --git a/src/stdlib/REPL.md b/src/stdlib/REPL.md index 158b077..ff828c3 100644 --- a/src/stdlib/REPL.md +++ b/src/stdlib/REPL.md @@ -366,7 +366,154 @@ ENV["JULIA_WARN_COLOR"] = :yellow ENV["JULIA_INFO_COLOR"] = :cyan ``` -## References +# TerminalMenus + +TerminalMenus is a submodule of the Julia REPL and enables small, low-profile interactive menus in the terminal. + +## Examples + +```julia +import REPL +using REPL.TerminalMenus + +options = ["apple", "orange", "grape", "strawberry", + "blueberry", "peach", "lemon", "lime"] + +``` + +### RadioMenu + +The RadioMenu allows the user to select one option from the list. The `request` +function displays the interactive menu and returns the index of the selected +choice. If a user presses 'q' or `ctrl-c`, `request` will return a `-1`. + + +```julia +# `pagesize` is the number of items to be displayed at a time. +# The UI will scroll if the number of options is greater +# than the `pagesize` +menu = RadioMenu(options, pagesize=4) + +# `request` displays the menu and returns the index after the +# user has selected a choice +choice = request("Choose your favorite fruit:", menu) + +if choice != -1 + println("Your favorite fruit is ", options[choice], "!") +else + println("Menu canceled.") +end + +``` + +Output: + +``` +Choose your favorite fruit: +^ grape + strawberry + > blueberry +v peach +Your favorite fruit is blueberry! +``` + +### MultiSelectMenu + +The MultiSelectMenu allows users to select many choices from a list. + +```julia +# here we use the default `pagesize` 10 +menu = MultiSelectMenu(options) + +# `request` returns a `Set` of selected indices +# if the menu us canceled (ctrl-c or q), return an empty set +choices = request("Select the fruits you like:", menu) + +if length(choices) > 0 + println("You like the following fruits:") + for i in choices + println(" - ", options[i]) + end +else + println("Menu canceled.") +end +``` + +Output: + +``` +Select the fruits you like: +[press: d=done, a=all, n=none] + [ ] apple + > [X] orange + [X] grape + [ ] strawberry + [ ] blueberry + [X] peach + [ ] lemon + [ ] lime +You like the following fruits: + - orange + - grape + - peach +``` + +## Customization / Configuation + +All interface customization is done through the keyword only +`TerminalMenus.config()` function. + +### Arguments + + - `charset::Symbol=:na`: ui characters to use (`:ascii` or `:unicode`); overridden by other arguments + - `cursor::Char='>'|'→'`: character to use for cursor + - `up_arrow::Char='^'|'↑'`: character to use for up arrow + - `down_arrow::Char='v'|'↓'`: character to use for down arrow + - `checked::String="[X]"|"✓"`: string to use for checked + - `unchecked::String="[ ]"|"⬚")`: string to use for unchecked + - `scroll::Symbol=:na`: If `:wrap` then wrap the cursor around top and bottom, if :`nowrap` do not wrap cursor + - `supress_output::Bool=false`: For testing. If true, menu will not be printed to console. + - `ctrl_c_interrupt::Bool=true`: If `false`, return empty on ^C, if `true` throw InterruptException() on ^C + +### Examples + +```julia +julia> menu = MultiSelectMenu(options, pagesize=5); + +julia> request(menu) # ASCII is used by default +[press: d=done, a=all, n=none] + [ ] apple + [X] orange + [ ] grape + > [X] strawberry +v [ ] blueberry +Set([4, 2]) + +julia> TerminalMenus.config(charset=:unicode) + +julia> request(menu) +[press: d=done, a=all, n=none] + ⬚ apple + ✓ orange + ⬚ grape + → ✓ strawberry +↓ ⬚ blueberry +Set([4, 2]) + +julia> TerminalMenus.config(checked="YEP!", unchecked="NOPE", cursor='⧐') + +julia> request(menu) +[press: d=done, a=all, n=none] + NOPE apple + YEP! orange + NOPE grape + ⧐ YEP! strawberry +↓ NOPE blueberry +Set([4, 2]) + +``` + +# References ```@docs Base.atreplinit diff --git a/src/stdlib/SHA.md b/src/stdlib/SHA.md new file mode 100644 index 0000000..a12a423 --- /dev/null +++ b/src/stdlib/SHA.md @@ -0,0 +1,47 @@ +# SHA + + +Usage is very straightforward: +```julia +julia> using SHA + +julia> bytes2hex(sha256("test")) +"9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08" +``` + +Each exported function (at the time of this writing, SHA-1, SHA-2 224, 256, 384 and 512, and SHA-3 224, 256, 384 and 512 functions are implemented) takes in either an `Array{UInt8}`, a `ByteString` or an `IO` object. This makes it trivial to checksum a file: + +```julia +shell> cat /tmp/test.txt +test +julia> using SHA + +julia> open("/tmp/test.txt") do f + sha2_256(f) + end +32-element Array{UInt8,1}: + 0x9f + 0x86 + 0xd0 + 0x81 + 0x88 + 0x4c + 0x7d + 0x65 + ⋮ + 0x5d + 0x6c + 0x15 + 0xb0 + 0xf0 + 0x0a + 0x08 +``` + +Note the lack of a newline at the end of `/tmp/text.txt`. Julia automatically inserts a newline before the `julia>` prompt. + +Due to the colloquial usage of `sha256` to refer to `sha2_256`, convenience functions are provided, mapping `shaxxx()` function calls to `sha2_xxx()`. For SHA-3, no such colloquialisms exist and the user must use the full `sha3_xxx()` names. + +`shaxxx()` takes `AbstractString` and array-like objects (`NTuple` and `Array`) with elements of type `UInt8`. + +Note that, at the time of this writing, the SHA3 code is not optimized, and as such is roughly an order of magnitude slower than SHA2. From 935363b759e2a8e7d47076068fe50edd56e323c4 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Sun, 18 Feb 2018 09:49:54 +0900 Subject: [PATCH 006/153] update Julia Commit 15a345bf74 --- codex/NEWS.md | 37 ++++++++++++++++-- codex/base/arrays.md | 6 +-- codex/base/io-network.md | 8 ++-- codex/base/math.md | 2 +- codex/base/punctuation.md | 6 +-- codex/base/strings.md | 2 +- codex/manual/arrays.md | 4 +- codex/manual/functions.md | 1 - .../integers-and-floating-point-numbers.md | 2 +- codex/manual/noteworthy-differences.md | 2 +- codex/manual/parallel-computing.md | 2 +- codex/manual/performance-tips.md | 2 +- codex/stdlib/Base64.md | 1 + codex/stdlib/REPL.md | 4 +- codex/stdlib/base64.md | 1 + src/NEWS.md | 37 ++++++++++++++++-- src/base/arrays.md | 6 +-- src/base/io-network.md | 8 ++-- src/base/math.md | 2 +- src/base/punctuation.md | 6 +-- src/base/strings.md | 2 +- src/manual/arrays.md | 38 +++++++++---------- src/manual/functions.md | 1 - src/manual/noteworthy-differences.md | 2 +- src/manual/parallel-computing.md | 2 +- src/manual/performance-tips.md | 2 +- src/stdlib/Base64.md | 1 + src/stdlib/REPL.md | 4 +- src/stdlib/base64.md | 1 + 29 files changed, 124 insertions(+), 68 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index f996a6c..e707c30 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -82,6 +82,9 @@ Language changes * The parsing of `<|` is now right associative. `|>` remains left associative ([#24153](https://github.com/JuliaLang/julia/issues/24153)). + * `:` now parses like other operators, as a call to a function named `:`, instead of + calling `colon` ([#25947](https://github.com/JuliaLang/julia/issues/25947)). + * `{ }` expressions now use `braces` and `bracescat` as expression heads instead of `cell1d` and `cell2d`, and parse similarly to `vect` and `vcat` ([#8470](https://github.com/JuliaLang/julia/issues/8470)). @@ -180,6 +183,10 @@ Language changes backslashes and the end of the literal while 2n+1 backslashes followed by a quote encodes n backslashes followed by a quote character ([#22926](https://github.com/JuliaLang/julia/issues/22926)). + * `reprmime(mime, x)` has been renamed to `repr(mime, x)`, and along with `repr(x)` + and `sprint` it now accepts an optional `context` keyword for `IOContext` attributes. + `stringmime` has been moved to the Base64 stdlib package ([#25990](https://github.com/JuliaLang/julia/issues/25990)). + * The syntax `(x...)` for constructing a tuple is deprecated; use `(x...,)` instead ([#24452](https://github.com/JuliaLang/julia/issues/24452)). * Non-parenthesized interpolated variables in strings, e.g. `"$x"`, must be followed @@ -334,10 +341,6 @@ This section lists changes that do not have deprecation warnings. longer the case; now bindings will only exist for packages brought into scope by typing `using Package` or `import Package` ([#17997](https://github.com/JuliaLang/julia/issues/17997)). - * `slicedim(b::BitVector, 1, x)` now consistently returns the same thing that `b[x]` would, - consistent with its documentation. Previously it would return a `BitArray{0}` for scalar - `x` ([#20233](https://github.com/JuliaLang/julia/issues/20233)). - * The rules for mixed-signedness integer arithmetic (e.g. `Int32(1) + UInt64(1)`) have been simplified: if the arguments have different sizes (in bits), then the type of the larger argument is used. If the arguments have the same size, the unsigned type is used ([#9292](https://github.com/JuliaLang/julia/issues/9292)). @@ -401,6 +404,10 @@ This section lists changes that do not have deprecation warnings. and higher-dimensional arrays insted of linear indices as was previously the case. Use `LinearIndices(a)[findall(f, a)]` and similar constructs to compute linear indices. + * The `find*` functions which return scalars, i.e. `findnext`, `findprev`, `findfirst`, + and `findlast`, as well as `indexin`, now return `nothing` when no match is found rather + than 0 ([#25472](https://github.com/JuliaLang/julia/issues/25472), [#25662](https://github.com/JuliaLang/julia/issues/25662)). + * The `Base.HasShape` iterator trait has gained a type parameter `N` indicating the number of dimensions, which must correspond to the length of the tuple returned by `size` ([#25655](https://github.com/JuliaLang/julia/issues/25655)). @@ -426,6 +433,8 @@ This section lists changes that do not have deprecation warnings. * The `fieldnames` and `propertynames` functions now return a tuple rather than an array ([#25725](https://github.com/JuliaLang/julia/issues/25725)). + * `indexin` now returns the first rather than the last matching index ([#25998](https://github.com/JuliaLang/julia/issues/25998)). + Library improvements -------------------- @@ -649,6 +658,13 @@ Deprecated or removed * Using Bool values directly as indices is now deprecated and will be an error in the future. Convert them to `Int` before indexing if you intend to access index `1` for `true` and `0` for `false`. + * `slicedim(A, d, i)` has been deprecated in favor of `copy(selectdim(A, d, i))`. The new + `selectdim` function now always returns a view into `A`; in many cases the `copy` is + not necessary. Previously, `slicedim` on a vector `V` over dimension `d=1` and scalar + index `i` would return the just selected element (unless `V` was a `BitVector`). This + has now been made consistent: `selectdim` now always returns a view into the original + array, with a zero-dimensional view in this specific case ([#26009](https://github.com/JuliaLang/julia/issues/26009)). + * `whos` has been renamed `varinfo`, and now returns a markdown table instead of printing output ([#12131](https://github.com/JuliaLang/julia/issues/12131)). @@ -1029,6 +1045,19 @@ Deprecated or removed * `scale!` has been deprecated in favor of `mul!`, `lmul!`, and `rmul!` ([#25701](https://github.com/JuliaLang/julia/issues/25701), [#25812](https://github.com/JuliaLang/julia/issues/25812)). + * The `remove_destination` keyword argument to `cp`, `mv`, and the unexported `cptree` + has been renamed to `force` ([#25979](https://github.com/JuliaLang/julia/issues/25979)). + + * The methods of `range` based on positional arguments have been deprecated in favor of + keyword arguments ([#25896](https://github.com/JuliaLang/julia/issues/25896)). + + * `linspace` has been deprecated in favor of `range` with `stop` and `length` keyword + arguments ([#25896](https://github.com/JuliaLang/julia/issues/25896)). + + * `LinSpace` has been renamed to `LinRange` ([#25896](https://github.com/JuliaLang/julia/issues/25896)). + + * `logspace` has been deprecated to its definition ([#25896](https://github.com/JuliaLang/julia/issues/25896)). + * `endof(a)` has been renamed to `lastindex(a)`, and the `end` keyword in indexing expressions now lowers to either `lastindex(a)` (in the case with only one index) or `lastindex(a, d)` (in cases where there is more than one index and `end` appears at dimension `d`) ([#23554](https://github.com/JuliaLang/julia/issues/23554), [#25763](https://github.com/JuliaLang/julia/issues/25763)). diff --git a/codex/base/arrays.md b/codex/base/arrays.md index 4362cd0..6ea60b5 100644 --- a/codex/base/arrays.md +++ b/codex/base/arrays.md @@ -32,8 +32,6 @@ Base.fill Base.fill! Base.similar(::AbstractArray) Base.similar(::Any, ::Tuple) -Base.linspace -Base.logspace ``` ## Basic functions @@ -102,7 +100,7 @@ Base.@view Base.@views Base.parent Base.parentindices -Base.slicedim +Base.selectdim Base.reinterpret Base.reshape Base.squeeze @@ -147,7 +145,7 @@ Base.cumprod! Base.cumsum Base.cumsum! LinearAlgebra.diff -Base.repeat(::AbstractArray) +Base.repeat Base.rot180 Base.rotl90 Base.rotr90 diff --git a/codex/base/io-network.md b/codex/base/io-network.md index 1816f7b..ec69c67 100644 --- a/codex/base/io-network.md +++ b/codex/base/io-network.md @@ -94,8 +94,7 @@ Base.Multimedia.redisplay Base.Multimedia.displayable Base.show(::Any, ::Any, ::Any) Base.Multimedia.mimewritable -Base.Multimedia.reprmime -Base.Multimedia.stringmime +Base.repr(::Any, ::Any) ``` As mentioned above, one can also define new display backends. For example, a module that can display @@ -105,8 +104,9 @@ types with PNG representations will automatically display the image using the mo In order to define a new display backend, one should first create a subtype `D` of the abstract class `AbstractDisplay`. Then, for each MIME type (`mime` string) that can be displayed on `D`, one should define a function `display(d::D, ::MIME"mime", x) = ...` that displays `x` as that MIME type, -usually by calling [`reprmime(mime, x)`](@ref). A `MethodError` should be thrown if `x` cannot be displayed -as that MIME type; this is automatic if one calls [`reprmime`](@ref). Finally, one should define a function +usually by calling [`show(io, mime, x)`](@ref) or [`repr(io, mime, x)`](@ref). +A `MethodError` should be thrown if `x` cannot be displayed +as that MIME type; this is automatic if one calls `show` or `repr`. Finally, one should define a function `display(d::D, x)` that queries [`mimewritable(mime, x)`](@ref) for the `mime` types supported by `D` and displays the "best" one; a `MethodError` should be thrown if no supported MIME types are found for `x`. Similarly, some subtypes may wish to override [`redisplay(d::D, ...)`](@ref Base.Multimedia.redisplay). (Again, one should diff --git a/codex/base/math.md b/codex/base/math.md index 6b8cbf0..46b3fc1 100644 --- a/codex/base/math.md +++ b/codex/base/math.md @@ -32,7 +32,7 @@ Base.denominator Base.:(<<) Base.:(>>) Base.:(>>>) -Base.colon +Base.:(:) Base.range Base.OneTo Base.StepRangeLen diff --git a/codex/base/punctuation.md b/codex/base/punctuation.md index 19f2604..817aa45 100644 --- a/codex/base/punctuation.md +++ b/codex/base/punctuation.md @@ -36,9 +36,9 @@ Extended documentation for mathematical symbols & functions is [here](@ref math- | ``` ` ` ``` | delimit external process (command) specifications | | `...` | splice arguments into a function call or declare a varargs function | | `.` | access named fields in objects/modules (calling [`getproperty`](@ref Base.getproperty) or [`setproperty!`](@ref Base.setproperty!)), also prefixes elementwise function calls (calling [`broadcast`](@ref)) | -| `a:b` | range a, a+1, a+2, ..., b (calling [`colon`](@ref)) | -| `a:s:b` | range a, a+s, a+2s, ..., b (also calling [`colon`](@ref)) | -| `:` | index an entire dimension (firstindex:lastindex), see [`Colon`](@ref)) | +| `a:b` | range a, a+1, a+2, ..., b | +| `a:s:b` | range a, a+s, a+2s, ..., b | +| `:` | index an entire dimension (firstindex:lastindex), see [`Colon`](@ref)) | | `::` | type annotation or [`typeassert`](@ref), depending on context | | `:( )` | quoted expression | | `:a` | symbol a | diff --git a/codex/base/strings.md b/codex/base/strings.md index 011cf24..f173e13 100644 --- a/codex/base/strings.md +++ b/codex/base/strings.md @@ -8,7 +8,7 @@ Base.:^(::AbstractString, ::Integer) Base.string Base.repeat(::AbstractString, ::Integer) Base.repeat(::Char, ::Integer) -Base.repr +Base.repr(::Any) Core.String(::AbstractString) Base.SubString Base.transcode diff --git a/codex/manual/arrays.md b/codex/manual/arrays.md index b14e7e3..f743206 100644 --- a/codex/manual/arrays.md +++ b/codex/manual/arrays.md @@ -63,7 +63,7 @@ omitted it will default to [`Float64`](@ref). | [`rand(T, dims...)`](@ref) | an `Array` with random, iid [^1] and uniformly distributed values in the half-open interval ``[0, 1)`` | | [`randn(T, dims...)`](@ref) | an `Array` with random, iid and standard normally distributed values | | [`Matrix{T}(I, m, n)`](@ref) | `m`-by-`n` identity matrix | -| [`linspace(start, stop, n)`](@ref) | range of `n` linearly spaced elements from `start` to `stop` | +| [`range(start, stop=stop, length=n)`](@ref) | range of `n` linearly spaced elements from `start` to `stop` | | [`fill!(A, x)`](@ref) | fill the array `A` with the value `x` | | [`fill(x, dims...)`](@ref) | an `Array` filled with the value `x` | @@ -619,7 +619,7 @@ be to replicate the vector to the size of the matrix: ```julia-repl julia> a = rand(2,1); A = rand(2,3); -julia> repmat(a,1,3)+A +julia> repeat(a,1,3)+A 2×3 Array{Float64,2}: 1.20813 1.82068 1.25387 1.56851 1.86401 1.67846 diff --git a/codex/manual/functions.md b/codex/manual/functions.md index df9696f..fc79f56 100644 --- a/codex/manual/functions.md +++ b/codex/manual/functions.md @@ -164,7 +164,6 @@ A few special expressions correspond to calls to functions with non-obvious name | `[A; B; C; ...]` | [`vcat`](@ref) | | `[A B; C D; ...]` | [`hvcat`](@ref) | | `A'` | [`adjoint`](@ref) | -| `1:n` | [`colon`](@ref) | | `A[i]` | [`getindex`](@ref) | | `A[i] = x` | [`setindex!`](@ref) | | `A.n` | [`getproperty`](@ref Base.getproperty) | diff --git a/codex/manual/integers-and-floating-point-numbers.md b/codex/manual/integers-and-floating-point-numbers.md index 49d7893..b1295d1 100644 --- a/codex/manual/integers-and-floating-point-numbers.md +++ b/codex/manual/integers-and-floating-point-numbers.md @@ -338,7 +338,7 @@ julia> 10_000, 0.000_000_005, 0xdead_beef, 0b1011_0010 Floating-point numbers have [two zeros](https://en.wikipedia.org/wiki/Signed_zero), positive zero and negative zero. They are equal to each other but have different binary representations, as -can be seen using the `bits` function: : +can be seen using the `bits` function: ```jldoctest julia> 0.0 == -0.0 diff --git a/codex/manual/noteworthy-differences.md b/codex/manual/noteworthy-differences.md index 12b3ce2..dd0a8c1 100644 --- a/codex/manual/noteworthy-differences.md +++ b/codex/manual/noteworthy-differences.md @@ -38,7 +38,7 @@ may trip up Julia users accustomed to MATLAB: use [`collect(a:b)`](@ref). Generally, there is no need to call `collect` though. An `AbstractRange` object will act like a normal array in most cases but is more efficient because it lazily computes its values. This pattern of creating specialized objects instead of full arrays is used frequently, and is - also seen in functions such as [`linspace`](@ref), or with iterators such as `enumerate`, and + also seen in functions such as [`range`](@ref), or with iterators such as `enumerate`, and `zip`. The special objects can mostly be used as if they were normal arrays. * Functions in Julia return values from their last expression or the `return` keyword instead of listing the names of variables to return in the function definition (see [The return Keyword](@ref) diff --git a/codex/manual/parallel-computing.md b/codex/manual/parallel-computing.md index 514e36d..195d039 100644 --- a/codex/manual/parallel-computing.md +++ b/codex/manual/parallel-computing.md @@ -956,7 +956,7 @@ julia> @everywhere function myrange(q::SharedArray) return 1:0, 1:0 end nchunks = length(procs(q)) - splits = [round(Int, s) for s in linspace(0,size(q,2),nchunks+1)] + splits = [round(Int, s) for s in range(0, stop=size(q,2), length=nchunks+1)] 1:size(q,1), splits[idx]+1:splits[idx+1] end ``` diff --git a/codex/manual/performance-tips.md b/codex/manual/performance-tips.md index f2c10d0..a832506 100644 --- a/codex/manual/performance-tips.md +++ b/codex/manual/performance-tips.md @@ -841,7 +841,7 @@ Consider the following contrived example. Imagine we wanted to write a function [`Vector`](@ref) and returns a square [`Matrix`](@ref) with either the rows or the columns filled with copies of the input vector. Assume that it is not important whether rows or columns are filled with these copies (perhaps the rest of the code can be easily adapted accordingly). We could conceivably -do this in at least four ways (in addition to the recommended call to the built-in [`repmat`](@ref)): +do this in at least four ways (in addition to the recommended call to the built-in [`repeat`](@ref)): ```julia function copy_cols(x::Vector{T}) where T diff --git a/codex/stdlib/Base64.md b/codex/stdlib/Base64.md index 4b4eb6e..02e7e6b 100644 --- a/codex/stdlib/Base64.md +++ b/codex/stdlib/Base64.md @@ -5,4 +5,5 @@ Base64.Base64EncodePipe Base64.base64encode Base64.Base64DecodePipe Base64.base64decode +Base64.stringmime ``` diff --git a/codex/stdlib/REPL.md b/codex/stdlib/REPL.md index ff828c3..34422a2 100644 --- a/codex/stdlib/REPL.md +++ b/codex/stdlib/REPL.md @@ -67,7 +67,7 @@ When the cursor is at the beginning of the line, the prompt can be changed to a julia> ? # upon typing ?, the prompt changes (in place) to: help?> help?> string -search: string String stringmime Cstring Cwstring RevString randstring bytestring SubString +search: string String Cstring Cwstring RevString randstring bytestring SubString string(xs...) @@ -220,7 +220,7 @@ or type and then press the tab key to get a list all matches: ```julia-repl julia> stri[TAB] -stride strides string stringmime strip +stride strides string strip julia> Stri[TAB] StridedArray StridedMatrix StridedVecOrMat StridedVector String diff --git a/codex/stdlib/base64.md b/codex/stdlib/base64.md index 4b4eb6e..02e7e6b 100644 --- a/codex/stdlib/base64.md +++ b/codex/stdlib/base64.md @@ -5,4 +5,5 @@ Base64.Base64EncodePipe Base64.base64encode Base64.Base64DecodePipe Base64.base64decode +Base64.stringmime ``` diff --git a/src/NEWS.md b/src/NEWS.md index 4c1798a..fde0828 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -70,6 +70,9 @@ Language changes * The parsing of `<|` is now right associative. `|>` remains left associative ([#24153](https://github.com/JuliaLang/julia/issues/24153)). + * `:` now parses like other operators, as a call to a function named `:`, instead of + calling `colon` ([#25947](https://github.com/JuliaLang/julia/issues/25947)). + * `{ }` expressions now use `braces` and `bracescat` as expression heads instead of `cell1d` and `cell2d`, and parse similarly to `vect` and `vcat` ([#8470](https://github.com/JuliaLang/julia/issues/8470)). @@ -168,6 +171,10 @@ Language changes backslashes and the end of the literal while 2n+1 backslashes followed by a quote encodes n backslashes followed by a quote character ([#22926](https://github.com/JuliaLang/julia/issues/22926)). + * `reprmime(mime, x)` has been renamed to `repr(mime, x)`, and along with `repr(x)` + and `sprint` it now accepts an optional `context` keyword for `IOContext` attributes. + `stringmime` has been moved to the Base64 stdlib package ([#25990](https://github.com/JuliaLang/julia/issues/25990)). + * The syntax `(x...)` for constructing a tuple is deprecated; use `(x...,)` instead ([#24452](https://github.com/JuliaLang/julia/issues/24452)). * Non-parenthesized interpolated variables in strings, e.g. `"$x"`, must be followed @@ -322,10 +329,6 @@ This section lists changes that do not have deprecation warnings. longer the case; now bindings will only exist for packages brought into scope by typing `using Package` or `import Package` ([#17997](https://github.com/JuliaLang/julia/issues/17997)). - * `slicedim(b::BitVector, 1, x)` now consistently returns the same thing that `b[x]` would, - consistent with its documentation. Previously it would return a `BitArray{0}` for scalar - `x` ([#20233](https://github.com/JuliaLang/julia/issues/20233)). - * The rules for mixed-signedness integer arithmetic (e.g. `Int32(1) + UInt64(1)`) have been simplified: if the arguments have different sizes (in bits), then the type of the larger argument is used. If the arguments have the same size, the unsigned type is used ([#9292](https://github.com/JuliaLang/julia/issues/9292)). @@ -389,6 +392,10 @@ This section lists changes that do not have deprecation warnings. and higher-dimensional arrays insted of linear indices as was previously the case. Use `LinearIndices(a)[findall(f, a)]` and similar constructs to compute linear indices. + * The `find*` functions which return scalars, i.e. `findnext`, `findprev`, `findfirst`, + and `findlast`, as well as `indexin`, now return `nothing` when no match is found rather + than 0 ([#25472](https://github.com/JuliaLang/julia/issues/25472), [#25662](https://github.com/JuliaLang/julia/issues/25662)). + * The `Base.HasShape` iterator trait has gained a type parameter `N` indicating the number of dimensions, which must correspond to the length of the tuple returned by `size` ([#25655](https://github.com/JuliaLang/julia/issues/25655)). @@ -414,6 +421,8 @@ This section lists changes that do not have deprecation warnings. * The `fieldnames` and `propertynames` functions now return a tuple rather than an array ([#25725](https://github.com/JuliaLang/julia/issues/25725)). + * `indexin` now returns the first rather than the last matching index ([#25998](https://github.com/JuliaLang/julia/issues/25998)). + Library improvements -------------------- @@ -637,6 +646,13 @@ Deprecated or removed * Using Bool values directly as indices is now deprecated and will be an error in the future. Convert them to `Int` before indexing if you intend to access index `1` for `true` and `0` for `false`. + * `slicedim(A, d, i)` has been deprecated in favor of `copy(selectdim(A, d, i))`. The new + `selectdim` function now always returns a view into `A`; in many cases the `copy` is + not necessary. Previously, `slicedim` on a vector `V` over dimension `d=1` and scalar + index `i` would return the just selected element (unless `V` was a `BitVector`). This + has now been made consistent: `selectdim` now always returns a view into the original + array, with a zero-dimensional view in this specific case ([#26009](https://github.com/JuliaLang/julia/issues/26009)). + * `whos` has been renamed `varinfo`, and now returns a markdown table instead of printing output ([#12131](https://github.com/JuliaLang/julia/issues/12131)). @@ -1017,6 +1033,19 @@ Deprecated or removed * `scale!` has been deprecated in favor of `mul!`, `lmul!`, and `rmul!` ([#25701](https://github.com/JuliaLang/julia/issues/25701), [#25812](https://github.com/JuliaLang/julia/issues/25812)). + * The `remove_destination` keyword argument to `cp`, `mv`, and the unexported `cptree` + has been renamed to `force` ([#25979](https://github.com/JuliaLang/julia/issues/25979)). + + * The methods of `range` based on positional arguments have been deprecated in favor of + keyword arguments ([#25896](https://github.com/JuliaLang/julia/issues/25896)). + + * `linspace` has been deprecated in favor of `range` with `stop` and `length` keyword + arguments ([#25896](https://github.com/JuliaLang/julia/issues/25896)). + + * `LinSpace` has been renamed to `LinRange` ([#25896](https://github.com/JuliaLang/julia/issues/25896)). + + * `logspace` has been deprecated to its definition ([#25896](https://github.com/JuliaLang/julia/issues/25896)). + * `endof(a)` has been renamed to `lastindex(a)`, and the `end` keyword in indexing expressions now lowers to either `lastindex(a)` (in the case with only one index) or `lastindex(a, d)` (in cases where there is more than one index and `end` appears at dimension `d`) ([#23554](https://github.com/JuliaLang/julia/issues/23554), [#25763](https://github.com/JuliaLang/julia/issues/25763)). diff --git a/src/base/arrays.md b/src/base/arrays.md index 4362cd0..6ea60b5 100644 --- a/src/base/arrays.md +++ b/src/base/arrays.md @@ -32,8 +32,6 @@ Base.fill Base.fill! Base.similar(::AbstractArray) Base.similar(::Any, ::Tuple) -Base.linspace -Base.logspace ``` ## Basic functions @@ -102,7 +100,7 @@ Base.@view Base.@views Base.parent Base.parentindices -Base.slicedim +Base.selectdim Base.reinterpret Base.reshape Base.squeeze @@ -147,7 +145,7 @@ Base.cumprod! Base.cumsum Base.cumsum! LinearAlgebra.diff -Base.repeat(::AbstractArray) +Base.repeat Base.rot180 Base.rotl90 Base.rotr90 diff --git a/src/base/io-network.md b/src/base/io-network.md index 1816f7b..ec69c67 100644 --- a/src/base/io-network.md +++ b/src/base/io-network.md @@ -94,8 +94,7 @@ Base.Multimedia.redisplay Base.Multimedia.displayable Base.show(::Any, ::Any, ::Any) Base.Multimedia.mimewritable -Base.Multimedia.reprmime -Base.Multimedia.stringmime +Base.repr(::Any, ::Any) ``` As mentioned above, one can also define new display backends. For example, a module that can display @@ -105,8 +104,9 @@ types with PNG representations will automatically display the image using the mo In order to define a new display backend, one should first create a subtype `D` of the abstract class `AbstractDisplay`. Then, for each MIME type (`mime` string) that can be displayed on `D`, one should define a function `display(d::D, ::MIME"mime", x) = ...` that displays `x` as that MIME type, -usually by calling [`reprmime(mime, x)`](@ref). A `MethodError` should be thrown if `x` cannot be displayed -as that MIME type; this is automatic if one calls [`reprmime`](@ref). Finally, one should define a function +usually by calling [`show(io, mime, x)`](@ref) or [`repr(io, mime, x)`](@ref). +A `MethodError` should be thrown if `x` cannot be displayed +as that MIME type; this is automatic if one calls `show` or `repr`. Finally, one should define a function `display(d::D, x)` that queries [`mimewritable(mime, x)`](@ref) for the `mime` types supported by `D` and displays the "best" one; a `MethodError` should be thrown if no supported MIME types are found for `x`. Similarly, some subtypes may wish to override [`redisplay(d::D, ...)`](@ref Base.Multimedia.redisplay). (Again, one should diff --git a/src/base/math.md b/src/base/math.md index 6b8cbf0..46b3fc1 100644 --- a/src/base/math.md +++ b/src/base/math.md @@ -32,7 +32,7 @@ Base.denominator Base.:(<<) Base.:(>>) Base.:(>>>) -Base.colon +Base.:(:) Base.range Base.OneTo Base.StepRangeLen diff --git a/src/base/punctuation.md b/src/base/punctuation.md index 19f2604..817aa45 100644 --- a/src/base/punctuation.md +++ b/src/base/punctuation.md @@ -36,9 +36,9 @@ Extended documentation for mathematical symbols & functions is [here](@ref math- | ``` ` ` ``` | delimit external process (command) specifications | | `...` | splice arguments into a function call or declare a varargs function | | `.` | access named fields in objects/modules (calling [`getproperty`](@ref Base.getproperty) or [`setproperty!`](@ref Base.setproperty!)), also prefixes elementwise function calls (calling [`broadcast`](@ref)) | -| `a:b` | range a, a+1, a+2, ..., b (calling [`colon`](@ref)) | -| `a:s:b` | range a, a+s, a+2s, ..., b (also calling [`colon`](@ref)) | -| `:` | index an entire dimension (firstindex:lastindex), see [`Colon`](@ref)) | +| `a:b` | range a, a+1, a+2, ..., b | +| `a:s:b` | range a, a+s, a+2s, ..., b | +| `:` | index an entire dimension (firstindex:lastindex), see [`Colon`](@ref)) | | `::` | type annotation or [`typeassert`](@ref), depending on context | | `:( )` | quoted expression | | `:a` | symbol a | diff --git a/src/base/strings.md b/src/base/strings.md index 011cf24..f173e13 100644 --- a/src/base/strings.md +++ b/src/base/strings.md @@ -8,7 +8,7 @@ Base.:^(::AbstractString, ::Integer) Base.string Base.repeat(::AbstractString, ::Integer) Base.repeat(::Char, ::Integer) -Base.repr +Base.repr(::Any) Core.String(::AbstractString) Base.SubString Base.transcode diff --git a/src/manual/arrays.md b/src/manual/arrays.md index 5815790..2139587 100644 --- a/src/manual/arrays.md +++ b/src/manual/arrays.md @@ -45,24 +45,24 @@ Julia 배열 라이브러리의 어떤 코드도 입력 배열을 변경하지 이 함수들의 대부분은 첫번째 인수로 배열의 원소 타입 `T`를 받을 수 있다. `T`가 생략되었다면 [`Float64`](@ref)가 기본값이다. -| 함수 | 설명 | -|:------------------------------------------ |:------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| [`Array{T}(uninitialized, dims...)`](@ref) | 초기화 되지 않은 밀집 [`Array`](@ref) | -| [`zeros(T, dims...)`](@ref) | 모든 값이 0으로 초기화 된 `Array` | -| [`ones(T, dims...)`](@ref) | 모든 값이 1로 초기화 된 `Array` | -| [`trues(dims...)`](@ref) | 모든 값이 `true`로 초기화 된 [`BitArray`](@ref) | -| [`falses(dims...)`](@ref) | 모든 값이 `false`로 초기화 된 `BitArray` | -| [`reshape(A, dims...)`](@ref) | `A` 와 동일한 데이타를 가지고 있지만 형상이 다른 배열 | -| [`copy(A)`](@ref) | `A` 의 얕은 복사 | -| [`deepcopy(A)`](@ref) | `A` 의 깊은 복사 (모든 원소를 재귀적으로 복사함) | -| [`similar(A, T, dims...)`](@ref) | `A` 와 동일한 종류(밀집, 희소, 등)의 초기화 되지 않은 배열. 지정된 원소 타입과 형상을 가짐. 두번째와 세번째 인수는 선택적이며, 기본값은 `A`의 원소타입과 차원이다. | -| [`reinterpret(T, A)`](@ref) | `A` 와 동일한 이진 데이터를 가지고 있지만, 원소 타입이 `T` 인 배열 | -| [`rand(T, dims...)`](@ref) | 독립 동일하며 열린구간 ``[0, 1)`` 상에서 연속 균일 분포를 가진 랜덤 `Array` | -| [`randn(T, dims...)`](@ref) | 독립 동일하며 표준 정규 분포를 가진 랜덤 `Array` | -| [`Matrix{T}(I, m, n)`](@ref) | 크기가 `m` × `n` 인 단위 행렬 | -| [`linspace(start, stop, n)`](@ref) | `start`에서 `stop`까지 `n` 개의 원소가 선형적으로 배치된 구간 | -| [`fill!(A, x)`](@ref) | 배열 `A` 를 `x` 값으로 채우기 | -| [`fill(x, dims...)`](@ref) | `x` 값으로 차 있는 `Array` | +| 함수 | 설명 | +|:---------------------------------- |:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [`Array{T}(uninitialized, dims...)`](@ref) | 초기화 되지 않은 밀집 [`Array`](@ref) | +| [`zeros(T, dims...)`](@ref) | 모든 값이 0으로 초기화 된 `Array` | +| [`ones(T, dims...)`](@ref) | 모든 값이 1로 초기화 된 `Array` | +| [`trues(dims...)`](@ref) | 모든 값이 `true`로 초기화 된 [`BitArray`](@ref) | +| [`falses(dims...)`](@ref) | 모든 값이 `false`로 초기화 된 `BitArray` | +| [`reshape(A, dims...)`](@ref) | `A` 와 동일한 데이타를 가지고 있지만 형상이 다른 배열 | +| [`copy(A)`](@ref) | `A` 의 얕은 복사 | +| [`deepcopy(A)`](@ref) | `A` 의 깊은 복사 (모든 원소를 재귀적으로 복사함) | +| [`similar(A, T, dims...)`](@ref) | `A` 와 동일한 종류(밀집, 희소, 등)의 초기화 되지 않은 배열. 지정된 원소 타입과 형상을 가짐. 두번째와 세번째 인수는 선택적이며, 기본값은 `A`의 원소타입과 차원이다. | +| [`reinterpret(T, A)`](@ref) | `A` 와 동일한 이진 데이터를 가지고 있지만, 원소 타입이 `T` 인 배열 | +| [`rand(T, dims...)`](@ref) | 독립 동일하며 열린구간 ``[0, 1)`` 상에서 연속 균일 분포를 가진 랜덤 `Array` | +| [`randn(T, dims...)`](@ref) | 독립 동일하며 표준 정규 분포를 가진 랜덤 `Array` | +| [`Matrix{T}(I, m, n)`](@ref) | 크기가 `m` × `n` 인 단위 행렬 | +| [`range(start, stop=stop, length=n)`](@ref) | `start`에서 `stop`까지 `n` 개의 원소가 선형적으로 배치된 구간 | +| [`fill!(A, x)`](@ref) | 배열 `A` 를 `x` 값으로 채우기 | +| [`fill(x, dims...)`](@ref) | `x` 값으로 차 있는 `Array` | `[A, B, C, ...]` 문법은 주어진 인수들의 일차원 배열(벡터)을 생성한다. 만약 모든 인수가 공통의 [확장 타입(promotion type)](@ref conversion-and-promotion)을 가진다면, 이들은 [`convert`](@ref)를 통해 공통의 확장 타입으로 변환된다. @@ -571,7 +571,7 @@ Base.IndexStyle(::Type{<:MyArray}) = IndexLinear() ```julia-repl julia> a = rand(2,1); A = rand(2,3); -julia> repmat(a,1,3)+A +julia> repeat(a,1,3)+A 2×3 Array{Float64,2}: 1.20813 1.82068 1.25387 1.56851 1.86401 1.67846 diff --git a/src/manual/functions.md b/src/manual/functions.md index df9696f..fc79f56 100644 --- a/src/manual/functions.md +++ b/src/manual/functions.md @@ -164,7 +164,6 @@ A few special expressions correspond to calls to functions with non-obvious name | `[A; B; C; ...]` | [`vcat`](@ref) | | `[A B; C D; ...]` | [`hvcat`](@ref) | | `A'` | [`adjoint`](@ref) | -| `1:n` | [`colon`](@ref) | | `A[i]` | [`getindex`](@ref) | | `A[i] = x` | [`setindex!`](@ref) | | `A.n` | [`getproperty`](@ref Base.getproperty) | diff --git a/src/manual/noteworthy-differences.md b/src/manual/noteworthy-differences.md index 12b3ce2..dd0a8c1 100644 --- a/src/manual/noteworthy-differences.md +++ b/src/manual/noteworthy-differences.md @@ -38,7 +38,7 @@ may trip up Julia users accustomed to MATLAB: use [`collect(a:b)`](@ref). Generally, there is no need to call `collect` though. An `AbstractRange` object will act like a normal array in most cases but is more efficient because it lazily computes its values. This pattern of creating specialized objects instead of full arrays is used frequently, and is - also seen in functions such as [`linspace`](@ref), or with iterators such as `enumerate`, and + also seen in functions such as [`range`](@ref), or with iterators such as `enumerate`, and `zip`. The special objects can mostly be used as if they were normal arrays. * Functions in Julia return values from their last expression or the `return` keyword instead of listing the names of variables to return in the function definition (see [The return Keyword](@ref) diff --git a/src/manual/parallel-computing.md b/src/manual/parallel-computing.md index 514e36d..195d039 100644 --- a/src/manual/parallel-computing.md +++ b/src/manual/parallel-computing.md @@ -956,7 +956,7 @@ julia> @everywhere function myrange(q::SharedArray) return 1:0, 1:0 end nchunks = length(procs(q)) - splits = [round(Int, s) for s in linspace(0,size(q,2),nchunks+1)] + splits = [round(Int, s) for s in range(0, stop=size(q,2), length=nchunks+1)] 1:size(q,1), splits[idx]+1:splits[idx+1] end ``` diff --git a/src/manual/performance-tips.md b/src/manual/performance-tips.md index f2c10d0..a832506 100644 --- a/src/manual/performance-tips.md +++ b/src/manual/performance-tips.md @@ -841,7 +841,7 @@ Consider the following contrived example. Imagine we wanted to write a function [`Vector`](@ref) and returns a square [`Matrix`](@ref) with either the rows or the columns filled with copies of the input vector. Assume that it is not important whether rows or columns are filled with these copies (perhaps the rest of the code can be easily adapted accordingly). We could conceivably -do this in at least four ways (in addition to the recommended call to the built-in [`repmat`](@ref)): +do this in at least four ways (in addition to the recommended call to the built-in [`repeat`](@ref)): ```julia function copy_cols(x::Vector{T}) where T diff --git a/src/stdlib/Base64.md b/src/stdlib/Base64.md index 4b4eb6e..02e7e6b 100644 --- a/src/stdlib/Base64.md +++ b/src/stdlib/Base64.md @@ -5,4 +5,5 @@ Base64.Base64EncodePipe Base64.base64encode Base64.Base64DecodePipe Base64.base64decode +Base64.stringmime ``` diff --git a/src/stdlib/REPL.md b/src/stdlib/REPL.md index ff828c3..34422a2 100644 --- a/src/stdlib/REPL.md +++ b/src/stdlib/REPL.md @@ -67,7 +67,7 @@ When the cursor is at the beginning of the line, the prompt can be changed to a julia> ? # upon typing ?, the prompt changes (in place) to: help?> help?> string -search: string String stringmime Cstring Cwstring RevString randstring bytestring SubString +search: string String Cstring Cwstring RevString randstring bytestring SubString string(xs...) @@ -220,7 +220,7 @@ or type and then press the tab key to get a list all matches: ```julia-repl julia> stri[TAB] -stride strides string stringmime strip +stride strides string strip julia> Stri[TAB] StridedArray StridedMatrix StridedVecOrMat StridedVector String diff --git a/src/stdlib/base64.md b/src/stdlib/base64.md index 4b4eb6e..02e7e6b 100644 --- a/src/stdlib/base64.md +++ b/src/stdlib/base64.md @@ -5,4 +5,5 @@ Base64.Base64EncodePipe Base64.base64encode Base64.Base64DecodePipe Base64.base64decode +Base64.stringmime ``` From a6665938553e7b6d288bbeefeb6a34442beadc7f Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Fri, 23 Feb 2018 14:08:41 +0900 Subject: [PATCH 007/153] update Julia Commit 33ca610de6 --- codex/NEWS.md | 26 ++++---- codex/base/io-network.md | 4 +- codex/base/strings.md | 1 - codex/manual/arrays.md | 39 ++++++----- codex/manual/documentation.md | 4 +- codex/manual/embedding.md | 2 +- codex/manual/modules.md | 2 +- codex/manual/parallel-computing.md | 94 ++++++++++++++++++++++++++- codex/manual/style-guide.md | 2 +- codex/stdlib/Base64.md | 8 +++ codex/stdlib/Dates.md | 8 +++ codex/stdlib/DelimitedFiles.md | 8 +++ codex/stdlib/Distributed.md | 8 +++ codex/stdlib/InteractiveUtils.md | 8 +++ codex/stdlib/IterativeEigensolvers.md | 8 +++ codex/stdlib/LinearAlgebra.md | 9 ++- codex/stdlib/Mmap.md | 8 +++ codex/stdlib/Pkg.md | 8 +++ codex/stdlib/Printf.md | 8 +++ codex/stdlib/Random.md | 8 +++ codex/stdlib/SparseArrays.md | 8 +++ codex/stdlib/Test.md | 4 +- codex/stdlib/UUIDs.md | 8 +++ codex/stdlib/Unicode.md | 8 +++ codex/stdlib/base64.md | 8 +++ codex/stdlib/dates.md | 8 +++ codex/stdlib/delimitedfiles.md | 8 +++ codex/stdlib/distributed.md | 8 +++ codex/stdlib/iterativeeigensolvers.md | 8 +++ codex/stdlib/linearalgebra.md | 9 ++- codex/stdlib/mmap.md | 8 +++ codex/stdlib/printf.md | 8 +++ codex/stdlib/random.md | 8 +++ codex/stdlib/sparsearrays.md | 8 +++ codex/stdlib/test.md | 4 +- codex/stdlib/unicode.md | 8 +++ make.jl | 2 +- src/NEWS.md | 26 ++++---- src/base/io-network.md | 4 +- src/base/strings.md | 1 - src/manual/arrays.md | 35 ++++++---- src/manual/documentation.md | 4 +- src/manual/embedding.md | 2 +- src/manual/modules.md | 2 +- src/manual/parallel-computing.md | 94 ++++++++++++++++++++++++++- src/manual/style-guide.md | 2 +- src/stdlib/Base64.md | 8 +++ src/stdlib/Dates.md | 8 +++ src/stdlib/DelimitedFiles.md | 8 +++ src/stdlib/Distributed.md | 8 +++ src/stdlib/InteractiveUtils.md | 8 +++ src/stdlib/IterativeEigensolvers.md | 8 +++ src/stdlib/LinearAlgebra.md | 9 ++- src/stdlib/Mmap.md | 8 +++ src/stdlib/Pkg.md | 8 +++ src/stdlib/Printf.md | 8 +++ src/stdlib/Random.md | 8 +++ src/stdlib/SparseArrays.md | 8 +++ src/stdlib/Test.md | 4 +- src/stdlib/UUIDs.md | 8 +++ src/stdlib/Unicode.md | 8 +++ src/stdlib/base64.md | 8 +++ src/stdlib/dates.md | 8 +++ src/stdlib/delimitedfiles.md | 8 +++ src/stdlib/distributed.md | 8 +++ src/stdlib/iterativeeigensolvers.md | 8 +++ src/stdlib/linearalgebra.md | 9 ++- src/stdlib/mmap.md | 8 +++ src/stdlib/printf.md | 8 +++ src/stdlib/random.md | 8 +++ src/stdlib/sparsearrays.md | 8 +++ src/stdlib/test.md | 4 +- src/stdlib/unicode.md | 8 +++ 73 files changed, 675 insertions(+), 91 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index e707c30..1a0e2eb 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -165,7 +165,7 @@ Language changes expressions) ([#23885](https://github.com/JuliaLang/julia/issues/23885)). * The `+` and `-` methods for `Number` and `UniformScaling` are not ambiguous anymore since `+` - and `-` no longer do automatic broadcasting. Hence the methods for `UniformScaling` and `Number` are + and `-` no longer do automatic broadcasting. Hence, the methods for `UniformScaling` and `Number` are no longer deprecated ([#23923](https://github.com/JuliaLang/julia/issues/23923)). * The keyword `importall` is deprecated. Use `using` and/or individual `import` statements @@ -210,6 +210,11 @@ Breaking changes This section lists changes that do not have deprecation warnings. + * `replace(s::AbstractString, pat=>repl)` for function `repl` arguments formerly + passed a substring to `repl` in all cases. It now passes substrings for + string patterns `pat`, but a `Char` for character patterns (when `pat` is a + `Char`, collection of `Char`, or a character predicate) ([#25815](https://github.com/JuliaLang/julia/issues/25815)). + * `readuntil` now does *not* include the delimiter in its result, matching the behavior of `readline`. Pass `keep=true` to get the old behavior ([#25633](https://github.com/JuliaLang/julia/issues/25633)). @@ -226,7 +231,7 @@ This section lists changes that do not have deprecation warnings. * `finalizer(function, object)` now returns `object` rather than `nothing` ([#24679](https://github.com/JuliaLang/julia/issues/24679)). - * The constructor of `SubString` now checks if the requsted view range + * The constructor of `SubString` now checks if the requested view range is defined by valid indices in the parent `AbstractString` ([#22511](https://github.com/JuliaLang/julia/issues/22511)). * Macro calls with `for` expressions are now parsed as generators inside @@ -259,7 +264,7 @@ This section lists changes that do not have deprecation warnings. returned ([#21825](https://github.com/JuliaLang/julia/issues/21825)). * Using `ARGS` within the ~/.juliarc.jl or within a .jl file loaded with `--load` will no - longer contain the script name as the first argument. Instead the script name will be + longer contain the script name as the first argument. Instead, the script name will be assigned to `PROGRAM_FILE`. ([#22092](https://github.com/JuliaLang/julia/issues/22092)) * The format for a `ClusterManager` specifying the cookie on the command line is now @@ -337,7 +342,7 @@ This section lists changes that do not have deprecation warnings. * The `openspecfun` library is no longer built and shipped with Julia, as it is no longer used internally ([#22390](https://github.com/JuliaLang/julia/issues/22390)). - * All loaded packges used to have bindings in `Main` (e.g. `Main.Package`). This is no + * All loaded packages used to have bindings in `Main` (e.g. `Main.Package`). This is no longer the case; now bindings will only exist for packages brought into scope by typing `using Package` or `import Package` ([#17997](https://github.com/JuliaLang/julia/issues/17997)). @@ -401,7 +406,7 @@ This section lists changes that do not have deprecation warnings. now take and/or return the same type of indices as `keys`/`pairs` for `AbstractArray`, `AbstractDict`, `AbstractString`, `Tuple` and `NamedTuple` objects ([#24774](https://github.com/JuliaLang/julia/issues/24774), [#25545](https://github.com/JuliaLang/julia/issues/25545)). In particular, this means that they use `CartesianIndex` objects for matrices - and higher-dimensional arrays insted of linear indices as was previously the case. + and higher-dimensional arrays instead of linear indices as was previously the case. Use `LinearIndices(a)[findall(f, a)]` and similar constructs to compute linear indices. * The `find*` functions which return scalars, i.e. `findnext`, `findprev`, `findfirst`, @@ -508,9 +513,6 @@ Library improvements git repo. Additionally, the argument order was changed to be consistent with the git command line tool ([#22062](https://github.com/JuliaLang/julia/issues/22062)). - * `logspace` now accepts a `base` keyword argument to specify the base of the logarithmic - range. The base defaults to 10 ([#22310](https://github.com/JuliaLang/julia/issues/22310)). - * Added `unique!` which is an inplace version of `unique` ([#20549](https://github.com/JuliaLang/julia/issues/20549)). * `@test isequal(x, y)` and `@test isapprox(x, y)` now prints an evaluated expression when @@ -593,7 +595,7 @@ Library improvements Use `unique` to get the old behavior. * The type `LinearIndices` has been added, providing conversion from - cartesian incices to linear indices using the normal indexing operation. ([#24715](https://github.com/JuliaLang/julia/issues/24715)) + cartesian indices to linear indices using the normal indexing operation. ([#24715](https://github.com/JuliaLang/julia/issues/24715)) * `IdDict{K,V}` replaces `ObjectIdDict`. It has type parameters like other `AbstractDict` subtypes and its constructors mirror the @@ -602,6 +604,9 @@ Library improvements * `IOBuffer` can take the `sizehint` keyword argument to suggest a capacity of the buffer ([#25944](https://github.com/JuliaLang/julia/issues/25944)). + * `trunc`, `floor`, `ceil`, `round`, and `signif` specify `base` using a + keyword argument. ([#26156](https://github.com/JuliaLang/julia/issues/26156)) + Compiler/Runtime improvements ----------------------------- @@ -1004,8 +1009,7 @@ Deprecated or removed * `ismatch(regex, str)` has been deprecated in favor of `contains(str, regex)` ([#24673](https://github.com/JuliaLang/julia/issues/24673)). - * `linspace` and `logspace` now require an explicit number of elements to be - supplied rather than defaulting to `50`([#24794](https://github.com/JuliaLang/julia/issues/24794), [#24805](https://github.com/JuliaLang/julia/issues/24805)). + * `matchall` has been deprecated in favor of `collect(m.match for m in eachmatch(r, s))` ([#26071](https://github.com/JuliaLang/julia/issues/26071)). * `similar(::Associative)` has been deprecated in favor of `empty(::Associative)`, and `similar(::Associative, ::Pair{K, V})` has been deprecated in favour of diff --git a/codex/base/io-network.md b/codex/base/io-network.md index ec69c67..396c0ef 100644 --- a/codex/base/io-network.md +++ b/codex/base/io-network.md @@ -93,7 +93,7 @@ Base.Multimedia.display Base.Multimedia.redisplay Base.Multimedia.displayable Base.show(::Any, ::Any, ::Any) -Base.Multimedia.mimewritable +Base.Multimedia.showable Base.repr(::Any, ::Any) ``` @@ -107,7 +107,7 @@ define a function `display(d::D, ::MIME"mime", x) = ...` that displays `x` as th usually by calling [`show(io, mime, x)`](@ref) or [`repr(io, mime, x)`](@ref). A `MethodError` should be thrown if `x` cannot be displayed as that MIME type; this is automatic if one calls `show` or `repr`. Finally, one should define a function -`display(d::D, x)` that queries [`mimewritable(mime, x)`](@ref) for the `mime` types supported by `D` +`display(d::D, x)` that queries [`showable(mime, x)`](@ref) for the `mime` types supported by `D` and displays the "best" one; a `MethodError` should be thrown if no supported MIME types are found for `x`. Similarly, some subtypes may wish to override [`redisplay(d::D, ...)`](@ref Base.Multimedia.redisplay). (Again, one should `import Base.display` to add new methods to `display`.) The return values of these functions are diff --git a/codex/base/strings.md b/codex/base/strings.md index f173e13..d71e7ef 100644 --- a/codex/base/strings.md +++ b/codex/base/strings.md @@ -26,7 +26,6 @@ Base.isvalid(::Any, ::Any) Base.isvalid(::AbstractString, ::Integer) Base.match Base.eachmatch -Base.matchall Base.isless(::AbstractString, ::AbstractString) Base.:(==)(::AbstractString, ::AbstractString) Base.cmp(::AbstractString, ::AbstractString) diff --git a/codex/manual/arrays.md b/codex/manual/arrays.md index f743206..09ca6a3 100644 --- a/codex/manual/arrays.md +++ b/codex/manual/arrays.md @@ -697,21 +697,13 @@ object returned by *integer* indexing (`A[1, ..., 1]`, when `A` is not empty) an the length of the tuple returned by [`size`](@ref). For more details on defining custom `AbstractArray` implementations, see the [array interface guide in the interfaces chapter](@ref man-interface-array). -`DenseArray` is an abstract subtype of `AbstractArray` intended to include all arrays that are -laid out at regular offsets in memory, and which can therefore be passed to external C and Fortran -functions expecting this memory layout. Subtypes should provide a [`strides(A)`](@ref) method -that returns a tuple of "strides" for each dimension; a provided [`stride(A,k)`](@ref) method accesses -the `k`th element within this tuple. Increasing the index of dimension `k` by `1` should -increase the index `i` of [`getindex(A,i)`](@ref) by [`stride(A,k)`](@ref). If a pointer conversion -method [`Base.unsafe_convert(Ptr{T}, A)`](@ref) is provided, the memory layout should correspond -in the same way to these strides. More concrete examples can be found within the [interface guide -for strided arrays](@ref man-interface-strided-arrays). - -The [`Array`](@ref) type is a specific instance of `DenseArray` where elements are stored in column-major -order (see additional notes in [Performance Tips](@ref man-performance-tips)). [`Vector`](@ref) and [`Matrix`](@ref) are aliases for -the 1-d and 2-d cases. Specific operations such as scalar indexing, assignment, and a few other -basic storage-specific operations are all that have to be implemented for [`Array`](@ref), so -that the rest of the array library can be implemented in a generic manner. +`DenseArray` is an abstract subtype of `AbstractArray` intended to include all arrays where +elements are stored contiguously in column-major order (see additional notes in +[Performance Tips](@ref man-performance-tips)). The [`Array`](@ref) type is a specific instance +of `DenseArray` [`Vector`](@ref) and [`Matrix`](@ref) are aliases for the 1-d and 2-d cases. +Very few operations are implemented specifically for `Array` beyond those that are required +for all `AbstractArrays`s; much of the array library is implemented in a generic +manner that allows all custom arrays to behave similarly. `SubArray` is a specialization of `AbstractArray` that performs indexing by reference rather than by copying. A `SubArray` is created with the [`view`](@ref) function, which is called the same @@ -722,9 +714,20 @@ array indirectly. By putting the [`@views`](@ref) macro in front of an expressi block of code, any `array[...]` slice in that expression will be converted to create a `SubArray` view instead. -`StridedVector` and `StridedMatrix` are convenient aliases defined to make it possible for Julia -to call a wider range of BLAS and LAPACK functions by passing them either [`Array`](@ref) or -`SubArray` objects, and thus saving inefficiencies from memory allocation and copying. +A "strided" array is stored in memory with elements laid out in regular offsets such that +an instance with a supported `isbits` element type can be passed to +external C and Fortran functions that expect this memory layout. Strided arrays +must define a [`strides(A)`](@ref) method that returns a tuple of "strides" for each dimension; a +provided [`stride(A,k)`](@ref) method accesses the `k`th element within this tuple. Increasing the +index of dimension `k` by `1` should increase the index `i` of [`getindex(A,i)`](@ref) by +[`stride(A,k)`](@ref). If a pointer conversion method [`Base.unsafe_convert(Ptr{T}, A)`](@ref) is +provided, the memory layout must correspond in the same way to these strides. `DenseArray` is a +very specific example of a strided array where the elements are arranged contiguously, thus it +provides its subtypes with the approporiate definition of `strides`. More concrete examples +can be found within the [interface guide for strided arrays](@ref man-interface-strided-arrays). +`StridedVector` and `StridedMatrix` are convenient aliases for many of the builtin array types that +are considered strided arrays, allowing them to dispatch to select specialized implementations that +call highly tuned and optimized BLAS and LAPACK functions using just the pointer and strides. The following example computes the QR decomposition of a small section of a larger array, without creating any temporaries, and by calling the appropriate LAPACK function with the right leading diff --git a/codex/manual/documentation.md b/codex/manual/documentation.md index dbc068c..8118e39 100644 --- a/codex/manual/documentation.md +++ b/codex/manual/documentation.md @@ -338,7 +338,7 @@ function f end f ``` -Adds docstring `"..."` to function `f`. The first version is the preferred syntax, however both +Adds docstring `"..."` to the function `f`. The first version is the preferred syntax, however both are equivalent. ```julia @@ -354,7 +354,7 @@ end f(x) ``` -Adds docstring `"..."` to the `Method` `f(::Any)`. +Adds docstring `"..."` to the method `f(::Any)`. ```julia "..." diff --git a/codex/manual/embedding.md b/codex/manual/embedding.md index fcf0d11..54cabeb 100644 --- a/codex/manual/embedding.md +++ b/codex/manual/embedding.md @@ -288,7 +288,7 @@ To keep things simple, we start with a 1D array. Creating an array containing Fl of length 10 is done by: ```c -jl_value_t* array_type = jl_apply_array_type(jl_float64_type, 1); +jl_value_t* array_type = jl_apply_array_type((jl_value_t*)jl_float64_type, 1); jl_array_t* x = jl_alloc_array_1d(array_type, 10); ``` diff --git a/codex/manual/modules.md b/codex/manual/modules.md index bb7c0f2..1442f89 100644 --- a/codex/manual/modules.md +++ b/codex/manual/modules.md @@ -221,7 +221,7 @@ versions of modules to reduce this time. To create an incremental precompiled module file, add `__precompile__()` at the top of your module file (before the `module` starts). This will cause it to be automatically compiled the first time it is imported. Alternatively, you can manually call `Base.compilecache(modulename)`. The resulting -cache files will be stored in `Base.LOAD_CACHE_PATH[1]`. Subsequently, the module is automatically +cache files will be stored in `DEPOT_PATH[1]/compiled/`. Subsequently, the module is automatically recompiled upon `import` whenever any of its dependencies change; dependencies are modules it imports, the Julia build, files it includes, or explicit dependencies declared by `include_dependency(path)` in the module file(s). diff --git a/codex/manual/parallel-computing.md b/codex/manual/parallel-computing.md index 195d039..876ca90 100644 --- a/codex/manual/parallel-computing.md +++ b/codex/manual/parallel-computing.md @@ -1346,8 +1346,8 @@ in future releases. ## Multi-Threading (Experimental) -In addition to tasks, remote calls, and remote references, Julia from `v0.5` forwards will natively -support multi-threading. Note that this section is experimental and the interfaces may change +In addition to tasks, remote calls, and remote references, Julia from `v0.5` forwards natively +supports multi-threading. Note that this section is experimental and the interfaces may change in the future. ### Setup @@ -1505,6 +1505,96 @@ julia> acc[] `UInt64`, `UInt128`, `Float16`, `Float32`, and `Float64`. Additionally, `Int128` and `UInt128` are not supported on AAarch32 and ppc64le. +When using multi-threading we have to be careful when using functions that are not +[pure](https://en.wikipedia.org/wiki/Pure_function) as we might get a wrong answer. +For instance functions that have their +[name ending with `!`](https://docs.julialang.org/en/latest/manual/style-guide/#Append-!-to-names-of-functions-that-modify-their-arguments-1) +by convention modify their arguments and thus are not pure. However, there are +functions that have side effects and their name does not end with `!`. For +instance [`findfirst(regex, str)`](@Ref) mutates its `regex` argument or +[`rand()`](@Ref) changes `Base.GLOBAL_RNG` : + +```julia-repl +julia> using Base.Threads + +julia> nthreads() +4 + +julia> function f() + s = repeat(["123", "213", "231"], outer=1000) + x = similar(s, Int) + rx = r"1" + @threads for i in 1:3000 + x[i] = findfirst(rx, s[i]).start + end + count(v -> v == 1, x) + end +f (generic function with 1 method) + +julia> f() # the correct result is 1000 +1017 + +julia> function g() + a = zeros(1000) + @threads for i in 1:1000 + a[i] = rand() + end + length(unique(a)) + end +g (generic function with 1 method) + +julia> srand(1); g() # the result for a single thread is 1000 +781 +``` + +In such cases one should redesign the code to avoid the possibility of a race condition or use +[synchronization primitives](https://docs.julialang.org/en/latest/base/multi-threading/#Synchronization-Primitives-1). + +For example in order to fix `findfirst` example above one needs to have a +separate copy of `rx` variable for each thread: + +```julia-repl +julia> function f_fix() + s = repeat(["123", "213", "231"], outer=1000) + x = similar(s, Int) + rx = [Regex("1") for i in 1:nthreads()] + @threads for i in 1:3000 + x[i] = findfirst(rx[threadid()], s[i]).start + end + count(v -> v == 1, x) + end +f_fix (generic function with 1 method) + +julia> f_fix() +1000 +``` + +We now use `Regex("1")` instead of `r"1"` to make sure that Julia +creates separate instances of `Regex` object for each entry of `rx` vector. + +The case of `rand` is a bit more complex as we have to ensure that each thread +uses non-overlapping pseudorandom number sequences. This can be simply ensured +by using [`randjump`](@Ref) function: + + +```julia-repl +julia> function g_fix(r) + a = zeros(1000) + @threads for i in 1:1000 + a[i] = rand(r[threadid()]) + end + length(unique(a)) + end +g_fix (generic function with 1 method) + +julia> r = randjump(MersenneTwister(1), big(10)^20, nthreads()); +julia> g_fix(r) +1000 +``` + +We pass `r` vector to `g_fix` as generating several RGNs is an expensive +operation so we do not want to repeat it every time we run the function. + ## @threadcall (Experimental) All I/O tasks, timers, REPL commands, etc are multiplexed onto a single OS thread via an event diff --git a/codex/manual/style-guide.md b/codex/manual/style-guide.md index cb59a41..a62f853 100644 --- a/codex/manual/style-guide.md +++ b/codex/manual/style-guide.md @@ -20,7 +20,7 @@ on global variables (aside from constants like [`pi`](@ref)). Code should be as generic as possible. Instead of writing: ```julia -convert(Complex{Float64}, x) +Complex{Float64}(x) ``` it's better to use available generic functions: diff --git a/codex/stdlib/Base64.md b/codex/stdlib/Base64.md index 02e7e6b..b179de0 100644 --- a/codex/stdlib/Base64.md +++ b/codex/stdlib/Base64.md @@ -1,5 +1,9 @@ # Base64 +```@meta +DocTestSetup = :(using Base64) +``` + ```@docs Base64.Base64EncodePipe Base64.base64encode @@ -7,3 +11,7 @@ Base64.Base64DecodePipe Base64.base64decode Base64.stringmime ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/codex/stdlib/Dates.md b/codex/stdlib/Dates.md index 40852af..3abee48 100644 --- a/codex/stdlib/Dates.md +++ b/codex/stdlib/Dates.md @@ -1,5 +1,9 @@ # [Dates and Time](@id stdlib-dates) +```@meta +DocTestSetup = :(using Dates) +``` + Functionality to handle time and dates is defined in the standard library module `Dates`. You'll need to import the module using `import Dates` and prefix each function call with an explicit `Dates.`, e.g. `Dates.dayofweek(dt)`. Alternatively, you can write @@ -192,3 +196,7 @@ Months of the Year: | `October` | `Oct` | 10 | | `November` | `Nov` | 11 | | `December` | `Dec` | 12 | + +```@meta +DocTestSetup = nothing +``` diff --git a/codex/stdlib/DelimitedFiles.md b/codex/stdlib/DelimitedFiles.md index 7cd38cb..2a343d5 100644 --- a/codex/stdlib/DelimitedFiles.md +++ b/codex/stdlib/DelimitedFiles.md @@ -1,5 +1,9 @@ # Delimited Files +```@meta +DocTestSetup = :(using DelimitedFiles) +``` + ```@docs DelimitedFiles.readdlm(::Any, ::Char, ::Type, ::Char) DelimitedFiles.readdlm(::Any, ::Char, ::Char) @@ -9,3 +13,7 @@ DelimitedFiles.readdlm(::Any, ::Type) DelimitedFiles.readdlm(::Any) DelimitedFiles.writedlm ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/codex/stdlib/Distributed.md b/codex/stdlib/Distributed.md index 47d4c23..da0b822 100644 --- a/codex/stdlib/Distributed.md +++ b/codex/stdlib/Distributed.md @@ -1,5 +1,9 @@ # Distributed Computing +```@meta +DocTestSetup = :(using Distributed) +``` + ```@docs Distributed.addprocs Distributed.nprocs @@ -67,3 +71,7 @@ Distributed.init_worker Distributed.start_worker Distributed.process_messages ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/codex/stdlib/InteractiveUtils.md b/codex/stdlib/InteractiveUtils.md index 39555d3..656780c 100644 --- a/codex/stdlib/InteractiveUtils.md +++ b/codex/stdlib/InteractiveUtils.md @@ -1,5 +1,9 @@ # Interactive Utilities +```@meta +DocTestSetup = :(using InteractiveUtils) +``` + ```@docs InteractiveUtils.apropos InteractiveUtils.varinfo @@ -23,3 +27,7 @@ InteractiveUtils.@code_llvm InteractiveUtils.code_native InteractiveUtils.@code_native ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/codex/stdlib/IterativeEigensolvers.md b/codex/stdlib/IterativeEigensolvers.md index 664f782..62dadc7 100644 --- a/codex/stdlib/IterativeEigensolvers.md +++ b/codex/stdlib/IterativeEigensolvers.md @@ -1,5 +1,9 @@ # [Iterative Eigensolvers](@id lib-itereigen) +```@meta +DocTestSetup = :(using IterativeEigensolvers) +``` + Julia provides bindings to [ARPACK](http://www.caam.rice.edu/software/ARPACK/), which can be used to perform iterative solutions for eigensystems (using [`eigs`](@ref)) or singular value decompositions (using [`svds`](@ref)). @@ -207,3 +211,7 @@ IterativeEigensolvers.eigs(::Any) IterativeEigensolvers.eigs(::Any, ::Any) IterativeEigensolvers.svds ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/codex/stdlib/LinearAlgebra.md b/codex/stdlib/LinearAlgebra.md index 00d677f..d931b8c 100644 --- a/codex/stdlib/LinearAlgebra.md +++ b/codex/stdlib/LinearAlgebra.md @@ -1,5 +1,9 @@ # Linear Algebra +```@meta +DocTestSetup = :(using LinearAlgebra) +``` + In addition to (and as part of) its support for multi-dimensional arrays, Julia provides native implementations of many common and useful linear algebra operations. Basic operations, such as [`trace`](@ref), [`det`](@ref), and [`inv`](@ref) are all supported: @@ -368,7 +372,6 @@ LinearAlgebra.logabsdet Base.inv(::AbstractMatrix) LinearAlgebra.pinv LinearAlgebra.nullspace -Base.repmat Base.kron LinearAlgebra.linreg LinearAlgebra.exp(::StridedMatrix{<:LinearAlgebra.BlasFloat}) @@ -620,3 +623,7 @@ LinearAlgebra.LAPACK.trsen! LinearAlgebra.LAPACK.tgsen! LinearAlgebra.LAPACK.trsyl! ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/codex/stdlib/Mmap.md b/codex/stdlib/Mmap.md index ada88b1..9bd623d 100644 --- a/codex/stdlib/Mmap.md +++ b/codex/stdlib/Mmap.md @@ -1,7 +1,15 @@ # Memory-mapped I/O +```@meta +DocTestSetup = :(using Mmap) +``` + ```@docs Mmap.Anonymous Mmap.mmap Mmap.sync! ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/codex/stdlib/Pkg.md b/codex/stdlib/Pkg.md index b7cd686..47f3f96 100644 --- a/codex/stdlib/Pkg.md +++ b/codex/stdlib/Pkg.md @@ -1,5 +1,9 @@ # Package Manager Functions +```@meta +DocTestSetup = :(using Pkg) +``` + All package manager functions are defined in the `Pkg` module. None of the `Pkg` module's functions are exported; to use them, you'll need to prefix each function call with an explicit `Pkg.`, e.g. [`Pkg.status()`](@ref) or [`Pkg.dir()`](@ref). @@ -28,3 +32,7 @@ Pkg.build Pkg.test Pkg.dependents ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/codex/stdlib/Printf.md b/codex/stdlib/Printf.md index 828e527..de79d5c 100644 --- a/codex/stdlib/Printf.md +++ b/codex/stdlib/Printf.md @@ -1,6 +1,14 @@ # Printf +```@meta +DocTestSetup = :(using Printf) +``` + ```@docs Printf.@printf Printf.@sprintf ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/codex/stdlib/Random.md b/codex/stdlib/Random.md index 0ef892b..5607ba0 100644 --- a/codex/stdlib/Random.md +++ b/codex/stdlib/Random.md @@ -1,5 +1,9 @@ # Random Numbers +```@meta +DocTestSetup = :(using Random) +``` + Random number generation in Julia uses the [Mersenne Twister library](http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/#dSFMT) via `MersenneTwister` objects. Julia has a global RNG, which is used by default. Other RNG types can be plugged in by inheriting the `AbstractRNG` type; they can then be used to have multiple @@ -41,3 +45,7 @@ Random.randcycle! Random.shuffle Random.shuffle! ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/codex/stdlib/SparseArrays.md b/codex/stdlib/SparseArrays.md index d55c7f0..34dd58c 100644 --- a/codex/stdlib/SparseArrays.md +++ b/codex/stdlib/SparseArrays.md @@ -1,5 +1,9 @@ # Sparse Arrays +```@meta +DocTestSetup = :(using SparseArrays) +``` + Julia has support for sparse vectors and [sparse matrices](https://en.wikipedia.org/wiki/Sparse_matrix) in the `SparseArrays` stdlib module. Sparse arrays are arrays that contain enough zeros that storing them in a special data structure leads to savings in space and execution time, @@ -218,3 +222,7 @@ SparseArrays.dropzeros SparseArrays.permute permute!{Tv, Ti, Tp <: Integer, Tq <: Integer}(::SparseMatrixCSC{Tv,Ti}, ::SparseMatrixCSC{Tv,Ti}, ::AbstractArray{Tp,1}, ::AbstractArray{Tq,1}) ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/codex/stdlib/Test.md b/codex/stdlib/Test.md index 32ec604..4211071 100644 --- a/codex/stdlib/Test.md +++ b/codex/stdlib/Test.md @@ -1,9 +1,7 @@ # Unit Testing ```@meta -DocTestSetup = quote - using Test -end +DocTestSetup = :(using Test) ``` ## Testing Base Julia diff --git a/codex/stdlib/UUIDs.md b/codex/stdlib/UUIDs.md index 616ac63..ddc490f 100644 --- a/codex/stdlib/UUIDs.md +++ b/codex/stdlib/UUIDs.md @@ -1,7 +1,15 @@ # UUIDs +```@meta +DocTestSetup = :(using UUIDs) +``` + ```@docs UUIDs.uuid1 UUIDs.uuid4 UUIDs.uuid_version ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/codex/stdlib/Unicode.md b/codex/stdlib/Unicode.md index aba9d80..474629d 100644 --- a/codex/stdlib/Unicode.md +++ b/codex/stdlib/Unicode.md @@ -1,7 +1,15 @@ # Unicode +```@meta +DocTestSetup = :(using Unicode) +``` + ```@docs Unicode.isassigned Unicode.normalize Unicode.graphemes ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/codex/stdlib/base64.md b/codex/stdlib/base64.md index 02e7e6b..b179de0 100644 --- a/codex/stdlib/base64.md +++ b/codex/stdlib/base64.md @@ -1,5 +1,9 @@ # Base64 +```@meta +DocTestSetup = :(using Base64) +``` + ```@docs Base64.Base64EncodePipe Base64.base64encode @@ -7,3 +11,7 @@ Base64.Base64DecodePipe Base64.base64decode Base64.stringmime ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/codex/stdlib/dates.md b/codex/stdlib/dates.md index 40852af..3abee48 100644 --- a/codex/stdlib/dates.md +++ b/codex/stdlib/dates.md @@ -1,5 +1,9 @@ # [Dates and Time](@id stdlib-dates) +```@meta +DocTestSetup = :(using Dates) +``` + Functionality to handle time and dates is defined in the standard library module `Dates`. You'll need to import the module using `import Dates` and prefix each function call with an explicit `Dates.`, e.g. `Dates.dayofweek(dt)`. Alternatively, you can write @@ -192,3 +196,7 @@ Months of the Year: | `October` | `Oct` | 10 | | `November` | `Nov` | 11 | | `December` | `Dec` | 12 | + +```@meta +DocTestSetup = nothing +``` diff --git a/codex/stdlib/delimitedfiles.md b/codex/stdlib/delimitedfiles.md index 7cd38cb..2a343d5 100644 --- a/codex/stdlib/delimitedfiles.md +++ b/codex/stdlib/delimitedfiles.md @@ -1,5 +1,9 @@ # Delimited Files +```@meta +DocTestSetup = :(using DelimitedFiles) +``` + ```@docs DelimitedFiles.readdlm(::Any, ::Char, ::Type, ::Char) DelimitedFiles.readdlm(::Any, ::Char, ::Char) @@ -9,3 +13,7 @@ DelimitedFiles.readdlm(::Any, ::Type) DelimitedFiles.readdlm(::Any) DelimitedFiles.writedlm ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/codex/stdlib/distributed.md b/codex/stdlib/distributed.md index 47d4c23..da0b822 100644 --- a/codex/stdlib/distributed.md +++ b/codex/stdlib/distributed.md @@ -1,5 +1,9 @@ # Distributed Computing +```@meta +DocTestSetup = :(using Distributed) +``` + ```@docs Distributed.addprocs Distributed.nprocs @@ -67,3 +71,7 @@ Distributed.init_worker Distributed.start_worker Distributed.process_messages ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/codex/stdlib/iterativeeigensolvers.md b/codex/stdlib/iterativeeigensolvers.md index 664f782..62dadc7 100644 --- a/codex/stdlib/iterativeeigensolvers.md +++ b/codex/stdlib/iterativeeigensolvers.md @@ -1,5 +1,9 @@ # [Iterative Eigensolvers](@id lib-itereigen) +```@meta +DocTestSetup = :(using IterativeEigensolvers) +``` + Julia provides bindings to [ARPACK](http://www.caam.rice.edu/software/ARPACK/), which can be used to perform iterative solutions for eigensystems (using [`eigs`](@ref)) or singular value decompositions (using [`svds`](@ref)). @@ -207,3 +211,7 @@ IterativeEigensolvers.eigs(::Any) IterativeEigensolvers.eigs(::Any, ::Any) IterativeEigensolvers.svds ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/codex/stdlib/linearalgebra.md b/codex/stdlib/linearalgebra.md index 00d677f..d931b8c 100644 --- a/codex/stdlib/linearalgebra.md +++ b/codex/stdlib/linearalgebra.md @@ -1,5 +1,9 @@ # Linear Algebra +```@meta +DocTestSetup = :(using LinearAlgebra) +``` + In addition to (and as part of) its support for multi-dimensional arrays, Julia provides native implementations of many common and useful linear algebra operations. Basic operations, such as [`trace`](@ref), [`det`](@ref), and [`inv`](@ref) are all supported: @@ -368,7 +372,6 @@ LinearAlgebra.logabsdet Base.inv(::AbstractMatrix) LinearAlgebra.pinv LinearAlgebra.nullspace -Base.repmat Base.kron LinearAlgebra.linreg LinearAlgebra.exp(::StridedMatrix{<:LinearAlgebra.BlasFloat}) @@ -620,3 +623,7 @@ LinearAlgebra.LAPACK.trsen! LinearAlgebra.LAPACK.tgsen! LinearAlgebra.LAPACK.trsyl! ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/codex/stdlib/mmap.md b/codex/stdlib/mmap.md index ada88b1..9bd623d 100644 --- a/codex/stdlib/mmap.md +++ b/codex/stdlib/mmap.md @@ -1,7 +1,15 @@ # Memory-mapped I/O +```@meta +DocTestSetup = :(using Mmap) +``` + ```@docs Mmap.Anonymous Mmap.mmap Mmap.sync! ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/codex/stdlib/printf.md b/codex/stdlib/printf.md index 828e527..de79d5c 100644 --- a/codex/stdlib/printf.md +++ b/codex/stdlib/printf.md @@ -1,6 +1,14 @@ # Printf +```@meta +DocTestSetup = :(using Printf) +``` + ```@docs Printf.@printf Printf.@sprintf ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/codex/stdlib/random.md b/codex/stdlib/random.md index 0ef892b..5607ba0 100644 --- a/codex/stdlib/random.md +++ b/codex/stdlib/random.md @@ -1,5 +1,9 @@ # Random Numbers +```@meta +DocTestSetup = :(using Random) +``` + Random number generation in Julia uses the [Mersenne Twister library](http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/#dSFMT) via `MersenneTwister` objects. Julia has a global RNG, which is used by default. Other RNG types can be plugged in by inheriting the `AbstractRNG` type; they can then be used to have multiple @@ -41,3 +45,7 @@ Random.randcycle! Random.shuffle Random.shuffle! ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/codex/stdlib/sparsearrays.md b/codex/stdlib/sparsearrays.md index d55c7f0..34dd58c 100644 --- a/codex/stdlib/sparsearrays.md +++ b/codex/stdlib/sparsearrays.md @@ -1,5 +1,9 @@ # Sparse Arrays +```@meta +DocTestSetup = :(using SparseArrays) +``` + Julia has support for sparse vectors and [sparse matrices](https://en.wikipedia.org/wiki/Sparse_matrix) in the `SparseArrays` stdlib module. Sparse arrays are arrays that contain enough zeros that storing them in a special data structure leads to savings in space and execution time, @@ -218,3 +222,7 @@ SparseArrays.dropzeros SparseArrays.permute permute!{Tv, Ti, Tp <: Integer, Tq <: Integer}(::SparseMatrixCSC{Tv,Ti}, ::SparseMatrixCSC{Tv,Ti}, ::AbstractArray{Tp,1}, ::AbstractArray{Tq,1}) ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/codex/stdlib/test.md b/codex/stdlib/test.md index 32ec604..4211071 100644 --- a/codex/stdlib/test.md +++ b/codex/stdlib/test.md @@ -1,9 +1,7 @@ # Unit Testing ```@meta -DocTestSetup = quote - using Test -end +DocTestSetup = :(using Test) ``` ## Testing Base Julia diff --git a/codex/stdlib/unicode.md b/codex/stdlib/unicode.md index aba9d80..474629d 100644 --- a/codex/stdlib/unicode.md +++ b/codex/stdlib/unicode.md @@ -1,7 +1,15 @@ # Unicode +```@meta +DocTestSetup = :(using Unicode) +``` + ```@docs Unicode.isassigned Unicode.normalize Unicode.graphemes ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/make.jl b/make.jl index 41b1b08..fa66f20 100644 --- a/make.jl +++ b/make.jl @@ -145,6 +145,6 @@ makedocs( authors = "The Julia Project", analytics = "UA-110655381-2", # juliakorea 추척 ID pages = PAGES, - html_prettyurls = true, + html_prettyurls = !("local" in ARGS), html_canonical = "https://juliakorea.github.io/ko/latest/" ) diff --git a/src/NEWS.md b/src/NEWS.md index fde0828..85d84a8 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -153,7 +153,7 @@ Language changes expressions) ([#23885](https://github.com/JuliaLang/julia/issues/23885)). * The `+` and `-` methods for `Number` and `UniformScaling` are not ambiguous anymore since `+` - and `-` no longer do automatic broadcasting. Hence the methods for `UniformScaling` and `Number` are + and `-` no longer do automatic broadcasting. Hence, the methods for `UniformScaling` and `Number` are no longer deprecated ([#23923](https://github.com/JuliaLang/julia/issues/23923)). * The keyword `importall` is deprecated. Use `using` and/or individual `import` statements @@ -198,6 +198,11 @@ Breaking changes This section lists changes that do not have deprecation warnings. + * `replace(s::AbstractString, pat=>repl)` for function `repl` arguments formerly + passed a substring to `repl` in all cases. It now passes substrings for + string patterns `pat`, but a `Char` for character patterns (when `pat` is a + `Char`, collection of `Char`, or a character predicate) ([#25815](https://github.com/JuliaLang/julia/issues/25815)). + * `readuntil` now does *not* include the delimiter in its result, matching the behavior of `readline`. Pass `keep=true` to get the old behavior ([#25633](https://github.com/JuliaLang/julia/issues/25633)). @@ -214,7 +219,7 @@ This section lists changes that do not have deprecation warnings. * `finalizer(function, object)` now returns `object` rather than `nothing` ([#24679](https://github.com/JuliaLang/julia/issues/24679)). - * The constructor of `SubString` now checks if the requsted view range + * The constructor of `SubString` now checks if the requested view range is defined by valid indices in the parent `AbstractString` ([#22511](https://github.com/JuliaLang/julia/issues/22511)). * Macro calls with `for` expressions are now parsed as generators inside @@ -247,7 +252,7 @@ This section lists changes that do not have deprecation warnings. returned ([#21825](https://github.com/JuliaLang/julia/issues/21825)). * Using `ARGS` within the ~/.juliarc.jl or within a .jl file loaded with `--load` will no - longer contain the script name as the first argument. Instead the script name will be + longer contain the script name as the first argument. Instead, the script name will be assigned to `PROGRAM_FILE`. ([#22092](https://github.com/JuliaLang/julia/issues/22092)) * The format for a `ClusterManager` specifying the cookie on the command line is now @@ -325,7 +330,7 @@ This section lists changes that do not have deprecation warnings. * The `openspecfun` library is no longer built and shipped with Julia, as it is no longer used internally ([#22390](https://github.com/JuliaLang/julia/issues/22390)). - * All loaded packges used to have bindings in `Main` (e.g. `Main.Package`). This is no + * All loaded packages used to have bindings in `Main` (e.g. `Main.Package`). This is no longer the case; now bindings will only exist for packages brought into scope by typing `using Package` or `import Package` ([#17997](https://github.com/JuliaLang/julia/issues/17997)). @@ -389,7 +394,7 @@ This section lists changes that do not have deprecation warnings. now take and/or return the same type of indices as `keys`/`pairs` for `AbstractArray`, `AbstractDict`, `AbstractString`, `Tuple` and `NamedTuple` objects ([#24774](https://github.com/JuliaLang/julia/issues/24774), [#25545](https://github.com/JuliaLang/julia/issues/25545)). In particular, this means that they use `CartesianIndex` objects for matrices - and higher-dimensional arrays insted of linear indices as was previously the case. + and higher-dimensional arrays instead of linear indices as was previously the case. Use `LinearIndices(a)[findall(f, a)]` and similar constructs to compute linear indices. * The `find*` functions which return scalars, i.e. `findnext`, `findprev`, `findfirst`, @@ -496,9 +501,6 @@ Library improvements git repo. Additionally, the argument order was changed to be consistent with the git command line tool ([#22062](https://github.com/JuliaLang/julia/issues/22062)). - * `logspace` now accepts a `base` keyword argument to specify the base of the logarithmic - range. The base defaults to 10 ([#22310](https://github.com/JuliaLang/julia/issues/22310)). - * Added `unique!` which is an inplace version of `unique` ([#20549](https://github.com/JuliaLang/julia/issues/20549)). * `@test isequal(x, y)` and `@test isapprox(x, y)` now prints an evaluated expression when @@ -581,7 +583,7 @@ Library improvements Use `unique` to get the old behavior. * The type `LinearIndices` has been added, providing conversion from - cartesian incices to linear indices using the normal indexing operation. ([#24715](https://github.com/JuliaLang/julia/issues/24715)) + cartesian indices to linear indices using the normal indexing operation. ([#24715](https://github.com/JuliaLang/julia/issues/24715)) * `IdDict{K,V}` replaces `ObjectIdDict`. It has type parameters like other `AbstractDict` subtypes and its constructors mirror the @@ -590,6 +592,9 @@ Library improvements * `IOBuffer` can take the `sizehint` keyword argument to suggest a capacity of the buffer ([#25944](https://github.com/JuliaLang/julia/issues/25944)). + * `trunc`, `floor`, `ceil`, `round`, and `signif` specify `base` using a + keyword argument. ([#26156](https://github.com/JuliaLang/julia/issues/26156)) + Compiler/Runtime improvements ----------------------------- @@ -992,8 +997,7 @@ Deprecated or removed * `ismatch(regex, str)` has been deprecated in favor of `contains(str, regex)` ([#24673](https://github.com/JuliaLang/julia/issues/24673)). - * `linspace` and `logspace` now require an explicit number of elements to be - supplied rather than defaulting to `50`([#24794](https://github.com/JuliaLang/julia/issues/24794), [#24805](https://github.com/JuliaLang/julia/issues/24805)). + * `matchall` has been deprecated in favor of `collect(m.match for m in eachmatch(r, s))` ([#26071](https://github.com/JuliaLang/julia/issues/26071)). * `similar(::Associative)` has been deprecated in favor of `empty(::Associative)`, and `similar(::Associative, ::Pair{K, V})` has been deprecated in favour of diff --git a/src/base/io-network.md b/src/base/io-network.md index ec69c67..396c0ef 100644 --- a/src/base/io-network.md +++ b/src/base/io-network.md @@ -93,7 +93,7 @@ Base.Multimedia.display Base.Multimedia.redisplay Base.Multimedia.displayable Base.show(::Any, ::Any, ::Any) -Base.Multimedia.mimewritable +Base.Multimedia.showable Base.repr(::Any, ::Any) ``` @@ -107,7 +107,7 @@ define a function `display(d::D, ::MIME"mime", x) = ...` that displays `x` as th usually by calling [`show(io, mime, x)`](@ref) or [`repr(io, mime, x)`](@ref). A `MethodError` should be thrown if `x` cannot be displayed as that MIME type; this is automatic if one calls `show` or `repr`. Finally, one should define a function -`display(d::D, x)` that queries [`mimewritable(mime, x)`](@ref) for the `mime` types supported by `D` +`display(d::D, x)` that queries [`showable(mime, x)`](@ref) for the `mime` types supported by `D` and displays the "best" one; a `MethodError` should be thrown if no supported MIME types are found for `x`. Similarly, some subtypes may wish to override [`redisplay(d::D, ...)`](@ref Base.Multimedia.redisplay). (Again, one should `import Base.display` to add new methods to `display`.) The return values of these functions are diff --git a/src/base/strings.md b/src/base/strings.md index f173e13..d71e7ef 100644 --- a/src/base/strings.md +++ b/src/base/strings.md @@ -26,7 +26,6 @@ Base.isvalid(::Any, ::Any) Base.isvalid(::AbstractString, ::Integer) Base.match Base.eachmatch -Base.matchall Base.isless(::AbstractString, ::AbstractString) Base.:(==)(::AbstractString, ::AbstractString) Base.cmp(::AbstractString, ::AbstractString) diff --git a/src/manual/arrays.md b/src/manual/arrays.md index 2139587..cdd961d 100644 --- a/src/manual/arrays.md +++ b/src/manual/arrays.md @@ -644,19 +644,13 @@ Julia에서 기본 배열 타입은 추상 타입인 [`AbstractArray{T,N}`](@ref For more details on defining custom `AbstractArray` implementations, see the [array interface guide in the interfaces chapter](@ref man-interface-array). -`DenseArray`는 `AbstractArray`의 추상 서브타입으로, 원소가 메모리에 규칙적인 오프셋으로 배치된 배열 모두를 포함하고자 만들어졌으며, -따라서 이러한 메모리 레이아웃을 기대하는 외부의 C나 Fortran함수에 전달될 수도 있다. -Subtypes should provide a [`strides(A)`](@ref) method -that returns a tuple of "strides" for each dimension; a provided [`stride(A,k)`](@ref) method accesses -the `k`th element within this tuple. -`k`차원의 인덱스를 1만큼 늘리면 [`getindex(A,i)`](@ref)의 인덱스 `i`를 [`stride(A,k)`](@ref)만큼 늘리는 것과 동일하다. -포인터 변환 메소드 [`Base.unsafe_convert(Ptr{T}, A)`](@ref)가 제공된다면, 메모리 레이아웃 또한 같은 식으로 스트라이드를 따라야 한다. -More concrete examples can be found within the [interface guide for strided arrays](@ref man-interface-strided-arrays). - -[`Array`](@ref) 타입은 `DenseArray`의 구체적 인스턴스로서, 원소들은 열 우선 순서(column-major order)로 저장된다. -([성능 향상 팁](@ref man-performance-tips) 참조) -[`Vector`](@ref)와 [`Matrix`](@ref)는 1차원과 2차원 [`Array`](@ref)의 앨리어스이다. -배열 라이브러리의 다른 부분이 일반적인 방식으로 구현될 수 있도록, 스칼라 인덱싱과 대입 및 몇개의 기본적인 스토리지 특정 연산이 [`Array`](@ref)에 구현되어야 한다. +`DenseArray` is an abstract subtype of `AbstractArray` intended to include all arrays where +elements are stored contiguously in column-major order (see additional notes in +[Performance Tips](@ref man-performance-tips)). The [`Array`](@ref) type is a specific instance +of `DenseArray` [`Vector`](@ref) and [`Matrix`](@ref) are aliases for the 1-d and 2-d cases. +Very few operations are implemented specifically for `Array` beyond those that are required +for all `AbstractArrays`s; much of the array library is implemented in a generic +manner that allows all custom arrays to behave similarly. `SubArray`는 복사가 아닌 참조로 인덱싱을 수행하는 `AbstractArray`의 특수화이다. `SubArray`는 [`view`](@ref)함수로 생성되는데, 호출 방식은 [`getindex`](@ref)와 같다. @@ -664,7 +658,20 @@ More concrete examples can be found within the [interface guide for strided arra [`view`](@ref)는 입력 인덱스 벡터를 `SubArray` 객체에 저장하는데, 이는 참조되는 원 배열을 나중에 간접적으로 인덱싱 하는데에 쓰인다. [`@views`](@ref) 매크로를 표현식이나 코드 블록 앞에 둠으로써, 그 표현식 내의 모든 `array[...]` 슬라이스가 `SubArray` 뷰를 생성하도록 할 수 있다. -`StridedVector`와 `StridedMatrix`는 Julia가 BLAS와 LAPACK 함수를 호출 할 때 [`Array`](@ref) 혹은 `SubArray` 객체를 전달할 수 있게 해주는 편리한 앨리어스이며, 따라서 메모리 할당과 복사에 의한 비효율성을 줄일 수 있도록 해준다. +A "strided" array is stored in memory with elements laid out in regular offsets such that +an instance with a supported `isbits` element type can be passed to +external C and Fortran functions that expect this memory layout. Strided arrays +must define a [`strides(A)`](@ref) method that returns a tuple of "strides" for each dimension; a +provided [`stride(A,k)`](@ref) method accesses the `k`th element within this tuple. Increasing the +index of dimension `k` by `1` should increase the index `i` of [`getindex(A,i)`](@ref) by +[`stride(A,k)`](@ref). If a pointer conversion method [`Base.unsafe_convert(Ptr{T}, A)`](@ref) is +provided, the memory layout must correspond in the same way to these strides. `DenseArray` is a +very specific example of a strided array where the elements are arranged contiguously, thus it +provides its subtypes with the approporiate definition of `strides`. More concrete examples +can be found within the [interface guide for strided arrays](@ref man-interface-strided-arrays). +`StridedVector` and `StridedMatrix` are convenient aliases for many of the builtin array types that +are considered strided arrays, allowing them to dispatch to select specialized implementations that +call highly tuned and optimized BLAS and LAPACK functions using just the pointer and strides. 다음 예시에서는 임시 배열을 만들지 않고 적절한 LAPACK 함수를 차원 크기와 스트라이드를 사용하여 호출하여 큰 배열의 작은 섹션의 QR 분해를 계산한다. diff --git a/src/manual/documentation.md b/src/manual/documentation.md index dbc068c..8118e39 100644 --- a/src/manual/documentation.md +++ b/src/manual/documentation.md @@ -338,7 +338,7 @@ function f end f ``` -Adds docstring `"..."` to function `f`. The first version is the preferred syntax, however both +Adds docstring `"..."` to the function `f`. The first version is the preferred syntax, however both are equivalent. ```julia @@ -354,7 +354,7 @@ end f(x) ``` -Adds docstring `"..."` to the `Method` `f(::Any)`. +Adds docstring `"..."` to the method `f(::Any)`. ```julia "..." diff --git a/src/manual/embedding.md b/src/manual/embedding.md index fcf0d11..54cabeb 100644 --- a/src/manual/embedding.md +++ b/src/manual/embedding.md @@ -288,7 +288,7 @@ To keep things simple, we start with a 1D array. Creating an array containing Fl of length 10 is done by: ```c -jl_value_t* array_type = jl_apply_array_type(jl_float64_type, 1); +jl_value_t* array_type = jl_apply_array_type((jl_value_t*)jl_float64_type, 1); jl_array_t* x = jl_alloc_array_1d(array_type, 10); ``` diff --git a/src/manual/modules.md b/src/manual/modules.md index bb7c0f2..1442f89 100644 --- a/src/manual/modules.md +++ b/src/manual/modules.md @@ -221,7 +221,7 @@ versions of modules to reduce this time. To create an incremental precompiled module file, add `__precompile__()` at the top of your module file (before the `module` starts). This will cause it to be automatically compiled the first time it is imported. Alternatively, you can manually call `Base.compilecache(modulename)`. The resulting -cache files will be stored in `Base.LOAD_CACHE_PATH[1]`. Subsequently, the module is automatically +cache files will be stored in `DEPOT_PATH[1]/compiled/`. Subsequently, the module is automatically recompiled upon `import` whenever any of its dependencies change; dependencies are modules it imports, the Julia build, files it includes, or explicit dependencies declared by `include_dependency(path)` in the module file(s). diff --git a/src/manual/parallel-computing.md b/src/manual/parallel-computing.md index 195d039..876ca90 100644 --- a/src/manual/parallel-computing.md +++ b/src/manual/parallel-computing.md @@ -1346,8 +1346,8 @@ in future releases. ## Multi-Threading (Experimental) -In addition to tasks, remote calls, and remote references, Julia from `v0.5` forwards will natively -support multi-threading. Note that this section is experimental and the interfaces may change +In addition to tasks, remote calls, and remote references, Julia from `v0.5` forwards natively +supports multi-threading. Note that this section is experimental and the interfaces may change in the future. ### Setup @@ -1505,6 +1505,96 @@ julia> acc[] `UInt64`, `UInt128`, `Float16`, `Float32`, and `Float64`. Additionally, `Int128` and `UInt128` are not supported on AAarch32 and ppc64le. +When using multi-threading we have to be careful when using functions that are not +[pure](https://en.wikipedia.org/wiki/Pure_function) as we might get a wrong answer. +For instance functions that have their +[name ending with `!`](https://docs.julialang.org/en/latest/manual/style-guide/#Append-!-to-names-of-functions-that-modify-their-arguments-1) +by convention modify their arguments and thus are not pure. However, there are +functions that have side effects and their name does not end with `!`. For +instance [`findfirst(regex, str)`](@Ref) mutates its `regex` argument or +[`rand()`](@Ref) changes `Base.GLOBAL_RNG` : + +```julia-repl +julia> using Base.Threads + +julia> nthreads() +4 + +julia> function f() + s = repeat(["123", "213", "231"], outer=1000) + x = similar(s, Int) + rx = r"1" + @threads for i in 1:3000 + x[i] = findfirst(rx, s[i]).start + end + count(v -> v == 1, x) + end +f (generic function with 1 method) + +julia> f() # the correct result is 1000 +1017 + +julia> function g() + a = zeros(1000) + @threads for i in 1:1000 + a[i] = rand() + end + length(unique(a)) + end +g (generic function with 1 method) + +julia> srand(1); g() # the result for a single thread is 1000 +781 +``` + +In such cases one should redesign the code to avoid the possibility of a race condition or use +[synchronization primitives](https://docs.julialang.org/en/latest/base/multi-threading/#Synchronization-Primitives-1). + +For example in order to fix `findfirst` example above one needs to have a +separate copy of `rx` variable for each thread: + +```julia-repl +julia> function f_fix() + s = repeat(["123", "213", "231"], outer=1000) + x = similar(s, Int) + rx = [Regex("1") for i in 1:nthreads()] + @threads for i in 1:3000 + x[i] = findfirst(rx[threadid()], s[i]).start + end + count(v -> v == 1, x) + end +f_fix (generic function with 1 method) + +julia> f_fix() +1000 +``` + +We now use `Regex("1")` instead of `r"1"` to make sure that Julia +creates separate instances of `Regex` object for each entry of `rx` vector. + +The case of `rand` is a bit more complex as we have to ensure that each thread +uses non-overlapping pseudorandom number sequences. This can be simply ensured +by using [`randjump`](@Ref) function: + + +```julia-repl +julia> function g_fix(r) + a = zeros(1000) + @threads for i in 1:1000 + a[i] = rand(r[threadid()]) + end + length(unique(a)) + end +g_fix (generic function with 1 method) + +julia> r = randjump(MersenneTwister(1), big(10)^20, nthreads()); +julia> g_fix(r) +1000 +``` + +We pass `r` vector to `g_fix` as generating several RGNs is an expensive +operation so we do not want to repeat it every time we run the function. + ## @threadcall (Experimental) All I/O tasks, timers, REPL commands, etc are multiplexed onto a single OS thread via an event diff --git a/src/manual/style-guide.md b/src/manual/style-guide.md index cb59a41..a62f853 100644 --- a/src/manual/style-guide.md +++ b/src/manual/style-guide.md @@ -20,7 +20,7 @@ on global variables (aside from constants like [`pi`](@ref)). Code should be as generic as possible. Instead of writing: ```julia -convert(Complex{Float64}, x) +Complex{Float64}(x) ``` it's better to use available generic functions: diff --git a/src/stdlib/Base64.md b/src/stdlib/Base64.md index 02e7e6b..b179de0 100644 --- a/src/stdlib/Base64.md +++ b/src/stdlib/Base64.md @@ -1,5 +1,9 @@ # Base64 +```@meta +DocTestSetup = :(using Base64) +``` + ```@docs Base64.Base64EncodePipe Base64.base64encode @@ -7,3 +11,7 @@ Base64.Base64DecodePipe Base64.base64decode Base64.stringmime ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/src/stdlib/Dates.md b/src/stdlib/Dates.md index 40852af..3abee48 100644 --- a/src/stdlib/Dates.md +++ b/src/stdlib/Dates.md @@ -1,5 +1,9 @@ # [Dates and Time](@id stdlib-dates) +```@meta +DocTestSetup = :(using Dates) +``` + Functionality to handle time and dates is defined in the standard library module `Dates`. You'll need to import the module using `import Dates` and prefix each function call with an explicit `Dates.`, e.g. `Dates.dayofweek(dt)`. Alternatively, you can write @@ -192,3 +196,7 @@ Months of the Year: | `October` | `Oct` | 10 | | `November` | `Nov` | 11 | | `December` | `Dec` | 12 | + +```@meta +DocTestSetup = nothing +``` diff --git a/src/stdlib/DelimitedFiles.md b/src/stdlib/DelimitedFiles.md index 7cd38cb..2a343d5 100644 --- a/src/stdlib/DelimitedFiles.md +++ b/src/stdlib/DelimitedFiles.md @@ -1,5 +1,9 @@ # Delimited Files +```@meta +DocTestSetup = :(using DelimitedFiles) +``` + ```@docs DelimitedFiles.readdlm(::Any, ::Char, ::Type, ::Char) DelimitedFiles.readdlm(::Any, ::Char, ::Char) @@ -9,3 +13,7 @@ DelimitedFiles.readdlm(::Any, ::Type) DelimitedFiles.readdlm(::Any) DelimitedFiles.writedlm ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/src/stdlib/Distributed.md b/src/stdlib/Distributed.md index 47d4c23..da0b822 100644 --- a/src/stdlib/Distributed.md +++ b/src/stdlib/Distributed.md @@ -1,5 +1,9 @@ # Distributed Computing +```@meta +DocTestSetup = :(using Distributed) +``` + ```@docs Distributed.addprocs Distributed.nprocs @@ -67,3 +71,7 @@ Distributed.init_worker Distributed.start_worker Distributed.process_messages ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/src/stdlib/InteractiveUtils.md b/src/stdlib/InteractiveUtils.md index 39555d3..656780c 100644 --- a/src/stdlib/InteractiveUtils.md +++ b/src/stdlib/InteractiveUtils.md @@ -1,5 +1,9 @@ # Interactive Utilities +```@meta +DocTestSetup = :(using InteractiveUtils) +``` + ```@docs InteractiveUtils.apropos InteractiveUtils.varinfo @@ -23,3 +27,7 @@ InteractiveUtils.@code_llvm InteractiveUtils.code_native InteractiveUtils.@code_native ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/src/stdlib/IterativeEigensolvers.md b/src/stdlib/IterativeEigensolvers.md index 664f782..62dadc7 100644 --- a/src/stdlib/IterativeEigensolvers.md +++ b/src/stdlib/IterativeEigensolvers.md @@ -1,5 +1,9 @@ # [Iterative Eigensolvers](@id lib-itereigen) +```@meta +DocTestSetup = :(using IterativeEigensolvers) +``` + Julia provides bindings to [ARPACK](http://www.caam.rice.edu/software/ARPACK/), which can be used to perform iterative solutions for eigensystems (using [`eigs`](@ref)) or singular value decompositions (using [`svds`](@ref)). @@ -207,3 +211,7 @@ IterativeEigensolvers.eigs(::Any) IterativeEigensolvers.eigs(::Any, ::Any) IterativeEigensolvers.svds ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/src/stdlib/LinearAlgebra.md b/src/stdlib/LinearAlgebra.md index 00d677f..d931b8c 100644 --- a/src/stdlib/LinearAlgebra.md +++ b/src/stdlib/LinearAlgebra.md @@ -1,5 +1,9 @@ # Linear Algebra +```@meta +DocTestSetup = :(using LinearAlgebra) +``` + In addition to (and as part of) its support for multi-dimensional arrays, Julia provides native implementations of many common and useful linear algebra operations. Basic operations, such as [`trace`](@ref), [`det`](@ref), and [`inv`](@ref) are all supported: @@ -368,7 +372,6 @@ LinearAlgebra.logabsdet Base.inv(::AbstractMatrix) LinearAlgebra.pinv LinearAlgebra.nullspace -Base.repmat Base.kron LinearAlgebra.linreg LinearAlgebra.exp(::StridedMatrix{<:LinearAlgebra.BlasFloat}) @@ -620,3 +623,7 @@ LinearAlgebra.LAPACK.trsen! LinearAlgebra.LAPACK.tgsen! LinearAlgebra.LAPACK.trsyl! ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/src/stdlib/Mmap.md b/src/stdlib/Mmap.md index ada88b1..9bd623d 100644 --- a/src/stdlib/Mmap.md +++ b/src/stdlib/Mmap.md @@ -1,7 +1,15 @@ # Memory-mapped I/O +```@meta +DocTestSetup = :(using Mmap) +``` + ```@docs Mmap.Anonymous Mmap.mmap Mmap.sync! ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/src/stdlib/Pkg.md b/src/stdlib/Pkg.md index b7cd686..47f3f96 100644 --- a/src/stdlib/Pkg.md +++ b/src/stdlib/Pkg.md @@ -1,5 +1,9 @@ # Package Manager Functions +```@meta +DocTestSetup = :(using Pkg) +``` + All package manager functions are defined in the `Pkg` module. None of the `Pkg` module's functions are exported; to use them, you'll need to prefix each function call with an explicit `Pkg.`, e.g. [`Pkg.status()`](@ref) or [`Pkg.dir()`](@ref). @@ -28,3 +32,7 @@ Pkg.build Pkg.test Pkg.dependents ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/src/stdlib/Printf.md b/src/stdlib/Printf.md index 828e527..de79d5c 100644 --- a/src/stdlib/Printf.md +++ b/src/stdlib/Printf.md @@ -1,6 +1,14 @@ # Printf +```@meta +DocTestSetup = :(using Printf) +``` + ```@docs Printf.@printf Printf.@sprintf ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/src/stdlib/Random.md b/src/stdlib/Random.md index 0ef892b..5607ba0 100644 --- a/src/stdlib/Random.md +++ b/src/stdlib/Random.md @@ -1,5 +1,9 @@ # Random Numbers +```@meta +DocTestSetup = :(using Random) +``` + Random number generation in Julia uses the [Mersenne Twister library](http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/#dSFMT) via `MersenneTwister` objects. Julia has a global RNG, which is used by default. Other RNG types can be plugged in by inheriting the `AbstractRNG` type; they can then be used to have multiple @@ -41,3 +45,7 @@ Random.randcycle! Random.shuffle Random.shuffle! ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/src/stdlib/SparseArrays.md b/src/stdlib/SparseArrays.md index d55c7f0..34dd58c 100644 --- a/src/stdlib/SparseArrays.md +++ b/src/stdlib/SparseArrays.md @@ -1,5 +1,9 @@ # Sparse Arrays +```@meta +DocTestSetup = :(using SparseArrays) +``` + Julia has support for sparse vectors and [sparse matrices](https://en.wikipedia.org/wiki/Sparse_matrix) in the `SparseArrays` stdlib module. Sparse arrays are arrays that contain enough zeros that storing them in a special data structure leads to savings in space and execution time, @@ -218,3 +222,7 @@ SparseArrays.dropzeros SparseArrays.permute permute!{Tv, Ti, Tp <: Integer, Tq <: Integer}(::SparseMatrixCSC{Tv,Ti}, ::SparseMatrixCSC{Tv,Ti}, ::AbstractArray{Tp,1}, ::AbstractArray{Tq,1}) ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/src/stdlib/Test.md b/src/stdlib/Test.md index 32ec604..4211071 100644 --- a/src/stdlib/Test.md +++ b/src/stdlib/Test.md @@ -1,9 +1,7 @@ # Unit Testing ```@meta -DocTestSetup = quote - using Test -end +DocTestSetup = :(using Test) ``` ## Testing Base Julia diff --git a/src/stdlib/UUIDs.md b/src/stdlib/UUIDs.md index 616ac63..ddc490f 100644 --- a/src/stdlib/UUIDs.md +++ b/src/stdlib/UUIDs.md @@ -1,7 +1,15 @@ # UUIDs +```@meta +DocTestSetup = :(using UUIDs) +``` + ```@docs UUIDs.uuid1 UUIDs.uuid4 UUIDs.uuid_version ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/src/stdlib/Unicode.md b/src/stdlib/Unicode.md index aba9d80..474629d 100644 --- a/src/stdlib/Unicode.md +++ b/src/stdlib/Unicode.md @@ -1,7 +1,15 @@ # Unicode +```@meta +DocTestSetup = :(using Unicode) +``` + ```@docs Unicode.isassigned Unicode.normalize Unicode.graphemes ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/src/stdlib/base64.md b/src/stdlib/base64.md index 02e7e6b..b179de0 100644 --- a/src/stdlib/base64.md +++ b/src/stdlib/base64.md @@ -1,5 +1,9 @@ # Base64 +```@meta +DocTestSetup = :(using Base64) +``` + ```@docs Base64.Base64EncodePipe Base64.base64encode @@ -7,3 +11,7 @@ Base64.Base64DecodePipe Base64.base64decode Base64.stringmime ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/src/stdlib/dates.md b/src/stdlib/dates.md index 40852af..3abee48 100644 --- a/src/stdlib/dates.md +++ b/src/stdlib/dates.md @@ -1,5 +1,9 @@ # [Dates and Time](@id stdlib-dates) +```@meta +DocTestSetup = :(using Dates) +``` + Functionality to handle time and dates is defined in the standard library module `Dates`. You'll need to import the module using `import Dates` and prefix each function call with an explicit `Dates.`, e.g. `Dates.dayofweek(dt)`. Alternatively, you can write @@ -192,3 +196,7 @@ Months of the Year: | `October` | `Oct` | 10 | | `November` | `Nov` | 11 | | `December` | `Dec` | 12 | + +```@meta +DocTestSetup = nothing +``` diff --git a/src/stdlib/delimitedfiles.md b/src/stdlib/delimitedfiles.md index 7cd38cb..2a343d5 100644 --- a/src/stdlib/delimitedfiles.md +++ b/src/stdlib/delimitedfiles.md @@ -1,5 +1,9 @@ # Delimited Files +```@meta +DocTestSetup = :(using DelimitedFiles) +``` + ```@docs DelimitedFiles.readdlm(::Any, ::Char, ::Type, ::Char) DelimitedFiles.readdlm(::Any, ::Char, ::Char) @@ -9,3 +13,7 @@ DelimitedFiles.readdlm(::Any, ::Type) DelimitedFiles.readdlm(::Any) DelimitedFiles.writedlm ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/src/stdlib/distributed.md b/src/stdlib/distributed.md index 47d4c23..da0b822 100644 --- a/src/stdlib/distributed.md +++ b/src/stdlib/distributed.md @@ -1,5 +1,9 @@ # Distributed Computing +```@meta +DocTestSetup = :(using Distributed) +``` + ```@docs Distributed.addprocs Distributed.nprocs @@ -67,3 +71,7 @@ Distributed.init_worker Distributed.start_worker Distributed.process_messages ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/src/stdlib/iterativeeigensolvers.md b/src/stdlib/iterativeeigensolvers.md index 664f782..62dadc7 100644 --- a/src/stdlib/iterativeeigensolvers.md +++ b/src/stdlib/iterativeeigensolvers.md @@ -1,5 +1,9 @@ # [Iterative Eigensolvers](@id lib-itereigen) +```@meta +DocTestSetup = :(using IterativeEigensolvers) +``` + Julia provides bindings to [ARPACK](http://www.caam.rice.edu/software/ARPACK/), which can be used to perform iterative solutions for eigensystems (using [`eigs`](@ref)) or singular value decompositions (using [`svds`](@ref)). @@ -207,3 +211,7 @@ IterativeEigensolvers.eigs(::Any) IterativeEigensolvers.eigs(::Any, ::Any) IterativeEigensolvers.svds ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/src/stdlib/linearalgebra.md b/src/stdlib/linearalgebra.md index 00d677f..d931b8c 100644 --- a/src/stdlib/linearalgebra.md +++ b/src/stdlib/linearalgebra.md @@ -1,5 +1,9 @@ # Linear Algebra +```@meta +DocTestSetup = :(using LinearAlgebra) +``` + In addition to (and as part of) its support for multi-dimensional arrays, Julia provides native implementations of many common and useful linear algebra operations. Basic operations, such as [`trace`](@ref), [`det`](@ref), and [`inv`](@ref) are all supported: @@ -368,7 +372,6 @@ LinearAlgebra.logabsdet Base.inv(::AbstractMatrix) LinearAlgebra.pinv LinearAlgebra.nullspace -Base.repmat Base.kron LinearAlgebra.linreg LinearAlgebra.exp(::StridedMatrix{<:LinearAlgebra.BlasFloat}) @@ -620,3 +623,7 @@ LinearAlgebra.LAPACK.trsen! LinearAlgebra.LAPACK.tgsen! LinearAlgebra.LAPACK.trsyl! ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/src/stdlib/mmap.md b/src/stdlib/mmap.md index ada88b1..9bd623d 100644 --- a/src/stdlib/mmap.md +++ b/src/stdlib/mmap.md @@ -1,7 +1,15 @@ # Memory-mapped I/O +```@meta +DocTestSetup = :(using Mmap) +``` + ```@docs Mmap.Anonymous Mmap.mmap Mmap.sync! ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/src/stdlib/printf.md b/src/stdlib/printf.md index 828e527..de79d5c 100644 --- a/src/stdlib/printf.md +++ b/src/stdlib/printf.md @@ -1,6 +1,14 @@ # Printf +```@meta +DocTestSetup = :(using Printf) +``` + ```@docs Printf.@printf Printf.@sprintf ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/src/stdlib/random.md b/src/stdlib/random.md index 0ef892b..5607ba0 100644 --- a/src/stdlib/random.md +++ b/src/stdlib/random.md @@ -1,5 +1,9 @@ # Random Numbers +```@meta +DocTestSetup = :(using Random) +``` + Random number generation in Julia uses the [Mersenne Twister library](http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/#dSFMT) via `MersenneTwister` objects. Julia has a global RNG, which is used by default. Other RNG types can be plugged in by inheriting the `AbstractRNG` type; they can then be used to have multiple @@ -41,3 +45,7 @@ Random.randcycle! Random.shuffle Random.shuffle! ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/src/stdlib/sparsearrays.md b/src/stdlib/sparsearrays.md index d55c7f0..34dd58c 100644 --- a/src/stdlib/sparsearrays.md +++ b/src/stdlib/sparsearrays.md @@ -1,5 +1,9 @@ # Sparse Arrays +```@meta +DocTestSetup = :(using SparseArrays) +``` + Julia has support for sparse vectors and [sparse matrices](https://en.wikipedia.org/wiki/Sparse_matrix) in the `SparseArrays` stdlib module. Sparse arrays are arrays that contain enough zeros that storing them in a special data structure leads to savings in space and execution time, @@ -218,3 +222,7 @@ SparseArrays.dropzeros SparseArrays.permute permute!{Tv, Ti, Tp <: Integer, Tq <: Integer}(::SparseMatrixCSC{Tv,Ti}, ::SparseMatrixCSC{Tv,Ti}, ::AbstractArray{Tp,1}, ::AbstractArray{Tq,1}) ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/src/stdlib/test.md b/src/stdlib/test.md index 32ec604..4211071 100644 --- a/src/stdlib/test.md +++ b/src/stdlib/test.md @@ -1,9 +1,7 @@ # Unit Testing ```@meta -DocTestSetup = quote - using Test -end +DocTestSetup = :(using Test) ``` ## Testing Base Julia diff --git a/src/stdlib/unicode.md b/src/stdlib/unicode.md index aba9d80..474629d 100644 --- a/src/stdlib/unicode.md +++ b/src/stdlib/unicode.md @@ -1,7 +1,15 @@ # Unicode +```@meta +DocTestSetup = :(using Unicode) +``` + ```@docs Unicode.isassigned Unicode.normalize Unicode.graphemes ``` + +```@meta +DocTestSetup = nothing +``` From 24b87d8652a0de38b6ec0c071c1d2ba06b7f8df2 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Tue, 27 Feb 2018 20:00:45 +0900 Subject: [PATCH 008/153] update Julia Commit 00c82f034d --- codex/NEWS.md | 13 +- codex/base/base.md | 3 +- codex/base/constants.md | 6 +- codex/base/index.md | 36 -- codex/base/io-network.md | 6 +- codex/devdocs/stdio.md | 10 +- codex/index.md | 3 +- codex/manual/dates.md | 628 --------------------- codex/manual/environment-variables.md | 12 +- codex/manual/faq.md | 6 +- codex/manual/functions.md | 12 + codex/manual/getting-started.md | 7 +- codex/manual/modules.md | 11 +- codex/manual/networking-and-streams.md | 28 +- codex/manual/parallel-computing.md | 12 +- codex/manual/profile.md | 6 +- codex/manual/running-external-programs.md | 10 +- codex/manual/types.md | 6 +- codex/manual/workflow-tips.md | 2 +- codex/stdlib/Dates.md | 631 +++++++++++++++++++++- codex/stdlib/REPL.md | 9 +- codex/stdlib/dates.md | 631 +++++++++++++++++++++- make.jl | 1 - src/NEWS.md | 13 +- src/base/base.md | 3 +- src/base/constants.md | 6 +- src/base/index.md | 36 -- src/base/io-network.md | 6 +- src/devdocs/stdio.md | 10 +- src/index.md | 3 +- src/manual/dates.md | 628 --------------------- src/manual/environment-variables.md | 12 +- src/manual/faq.md | 6 +- src/manual/functions.md | 12 + src/manual/getting-started.md | 4 +- src/manual/modules.md | 11 +- src/manual/networking-and-streams.md | 28 +- src/manual/parallel-computing.md | 12 +- src/manual/profile.md | 6 +- src/manual/running-external-programs.md | 10 +- src/manual/types.md | 6 +- src/manual/workflow-tips.md | 2 +- src/stdlib/Dates.md | 631 +++++++++++++++++++++- src/stdlib/REPL.md | 9 +- src/stdlib/dates.md | 631 +++++++++++++++++++++- 45 files changed, 2682 insertions(+), 1492 deletions(-) delete mode 100644 codex/base/index.md delete mode 100644 codex/manual/dates.md delete mode 100644 src/base/index.md delete mode 100644 src/manual/dates.md diff --git a/codex/NEWS.md b/codex/NEWS.md index 1a0e2eb..88552c2 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -199,6 +199,9 @@ Language changes * `=>` now has its own precedence level, giving it strictly higher precedence than `=` and `,` ([#25391](https://github.com/JuliaLang/julia/issues/25391)). + * The conditions under which unary operators followed by `(` are parsed as prefix function + calls have changed ([#26154](https://github.com/JuliaLang/julia/issues/26154)). + * `begin` is disallowed inside indexing expressions, in order to enable the syntax `a[begin]` (for selecting the first element) in the future ([#23354](https://github.com/JuliaLang/julia/issues/23354)). @@ -263,7 +266,10 @@ This section lists changes that do not have deprecation warnings. of the socket. Previously the address of the remote endpoint was being returned ([#21825](https://github.com/JuliaLang/julia/issues/21825)). - * Using `ARGS` within the ~/.juliarc.jl or within a .jl file loaded with `--load` will no + * The `~/.juliarc.jl` file has been moved to `~/.julia/config/startup.jl` and + `/etc/julia/juliarc.jl` file has been renamed to `/etc/julia/startup.jl` ([#26161](https://github.com/JuliaLang/julia/issues/26161)). + + * Using `ARGS` within `startup.jl` files or within a .jl file loaded with `--load` will no longer contain the script name as the first argument. Instead, the script name will be assigned to `PROGRAM_FILE`. ([#22092](https://github.com/JuliaLang/julia/issues/22092)) @@ -801,7 +807,7 @@ Deprecated or removed * Calling `write` on non-isbits arrays is deprecated in favor of explicit loops or `serialize` ([#6466](https://github.com/JuliaLang/julia/issues/6466)). - * The default `juliarc.jl` file on Windows has been removed. Now must explicitly include the + * The default `startup.jl` file on Windows has been removed. Now must explicitly include the full path if you need access to executables or libraries in the `Sys.BINDIR` directory, e.g. `joinpath(Sys.BINDIR, "7z.exe")` for `7z.exe` ([#21540](https://github.com/JuliaLang/julia/issues/21540)). @@ -1072,6 +1078,9 @@ Deprecated or removed * The fallback method `^(x, p::Integer)` is deprecated. If your type relied on this definition, add a method such as `^(x::MyType, p::Integer) = Base.power_by_squaring(x, p)` ([#23332](https://github.com/JuliaLang/julia/issues/23332)). + * `DevNull`, `STDIN`, `STDOUT`, and `STDERR` have been renamed to `devnull`, `stdin`, `stdout`, + and `stderr`, respectively ([#25786](https://github.com/JuliaLang/julia/issues/25786)). + * `wait` and `fetch` on `Task` now resemble the interface of `Future` Command-line option changes diff --git a/codex/base/base.md b/codex/base/base.md index bdb3264..254dc03 100644 --- a/codex/base/base.md +++ b/codex/base/base.md @@ -230,7 +230,7 @@ Base.skipmissing ```@docs Base.run Base.spawn -Base.DevNull +Base.devnull Base.success Base.process_running Base.process_exited @@ -274,7 +274,6 @@ Core.throw Base.rethrow Base.backtrace Base.catch_backtrace -Base.assert Base.@assert Base.ArgumentError Base.AssertionError diff --git a/codex/base/constants.md b/codex/base/constants.md index 0f4c321..b56659e 100644 --- a/codex/base/constants.md +++ b/codex/base/constants.md @@ -17,9 +17,9 @@ Base.Sys.MACHINE See also: - * [`STDIN`](@ref) - * [`STDOUT`](@ref) - * [`STDERR`](@ref) + * [`stdin`](@ref) + * [`stdout`](@ref) + * [`stderr`](@ref) * [`ENV`](@ref) * [`ENDIAN_BOM`](@ref) * `Libc.MS_ASYNC` diff --git a/codex/base/index.md b/codex/base/index.md deleted file mode 100644 index 637a62a..0000000 --- a/codex/base/index.md +++ /dev/null @@ -1,36 +0,0 @@ -# The Julia Standard Library - - * [Essentials](@ref) - * [Collections and Data Structures](@ref) - * [Mathematics](@ref) - * [Numbers](@ref lib-numbers) - * [Strings](@ref lib-strings) - * [Arrays](@ref lib-arrays) - * [Tasks](@ref) - * [Distributed Computing](@ref) - * [Shared Arrays](@ref) - * [Multi-Threading](@ref) - * [Constants](@ref lib-constants) - * [Filesystem](@ref) - * [Delimited Files](@ref) - * [I/O and Network](@ref) - * [Punctuation](@ref) - * [Sorting and Related Functions](@ref) - * [Package Manager Functions](@ref) - * [Dates and Time](@ref stdlib-dates) - * [Iteration utilities](@ref) - * [Unit Testing](@ref) - * [C Interface](@ref) - * [LLVM Interface](@ref) - * [C Standard Library](@ref) - * [Dynamic Linker](@ref) - * [StackTraces](@ref) - * [SIMD Support](@ref) - * [Profiling](@ref lib-profiling) - * [Memory-mapped I/O](@ref) - * [Base64](@ref) - * [File Events](@ref lib-filewatching) - * [Sparse Arrays](@ref) - * [Iterative Eigensolvers](@ref lib-itereigen) - * [Printf](@ref) - * [Random Numbers](@ref) diff --git a/codex/base/io-network.md b/codex/base/io-network.md index 396c0ef..b28cf9d 100644 --- a/codex/base/io-network.md +++ b/codex/base/io-network.md @@ -3,9 +3,9 @@ ## General I/O ```@docs -Base.STDOUT -Base.STDERR -Base.STDIN +Base.stdout +Base.stderr +Base.stdin Base.open Base.IOBuffer Base.take!(::Base.GenericIOBuffer) diff --git a/codex/devdocs/stdio.md b/codex/devdocs/stdio.md index 2adc259..d17f7ab 100644 --- a/codex/devdocs/stdio.md +++ b/codex/devdocs/stdio.md @@ -29,24 +29,24 @@ void jl_safe_printf(const char *str, ...); ## Interface between JL_STD* and Julia code -[`Base.STDIN`](@ref), [`Base.STDOUT`](@ref) and [`Base.STDERR`](@ref) are bound to the `JL_STD*` libuv +[`Base.stdin`](@ref), [`Base.stdout`](@ref) and [`Base.stderr`](@ref) are bound to the `JL_STD*` libuv streams defined in the runtime. Julia's `__init__()` function (in `base/sysimg.jl`) calls `reinit_stdio()` (in `base/stream.jl`) -to create Julia objects for [`Base.STDIN`](@ref), [`Base.STDOUT`](@ref) and [`Base.STDERR`](@ref). +to create Julia objects for [`Base.stdin`](@ref), [`Base.stdout`](@ref) and [`Base.stderr`](@ref). `reinit_stdio()` uses [`ccall`](@ref) to retrieve pointers to `JL_STD*` and calls `jl_uv_handle_type()` to inspect the type of each stream. It then creates a Julia `Base.IOStream`, `Base.TTY` or `Base.PipeEndpoint` object to represent each stream, e.g.: ``` -$ julia -e 'println(typeof((STDIN, STDOUT, STDERR)))' +$ julia -e 'println(typeof((stdin, stdout, stderr)))' Tuple{Base.TTY,Base.TTY,Base.TTY} -$ julia -e 'println(typeof((STDIN, STDOUT, STDERR)))' < /dev/null 2>/dev/null +$ julia -e 'println(typeof((stdin, stdout, stderr)))' < /dev/null 2>/dev/null Tuple{IOStream,Base.TTY,IOStream} -$ echo hello | julia -e 'println(typeof((STDIN, STDOUT, STDERR)))' | cat +$ echo hello | julia -e 'println(typeof((stdin, stdout, stderr)))' | cat Tuple{Base.PipeEndpoint,Base.PipeEndpoint,Base.TTY} ``` diff --git a/codex/index.md b/codex/index.md index 7faecc1..f7e5765 100644 --- a/codex/index.md +++ b/codex/index.md @@ -33,7 +33,6 @@ Please read the [release notes](NEWS.md) to see what has changed since the last * [Missing Values](@ref missing) * [Networking and Streams](@ref) * [Parallel Computing](@ref) - * [Date and DateTime](@ref) * [Running External Programs](@ref) * [Calling C and Fortran Code](@ref) * [Handling Operating System Variation](@ref) @@ -80,7 +79,7 @@ Please read the [release notes](NEWS.md) to see what has changed since the last * [Base64](@ref) * [CRC32c](@ref) * [SHA](@ref) - * [Dates and Time](@ref stdlib-dates) + * [Dates](@ref stdlib-dates) * [Delimited Files](@ref) * [Distributed Computing](@ref) * [File Events](@ref lib-filewatching) diff --git a/codex/manual/dates.md b/codex/manual/dates.md deleted file mode 100644 index 5496eb7..0000000 --- a/codex/manual/dates.md +++ /dev/null @@ -1,628 +0,0 @@ -# Date and DateTime - -```@meta -CurrentModule = Dates -``` - -The `Dates` module provides two types for working with dates: [`Date`](@ref) and [`DateTime`](@ref), -representing day and millisecond precision, respectively; both are subtypes of the abstract [`TimeType`](@ref). -The motivation for distinct types is simple: some operations are much simpler, both in terms of -code and mental reasoning, when the complexities of greater precision don't have to be dealt with. -For example, since the [`Date`](@ref) type only resolves to the precision of a single date (i.e. -no hours, minutes, or seconds), normal considerations for time zones, daylight savings/summer -time, and leap seconds are unnecessary and avoided. - -Both [`Date`](@ref) and [`DateTime`](@ref) are basically immutable [`Int64`](@ref) wrappers. -The single `instant` field of either type is actually a `UTInstant{P}` type, which -represents a continuously increasing machine timeline based on the UT second [^1]. The -[`DateTime`](@ref) type is not aware of time zones (*naive*, in Python parlance), -analogous to a *LocalDateTime* in Java 8. Additional time zone functionality -can be added through the [TimeZones.jl package](https://github.com/JuliaTime/TimeZones.jl/), which -compiles the [IANA time zone database](http://www.iana.org/time-zones). Both [`Date`](@ref) and -[`DateTime`](@ref) are based on the [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) standard, which follows the proleptic Gregorian calendar. -One note is that the ISO 8601 standard is particular about BC/BCE dates. In general, the last -day of the BC/BCE era, 1-12-31 BC/BCE, was followed by 1-1-1 AD/CE, thus no year zero exists. -The ISO standard, however, states that 1 BC/BCE is year zero, so `0000-12-31` is the day before -`0001-01-01`, and year `-0001` (yes, negative one for the year) is 2 BC/BCE, year `-0002` is 3 -BC/BCE, etc. - -[^1]: - The notion of the UT second is actually quite fundamental. There are basically two different notions - of time generally accepted, one based on the physical rotation of the earth (one full rotation - = 1 day), the other based on the SI second (a fixed, constant value). These are radically different! - Think about it, a "UT second", as defined relative to the rotation of the earth, may have a different - absolute length depending on the day! Anyway, the fact that [`Date`](@ref) and [`DateTime`](@ref) - are based on UT seconds is a simplifying, yet honest assumption so that things like leap seconds - and all their complexity can be avoided. This basis of time is formally called [UT](https://en.wikipedia.org/wiki/Universal_Time) - or UT1. Basing types on the UT second basically means that every minute has 60 seconds and every - day has 24 hours and leads to more natural calculations when working with calendar dates. - -## Constructors - -[`Date`](@ref) and [`DateTime`](@ref) types can be constructed by integer or [`Period`](@ref) -types, by parsing, or through adjusters (more on those later): - -```jldoctest -julia> DateTime(2013) -2013-01-01T00:00:00 - -julia> DateTime(2013,7) -2013-07-01T00:00:00 - -julia> DateTime(2013,7,1) -2013-07-01T00:00:00 - -julia> DateTime(2013,7,1,12) -2013-07-01T12:00:00 - -julia> DateTime(2013,7,1,12,30) -2013-07-01T12:30:00 - -julia> DateTime(2013,7,1,12,30,59) -2013-07-01T12:30:59 - -julia> DateTime(2013,7,1,12,30,59,1) -2013-07-01T12:30:59.001 - -julia> Date(2013) -2013-01-01 - -julia> Date(2013,7) -2013-07-01 - -julia> Date(2013,7,1) -2013-07-01 - -julia> Date(Dates.Year(2013),Dates.Month(7),Dates.Day(1)) -2013-07-01 - -julia> Date(Dates.Month(7),Dates.Year(2013)) -2013-07-01 -``` - -[`Date`](@ref) or [`DateTime`](@ref) parsing is accomplished by the use of format strings. Format -strings work by the notion of defining *delimited* or *fixed-width* "slots" that contain a period -to parse and passing the text to parse and format string to a [`Date`](@ref) or [`DateTime`](@ref) -constructor, of the form `Date("2015-01-01","y-m-d")` or `DateTime("20150101","yyyymmdd")`. - -Delimited slots are marked by specifying the delimiter the parser should expect between two subsequent -periods; so `"y-m-d"` lets the parser know that between the first and second slots in a date string -like `"2014-07-16"`, it should find the `-` character. The `y`, `m`, and `d` characters let the -parser know which periods to parse in each slot. - -Fixed-width slots are specified by repeating the period character the number of times corresponding -to the width with no delimiter between characters. So `"yyyymmdd"` would correspond to a date -string like `"20140716"`. The parser distinguishes a fixed-width slot by the absence of a delimiter, -noting the transition `"yyyymm"` from one period character to the next. - -Support for text-form month parsing is also supported through the `u` and `U` characters, for -abbreviated and full-length month names, respectively. By default, only English month names are -supported, so `u` corresponds to "Jan", "Feb", "Mar", etc. And `U` corresponds to "January", "February", -"March", etc. Similar to other name=>value mapping functions [`dayname`](@ref) and [`monthname`](@ref), -custom locales can be loaded by passing in the `locale=>Dict{String,Int}` mapping to the `MONTHTOVALUEABBR` -and `MONTHTOVALUE` dicts for abbreviated and full-name month names, respectively. - -One note on parsing performance: using the `Date(date_string,format_string)` function is fine -if only called a few times. If there are many similarly formatted date strings to parse however, -it is much more efficient to first create a [`Dates.DateFormat`](@ref), and pass it instead of -a raw format string. - -```jldoctest -julia> df = DateFormat("y-m-d"); - -julia> dt = Date("2015-01-01",df) -2015-01-01 - -julia> dt2 = Date("2015-01-02",df) -2015-01-02 -``` - -You can also use the `dateformat""` string macro. This macro creates the `DateFormat` object once when the macro is expanded and uses the same `DateFormat` object even if a code snippet is run multiple times. - -```jldoctest -julia> for i = 1:10^5 - Date("2015-01-01", dateformat"y-m-d") - end -``` - -A full suite of parsing and formatting tests and examples is available in [`stdlib/Dates/test/io.jl`](https://github.com/JuliaLang/julia/blob/master/stdlib/Dates/test/io.jl). - -## Durations/Comparisons - -Finding the length of time between two [`Date`](@ref) or [`DateTime`](@ref) is straightforward -given their underlying representation as `UTInstant{Day}` and `UTInstant{Millisecond}`, respectively. -The difference between [`Date`](@ref) is returned in the number of [`Day`](@ref), and [`DateTime`](@ref) -in the number of [`Millisecond`](@ref). Similarly, comparing [`TimeType`](@ref) is a simple matter -of comparing the underlying machine instants (which in turn compares the internal [`Int64`](@ref) values). - -```jldoctest -julia> dt = Date(2012,2,29) -2012-02-29 - -julia> dt2 = Date(2000,2,1) -2000-02-01 - -julia> dump(dt) -Date - instant: Dates.UTInstant{Dates.Day} - periods: Dates.Day - value: Int64 734562 - -julia> dump(dt2) -Date - instant: Dates.UTInstant{Dates.Day} - periods: Dates.Day - value: Int64 730151 - -julia> dt > dt2 -true - -julia> dt != dt2 -true - -julia> dt + dt2 -ERROR: MethodError: no method matching +(::Date, ::Date) -[...] - -julia> dt * dt2 -ERROR: MethodError: no method matching *(::Date, ::Date) -[...] - -julia> dt / dt2 -ERROR: MethodError: no method matching /(::Date, ::Date) -[...] - -julia> dt - dt2 -4411 days - -julia> dt2 - dt --4411 days - -julia> dt = DateTime(2012,2,29) -2012-02-29T00:00:00 - -julia> dt2 = DateTime(2000,2,1) -2000-02-01T00:00:00 - -julia> dt - dt2 -381110400000 milliseconds -``` - -## Accessor Functions - -Because the [`Date`](@ref) and [`DateTime`](@ref) types are stored as single [`Int64`](@ref) values, date -parts or fields can be retrieved through accessor functions. The lowercase accessors return the -field as an integer: - -```jldoctest tdate -julia> t = Date(2014, 1, 31) -2014-01-31 - -julia> Dates.year(t) -2014 - -julia> Dates.month(t) -1 - -julia> Dates.week(t) -5 - -julia> Dates.day(t) -31 -``` - -While propercase return the same value in the corresponding [`Period`](@ref) type: - -```jldoctest tdate -julia> Dates.Year(t) -2014 years - -julia> Dates.Day(t) -31 days -``` - -Compound methods are provided, as they provide a measure of efficiency if multiple fields are -needed at the same time: - -```jldoctest tdate -julia> Dates.yearmonth(t) -(2014, 1) - -julia> Dates.monthday(t) -(1, 31) - -julia> Dates.yearmonthday(t) -(2014, 1, 31) -``` - -One may also access the underlying `UTInstant` or integer value: - -```jldoctest tdate -julia> dump(t) -Date - instant: Dates.UTInstant{Dates.Day} - periods: Dates.Day - value: Int64 735264 - -julia> t.instant -Dates.UTInstant{Dates.Day}(735264 days) - -julia> Dates.value(t) -735264 -``` - -## Query Functions - -Query functions provide calendrical information about a [`TimeType`](@ref). They include information -about the day of the week: - -```jldoctest tdate2 -julia> t = Date(2014, 1, 31) -2014-01-31 - -julia> Dates.dayofweek(t) -5 - -julia> Dates.dayname(t) -"Friday" - -julia> Dates.dayofweekofmonth(t) # 5th Friday of January -5 -``` - -Month of the year: - -```jldoctest tdate2 -julia> Dates.monthname(t) -"January" - -julia> Dates.daysinmonth(t) -31 -``` - -As well as information about the [`TimeType`](@ref)'s year and quarter: - -```jldoctest tdate2 -julia> Dates.isleapyear(t) -false - -julia> Dates.dayofyear(t) -31 - -julia> Dates.quarterofyear(t) -1 - -julia> Dates.dayofquarter(t) -31 -``` - -The [`dayname`](@ref) and [`monthname`](@ref) methods can also take an optional `locale` keyword -that can be used to return the name of the day or month of the year for other languages/locales. -There are also versions of these functions returning the abbreviated names, namely -[`dayabbr`](@ref) and [`monthabbr`](@ref). -First the mapping is loaded into the `LOCALES` variable: - -```jldoctest tdate2 -julia> french_months = ["janvier", "février", "mars", "avril", "mai", "juin", - "juillet", "août", "septembre", "octobre", "novembre", "décembre"]; - -julia> french_monts_abbrev = ["janv","févr","mars","avril","mai","juin", - "juil","août","sept","oct","nov","déc"]; - -julia> french_days = ["lundi","mardi","mercredi","jeudi","vendredi","samedi","dimanche"]; - -julia> Dates.LOCALES["french"] = Dates.DateLocale(french_months, french_monts_abbrev, french_days, [""]); -``` - - The above mentioned functions can then be used to perform the queries: - -```jldoctest tdate2 -julia> Dates.dayname(t;locale="french") -"vendredi" - -julia> Dates.monthname(t;locale="french") -"janvier" - -julia> Dates.monthabbr(t;locale="french") -"janv" -``` - -Since the abbreviated versions of the days are not loaded, trying to use the -function `dayabbr` will error. - -```jldoctest tdate2 -julia> Dates.dayabbr(t;locale="french") -ERROR: BoundsError: attempt to access 1-element Array{String,1} at index [5] -Stacktrace: -[...] -``` - - -## TimeType-Period Arithmetic - -It's good practice when using any language/date framework to be familiar with how date-period -arithmetic is handled as there are some [tricky issues](https://codeblog.jonskeet.uk/2010/12/01/the-joys-of-date-time-arithmetic/) -to deal with (though much less so for day-precision types). - -The `Dates` module approach tries to follow the simple principle of trying to change as -little as possible when doing [`Period`](@ref) arithmetic. This approach is also often known as -*calendrical* arithmetic or what you would probably guess if someone were to ask you the same -calculation in a conversation. Why all the fuss about this? Let's take a classic example: add -1 month to January 31st, 2014. What's the answer? Javascript will say [March 3](http://www.markhneedham.com/blog/2009/01/07/javascript-add-a-month-to-a-date/) -(assumes 31 days). PHP says [March 2](https://stackoverflow.com/questions/5760262/php-adding-months-to-a-date-while-not-exceeding-the-last-day-of-the-month) -(assumes 30 days). The fact is, there is no right answer. In the `Dates` module, it gives -the result of February 28th. How does it figure that out? I like to think of the classic 7-7-7 -gambling game in casinos. - -Now just imagine that instead of 7-7-7, the slots are Year-Month-Day, or in our example, 2014-01-31. -When you ask to add 1 month to this date, the month slot is incremented, so now we have 2014-02-31. -Then the day number is checked if it is greater than the last valid day of the new month; if it -is (as in the case above), the day number is adjusted down to the last valid day (28). What are -the ramifications with this approach? Go ahead and add another month to our date, `2014-02-28 + Month(1) == 2014-03-28`. -What? Were you expecting the last day of March? Nope, sorry, remember the 7-7-7 slots. As few -slots as possible are going to change, so we first increment the month slot by 1, 2014-03-28, -and boom, we're done because that's a valid date. On the other hand, if we were to add 2 months -to our original date, 2014-01-31, then we end up with 2014-03-31, as expected. The other ramification -of this approach is a loss in associativity when a specific ordering is forced (i.e. adding things -in different orders results in different outcomes). For example: - -```jldoctest -julia> (Date(2014,1,29)+Dates.Day(1)) + Dates.Month(1) -2014-02-28 - -julia> (Date(2014,1,29)+Dates.Month(1)) + Dates.Day(1) -2014-03-01 -``` - -What's going on there? In the first line, we're adding 1 day to January 29th, which results in -2014-01-30; then we add 1 month, so we get 2014-02-30, which then adjusts down to 2014-02-28. -In the second example, we add 1 month *first*, where we get 2014-02-29, which adjusts down to -2014-02-28, and *then* add 1 day, which results in 2014-03-01. One design principle that helps -in this case is that, in the presence of multiple Periods, the operations will be ordered by the -Periods' *types*, not their value or positional order; this means `Year` will always be added -first, then `Month`, then `Week`, etc. Hence the following *does* result in associativity and -Just Works: - -```jldoctest -julia> Date(2014,1,29) + Dates.Day(1) + Dates.Month(1) -2014-03-01 - -julia> Date(2014,1,29) + Dates.Month(1) + Dates.Day(1) -2014-03-01 -``` - -Tricky? Perhaps. What is an innocent `Dates` user to do? The bottom line is to be aware -that explicitly forcing a certain associativity, when dealing with months, may lead to some unexpected -results, but otherwise, everything should work as expected. Thankfully, that's pretty much the -extent of the odd cases in date-period arithmetic when dealing with time in UT (avoiding the "joys" -of dealing with daylight savings, leap seconds, etc.). - -As a bonus, all period arithmetic objects work directly with ranges: - -```jldoctest -julia> dr = Date(2014,1,29):Date(2014,2,3) -2014-01-29:1 day:2014-02-03 - -julia> collect(dr) -6-element Array{Date,1}: - 2014-01-29 - 2014-01-30 - 2014-01-31 - 2014-02-01 - 2014-02-02 - 2014-02-03 - -julia> dr = Date(2014,1,29):Dates.Month(1):Date(2014,07,29) -2014-01-29:1 month:2014-07-29 - -julia> collect(dr) -7-element Array{Date,1}: - 2014-01-29 - 2014-02-28 - 2014-03-29 - 2014-04-29 - 2014-05-29 - 2014-06-29 - 2014-07-29 -``` - -## Adjuster Functions - -As convenient as date-period arithmetics are, often the kinds of calculations needed on dates -take on a *calendrical* or *temporal* nature rather than a fixed number of periods. Holidays are -a perfect example; most follow rules such as "Memorial Day = Last Monday of May", or "Thanksgiving -= 4th Thursday of November". These kinds of temporal expressions deal with rules relative to the -calendar, like first or last of the month, next Tuesday, or the first and third Wednesdays, etc. - -The `Dates` module provides the *adjuster* API through several convenient methods that -aid in simply and succinctly expressing temporal rules. The first group of adjuster methods deal -with the first and last of weeks, months, quarters, and years. They each take a single [`TimeType`](@ref) -as input and return or *adjust to* the first or last of the desired period relative to the input. - -```jldoctest -julia> Dates.firstdayofweek(Date(2014,7,16)) # Adjusts the input to the Monday of the input's week -2014-07-14 - -julia> Dates.lastdayofmonth(Date(2014,7,16)) # Adjusts to the last day of the input's month -2014-07-31 - -julia> Dates.lastdayofquarter(Date(2014,7,16)) # Adjusts to the last day of the input's quarter -2014-09-30 -``` - -The next two higher-order methods, [`tonext`](@ref), and [`toprev`](@ref), generalize working -with temporal expressions by taking a `DateFunction` as first argument, along with a starting -[`TimeType`](@ref). A `DateFunction` is just a function, usually anonymous, that takes a single -[`TimeType`](@ref) as input and returns a [`Bool`](@ref), `true` indicating a satisfied -adjustment criterion. -For example: - -```jldoctest -julia> istuesday = x->Dates.dayofweek(x) == Dates.Tuesday; # Returns true if the day of the week of x is Tuesday - -julia> Dates.tonext(istuesday, Date(2014,7,13)) # 2014-07-13 is a Sunday -2014-07-15 - -julia> Dates.tonext(Date(2014,7,13), Dates.Tuesday) # Convenience method provided for day of the week adjustments -2014-07-15 -``` - -This is useful with the do-block syntax for more complex temporal expressions: - -```jldoctest -julia> Dates.tonext(Date(2014,7,13)) do x - # Return true on the 4th Thursday of November (Thanksgiving) - Dates.dayofweek(x) == Dates.Thursday && - Dates.dayofweekofmonth(x) == 4 && - Dates.month(x) == Dates.November - end -2014-11-27 -``` - -The [`Base.filter`](@ref) method can be used to obtain all valid dates/moments in a specified -range: - -```jldoctest -# Pittsburgh street cleaning; Every 2nd Tuesday from April to November -# Date range from January 1st, 2014 to January 1st, 2015 -julia> dr = Dates.Date(2014):Dates.Date(2015); - -julia> filter(dr) do x - Dates.dayofweek(x) == Dates.Tue && - Dates.April <= Dates.month(x) <= Dates.Nov && - Dates.dayofweekofmonth(x) == 2 - end -8-element Array{Date,1}: - 2014-04-08 - 2014-05-13 - 2014-06-10 - 2014-07-08 - 2014-08-12 - 2014-09-09 - 2014-10-14 - 2014-11-11 -``` - -Additional examples and tests are available in [`stdlib/Dates/test/adjusters.jl`](https://github.com/JuliaLang/julia/blob/master/stdlib/Dates/test/adjusters.jl). - -## Period Types - -Periods are a human view of discrete, sometimes irregular durations of time. Consider 1 month; -it could represent, in days, a value of 28, 29, 30, or 31 depending on the year and month context. -Or a year could represent 365 or 366 days in the case of a leap year. [`Period`](@ref) types are -simple [`Int64`](@ref) wrappers and are constructed by wrapping any `Int64` convertible type, i.e. `Year(1)` -or `Month(3.0)`. Arithmetic between [`Period`](@ref) of the same type behave like integers, and -limited `Period-Real` arithmetic is available. - -```jldoctest -julia> y1 = Dates.Year(1) -1 year - -julia> y2 = Dates.Year(2) -2 years - -julia> y3 = Dates.Year(10) -10 years - -julia> y1 + y2 -3 years - -julia> div(y3,y2) -5 - -julia> y3 - y2 -8 years - -julia> y3 % y2 -0 years - -julia> div(y3,3) # mirrors integer division -3 years -``` - -## Rounding - -[`Date`](@ref) and [`DateTime`](@ref) values can be rounded to a specified resolution (e.g., 1 -month or 15 minutes) with [`floor`](@ref), [`ceil`](@ref), or [`round`](@ref): - -```jldoctest -julia> floor(Date(1985, 8, 16), Dates.Month) -1985-08-01 - -julia> ceil(DateTime(2013, 2, 13, 0, 31, 20), Dates.Minute(15)) -2013-02-13T00:45:00 - -julia> round(DateTime(2016, 8, 6, 20, 15), Dates.Day) -2016-08-07T00:00:00 -``` - -Unlike the numeric [`round`](@ref) method, which breaks ties toward the even number by default, -the [`TimeType`](@ref)[`round`](@ref) method uses the `RoundNearestTiesUp` rounding mode. (It's -difficult to guess what breaking ties to nearest "even" [`TimeType`](@ref) would entail.) Further -details on the available `RoundingMode` s can be found in the [API reference](@ref stdlib-dates). - -Rounding should generally behave as expected, but there are a few cases in which the expected -behaviour is not obvious. - -### Rounding Epoch - -In many cases, the resolution specified for rounding (e.g., `Dates.Second(30)`) divides evenly -into the next largest period (in this case, `Dates.Minute(1)`). But rounding behaviour in cases -in which this is not true may lead to confusion. What is the expected result of rounding a [`DateTime`](@ref) -to the nearest 10 hours? - -```jldoctest -julia> round(DateTime(2016, 7, 17, 11, 55), Dates.Hour(10)) -2016-07-17T12:00:00 -``` - -That may seem confusing, given that the hour (12) is not divisible by 10. The reason that `2016-07-17T12:00:00` -was chosen is that it is 17,676,660 hours after `0000-01-01T00:00:00`, and 17,676,660 is divisible -by 10. - -As Julia [`Date`](@ref) and [`DateTime`](@ref) values are represented according to the ISO 8601 -standard, `0000-01-01T00:00:00` was chosen as base (or "rounding epoch") from which to begin the -count of days (and milliseconds) used in rounding calculations. (Note that this differs slightly -from Julia's internal representation of [`Date`](@ref) s using Rata Die notation; but since the -ISO 8601 standard is most visible to the end user, `0000-01-01T00:00:00` was chosen as the rounding -epoch instead of the `0000-12-31T00:00:00` used internally to minimize confusion.) - -The only exception to the use of `0000-01-01T00:00:00` as the rounding epoch is when rounding -to weeks. Rounding to the nearest week will always return a Monday (the first day of the week -as specified by ISO 8601). For this reason, we use `0000-01-03T00:00:00` (the first day of the -first week of year 0000, as defined by ISO 8601) as the base when rounding to a number of weeks. - -Here is a related case in which the expected behaviour is not necessarily obvious: What happens -when we round to the nearest `P(2)`, where `P` is a [`Period`](@ref) type? In some cases (specifically, -when `P <: Dates.TimePeriod`) the answer is clear: - -```jldoctest -julia> round(DateTime(2016, 7, 17, 8, 55, 30), Dates.Hour(2)) -2016-07-17T08:00:00 - -julia> round(DateTime(2016, 7, 17, 8, 55, 30), Dates.Minute(2)) -2016-07-17T08:56:00 -``` - -This seems obvious, because two of each of these periods still divides evenly into the next larger -order period. But in the case of two months (which still divides evenly into one year), the answer -may be surprising: - -```jldoctest -julia> round(DateTime(2016, 7, 17, 8, 55, 30), Dates.Month(2)) -2016-07-01T00:00:00 -``` - -Why round to the first day in July, even though it is month 7 (an odd number)? The key is that -months are 1-indexed (the first month is assigned 1), unlike hours, minutes, seconds, and milliseconds -(the first of which are assigned 0). - -This means that rounding a [`DateTime`](@ref) to an even multiple of seconds, minutes, hours, -or years (because the ISO 8601 specification includes a year zero) will result in a [`DateTime`](@ref) -with an even value in that field, while rounding a [`DateTime`](@ref) to an even multiple of months -will result in the months field having an odd value. Because both months and years may contain -an irregular number of days, whether rounding to an even number of days will result in an even -value in the days field is uncertain. - -See the [API reference](@ref stdlib-dates) for additional information -on methods exported from the `Dates` module. diff --git a/codex/manual/environment-variables.md b/codex/manual/environment-variables.md index ebc4617..28dbf15 100644 --- a/codex/manual/environment-variables.md +++ b/codex/manual/environment-variables.md @@ -5,7 +5,7 @@ usual way of the operating system, or in a portable way from within Julia. Suppose you want to set the environment variable `JULIA_EDITOR` to `vim`, then either type `ENV["JULIA_EDITOR"] = "vim"` for instance in the REPL to make this change on a case by case basis, or add the same to the user -configuration file `.juliarc.jl` in the user's home directory to have +configuration file `~/.julia/config/startup.jl` in the user's home directory to have a permanent effect. The current value of the same environment variable is determined by evaluating `ENV["JULIA_EDITOR"]`. @@ -42,14 +42,14 @@ determines the directory in which Julia initially searches for source files (via `Base.find_source_file()`). Likewise, the global variable `Base.SYSCONFDIR` determines a relative path to the -configuration file directory. Then Julia searches for a `juliarc.jl` file at +configuration file directory. Then Julia searches for a `startup.jl` file at ``` -$JULIA_BINDIR/$SYSCONFDIR/julia/juliarc.jl -$JULIA_BINDIR/../etc/julia/juliarc.jl +$JULIA_BINDIR/$SYSCONFDIR/julia/startup.jl +$JULIA_BINDIR/../etc/julia/startup.jl ``` -by default (via `Base.load_juliarc()`). +by default (via `Base.load_julia_startup()`). For example, a Linux installation with a Julia executable located at `/bin/julia`, a `DATAROOTDIR` of `../share`, and a `SYSCONFDIR` of `../etc` will @@ -62,7 +62,7 @@ have `JULIA_BINDIR` set to `/bin`, a source-file search path of and a global configuration search path of ``` -/etc/julia/juliarc.jl +/etc/julia/startup.jl ``` ### `JULIA_LOAD_PATH` diff --git a/codex/manual/faq.md b/codex/manual/faq.md index d367791..fe8ca94 100644 --- a/codex/manual/faq.md +++ b/codex/manual/faq.md @@ -693,7 +693,7 @@ Consider the printed output from the following: ```jldoctest julia> @sync for i in 1:3 - @async write(STDOUT, string(i), " Foo ", " Bar ") + @async write(stdout, string(i), " Foo ", " Bar ") end 123 Foo Foo Foo Bar Bar Bar ``` @@ -706,7 +706,7 @@ in the above example results in: ```jldoctest julia> @sync for i in 1:3 - @async println(STDOUT, string(i), " Foo ", " Bar ") + @async println(stdout, string(i), " Foo ", " Bar ") end 1 Foo Bar 2 Foo Bar @@ -723,7 +723,7 @@ julia> @sync for i in 1:3 @async begin lock(l) try - write(STDOUT, string(i), " Foo ", " Bar ") + write(stdout, string(i), " Foo ", " Bar ") finally unlock(l) end diff --git a/codex/manual/functions.md b/codex/manual/functions.md index fc79f56..db16602 100644 --- a/codex/manual/functions.md +++ b/codex/manual/functions.md @@ -125,6 +125,18 @@ There are three possible points of return from this function, returning the valu expressions, depending on the values of `x` and `y`. The `return` on the last line could be omitted since it is the last expression. +A return type can also be specified in the function declaration using the `::` operator. This converts +the return value to the specified type. + +```jldoctest +function g(x,y)::Int8 + return x * y +end +``` + +This function will always return an `Int8` regardless of the types of `x` and `y`. +See [Type Declarations](@ref) for more on return types. + ## Operators Are Functions In Julia, most operators are just functions with support for special syntax. (The exceptions are diff --git a/codex/manual/getting-started.md b/codex/manual/getting-started.md index 842cff0..6de2c96 100644 --- a/codex/manual/getting-started.md +++ b/codex/manual/getting-started.md @@ -80,10 +80,11 @@ takes the form `[count*][user@]host[:port] [bind_addr[:port]]` . `user` defaults to 1. The optional `bind-to bind_addr[:port]` specifies the ip-address and port that other workers should use to connect to this worker. -If you have code that you want executed whenever Julia is run, you can put it in `~/.juliarc.jl`: +If you have code that you want executed whenever Julia is run, you can put it in +`~/.julia/config/startup.jl`: ``` -$ echo 'println("Greetings! 你好! 안녕하세요?")' > ~/.juliarc.jl +$ echo 'println("Greetings! 你好! 안녕하세요?")' > ~/.julia/config/startup.jl $ julia Greetings! 你好! 안녕하세요? @@ -100,7 +101,7 @@ julia [switches] -- [programfile] [args...] -J, --sysimage Start up with the given system image file -H, --home Set location of `julia` executable - --startup-file={yes|no} Load ~/.juliarc.jl + --startup-file={yes|no} Load `~/.julia/config/startup.jl` --handle-signals={yes|no} Enable or disable Julia's default signal handlers --sysimage-native-code={yes|no} Use native code from system image if available diff --git a/codex/manual/modules.md b/codex/manual/modules.md index 1442f89..20930e2 100644 --- a/codex/manual/modules.md +++ b/codex/manual/modules.md @@ -191,8 +191,9 @@ The global variable [`LOAD_PATH`](@ref) contains the directories Julia searches push!(LOAD_PATH, "/Path/To/My/Module/") ``` -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`. +Putting this statement in the file `~/.julia/config/startup.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 @@ -342,11 +343,11 @@ Other known potential failure scenarios include: of via its lookup path. For example, (in global scope): ```julia - #mystdout = Base.STDOUT #= will not work correctly, since this will copy Base.STDOUT into this module =# + #mystdout = Base.stdout #= will not work correctly, since this will copy Base.stdout into this module =# # instead use accessor functions: - getstdout() = Base.STDOUT #= best option =# + getstdout() = Base.stdout #= best option =# # or move the assignment into the runtime: - __init__() = global mystdout = Base.STDOUT #= also works =# + __init__() = global mystdout = Base.stdout #= also works =# ``` Several additional restrictions are placed on the operations that can be done while precompiling diff --git a/codex/manual/networking-and-streams.md b/codex/manual/networking-and-streams.md index d43c0d1..4d75c59 100644 --- a/codex/manual/networking-and-streams.md +++ b/codex/manual/networking-and-streams.md @@ -12,14 +12,14 @@ All Julia streams expose at least a [`read`](@ref) and a [`write`](@ref) method, stream as their first argument, e.g.: ```julia-repl -julia> write(STDOUT, "Hello World"); # suppress return value 11 with ; +julia> write(stdout, "Hello World"); # suppress return value 11 with ; Hello World -julia> read(STDIN, Char) +julia> read(stdin, Char) '\n': ASCII/Unicode U+000a (category Cc: Other, control) ``` -Note that [`write`](@ref) returns 11, the number of bytes (in `"Hello World"`) written to [`STDOUT`](@ref), +Note that [`write`](@ref) returns 11, the number of bytes (in `"Hello World"`) written to [`stdout`](@ref), but this return value is suppressed with the `;`. Here Enter was pressed again so that Julia would read the newline. Now, as you can see from this @@ -36,7 +36,7 @@ julia> x = zeros(UInt8, 4) 0x00 0x00 -julia> read!(STDIN, x) +julia> read!(stdin, x) abcd 4-element Array{UInt8,1}: 0x61 @@ -49,7 +49,7 @@ However, since this is slightly cumbersome, there are several convenience method example, we could have written the above as: ```julia-repl -julia> read(STDIN, 4) +julia> read(stdin, 4) abcd 4-element Array{UInt8,1}: 0x61 @@ -61,7 +61,7 @@ abcd or if we had wanted to read the entire line instead: ```julia-repl -julia> readline(STDIN) +julia> readline(stdin) abcd "abcd" ``` @@ -69,10 +69,10 @@ abcd Note that depending on your terminal settings, your TTY may be line buffered and might thus require an additional enter before the data is sent to Julia. -To read every line from [`STDIN`](@ref) you can use [`eachline`](@ref): +To read every line from [`stdin`](@ref) you can use [`eachline`](@ref): ```julia -for line in eachline(STDIN) +for line in eachline(stdin) print("Found $line") end ``` @@ -80,8 +80,8 @@ end or [`read`](@ref) if you wanted to read by character instead: ```julia -while !eof(STDIN) - x = read(STDIN, Char) +while !eof(stdin) + x = read(stdin, Char) println("Found: $x") end ``` @@ -92,18 +92,18 @@ Note that the [`write`](@ref) method mentioned above operates on binary streams. values do not get converted to any canonical text representation but are written out as is: ```jldoctest -julia> write(STDOUT, 0x61); # suppress return value 1 with ; +julia> write(stdout, 0x61); # suppress return value 1 with ; a ``` -Note that `a` is written to [`STDOUT`](@ref) by the [`write`](@ref) function and that the returned +Note that `a` is written to [`stdout`](@ref) by the [`write`](@ref) function and that the returned value is `1` (since `0x61` is one byte). For text I/O, use the [`print`](@ref) or [`show`](@ref) methods, depending on your needs (see the Julia Base reference for a detailed discussion of the difference between the two): ```jldoctest -julia> print(STDOUT, 0x61) +julia> print(stdout, 0x61) 97 ``` @@ -272,7 +272,7 @@ julia> clientside = connect(2001) TCPSocket(RawFD(28) open, 0 bytes waiting) julia> @async while true - write(STDOUT,readline(clientside)) + write(stdout,readline(clientside)) end Task (runnable) @0x00007fd31dc11870 diff --git a/codex/manual/parallel-computing.md b/codex/manual/parallel-computing.md index 876ca90..410122d 100644 --- a/codex/manual/parallel-computing.md +++ b/codex/manual/parallel-computing.md @@ -221,9 +221,9 @@ julia> addprocs(2) Module `Distributed` must be explicitly loaded on the master process before invoking [`addprocs`](@ref). It is automatically made available on the worker processes. -Note that workers do not run a `.juliarc.jl` startup script, nor do they synchronize their global -state (such as global variables, new method definitions, and loaded modules) with any of the other -running processes. +Note that workers do not run a `~/.julia/config/startup.jl` startup script, nor do they synchronize +their global state (such as global variables, new method definitions, and loaded modules) with any +of the other running processes. Other types of clusters can be supported by writing your own custom `ClusterManager`, as described below in the [ClusterManagers](@ref) section. @@ -1071,8 +1071,8 @@ manner: * [`addprocs`](@ref) is called on the master process with a `ClusterManager` object. * [`addprocs`](@ref) calls the appropriate [`launch`](@ref) method which spawns required number of worker processes on appropriate machines. - * Each worker starts listening on a free port and writes out its host and port information to [`STDOUT`](@ref). - * The cluster manager captures the [`STDOUT`](@ref) of each worker and makes it available to the + * Each worker starts listening on a free port and writes out its host and port information to [`stdout`](@ref). + * The cluster manager captures the [`stdout`](@ref) of each worker and makes it available to the master process. * The master process parses this information and sets up TCP/IP connections to each worker. * Every worker is also notified of other workers in the cluster. @@ -1315,7 +1315,7 @@ on the master process: are allowed to connect to each other. * The cookie may be passed to the workers at startup via argument `--worker=`. If argument `--worker` is specified without the cookie, the worker tries to read the cookie from its - standard input ([`STDIN`](@ref)). The `STDIN` is closed immediately after the cookie is retrieved. + standard input ([`stdin`](@ref)). The `stdin` is closed immediately after the cookie is retrieved. * `ClusterManager`s can retrieve the cookie on the master by calling [`cluster_cookie()`](@ref). Cluster managers not using the default TCP/IP transport (and hence not specifying `--worker`) must call `init_worker(cookie, manager)` with the same cookie as on the master. diff --git a/codex/manual/profile.md b/codex/manual/profile.md index 29cda5c..00d91cf 100644 --- a/codex/manual/profile.md +++ b/codex/manual/profile.md @@ -210,12 +210,12 @@ be very useful, but sometimes you want to start fresh; you can do so with [`Prof [`Profile.print`](@ref) has more options than we've described so far. Let's see the full declaration: ```julia -function print(io::IO = STDOUT, data = fetch(); kwargs...) +function print(io::IO = stdout, data = fetch(); kwargs...) ``` Let's first discuss the two positional arguments, and later the keyword arguments: - * `io` -- Allows you to save the results to a buffer, e.g. a file, but the default is to print to `STDOUT` + * `io` -- Allows you to save the results to a buffer, e.g. a file, but the default is to print to `stdout` (the console). * `data` -- Contains the data you want to analyze; by default that is obtained from [`Profile.fetch()`](@ref), which pulls out the backtraces from a pre-allocated buffer. For example, if you want to profile @@ -224,7 +224,7 @@ Let's first discuss the two positional arguments, and later the keyword argument ```julia data = copy(Profile.fetch()) Profile.clear() - @profile Profile.print(STDOUT, data) # Prints the previous results + @profile Profile.print(stdout, data) # Prints the previous results Profile.print() # Prints results from Profile.print() ``` diff --git a/codex/manual/running-external-programs.md b/codex/manual/running-external-programs.md index 065b402..88fc044 100644 --- a/codex/manual/running-external-programs.md +++ b/codex/manual/running-external-programs.md @@ -14,7 +14,7 @@ differs in several aspects from the behavior in various shells, Perl, or Ruby: You can use this object to connect the command to others via pipes, [`run`](@ref) it, and [`read`](@ref) or [`write`](@ref) to it. * When the command is run, Julia does not capture its output unless you specifically arrange for - it to. Instead, the output of the command by default goes to [`STDOUT`](@ref) as it would using + it to. Instead, the output of the command by default goes to [`stdout`](@ref) as it would using `libc`'s `system` call. * The command is never run with a shell. Instead, Julia parses the command syntax directly, appropriately interpolating variables and splitting on words as the shell would, respecting shell quoting syntax. @@ -33,7 +33,7 @@ julia> run(mycommand) hello ``` -The `hello` is the output of the `echo` command, sent to [`STDOUT`](@ref). The run method itself +The `hello` is the output of the `echo` command, sent to [`stdout`](@ref). The run method itself returns `nothing`, and throws an [`ErrorException`](@ref) if the external command fails to run successfully. @@ -50,7 +50,7 @@ true More generally, you can use [`open`](@ref) to read from or write to an external command. ```jldoctest -julia> open(`less`, "w", STDOUT) do io +julia> open(`less`, "w", stdout) do io for i = 1:3 println(io, i) end @@ -280,7 +280,7 @@ hello ``` The order of the output here is non-deterministic because the two `echo` processes are started -nearly simultaneously, and race to make the first write to the [`STDOUT`](@ref) descriptor they +nearly simultaneously, and race to make the first write to the [`stdout`](@ref) descriptor they share with each other and the `julia` parent process. Julia lets you pipe the output from both of these processes to another program: @@ -347,7 +347,7 @@ generates lines with the numbers 0 through 9 on them, while two parallel process output, one prefixing lines with the letter "A", the other with the letter "B". Which consumer gets the first line is non-deterministic, but once that race has been won, the lines are consumed alternately by one process and then the other. (Setting `$|=1` in Perl causes each print statement -to flush the [`STDOUT`](@ref) handle, which is necessary for this example to work. Otherwise all +to flush the [`stdout`](@ref) handle, which is necessary for this example to work. Otherwise all the output is buffered and printed to the pipe at once, to be read by just one consumer process.) Here is an even more complex multi-stage producer-consumer example: diff --git a/codex/manual/types.md b/codex/manual/types.md index e30405b..c64215b 100644 --- a/codex/manual/types.md +++ b/codex/manual/types.md @@ -1251,8 +1251,8 @@ julia> [Polar(3, 4.0), Polar(4.0,5.3)] ``` where the single-line `show(io, z)` form is still used for an array of `Polar` values. Technically, -the REPL calls `display(z)` to display the result of executing a line, which defaults to `show(STDOUT, MIME("text/plain"), z)`, -which in turn defaults to `show(STDOUT, z)`, but you should *not* define new [`display`](@ref) +the REPL calls `display(z)` to display the result of executing a line, which defaults to `show(stdout, MIME("text/plain"), z)`, +which in turn defaults to `show(stdout, z)`, but you should *not* define new [`display`](@ref) methods unless you are defining a new multimedia display handler (see [Multimedia I/O](@ref)). Moreover, you can also define `show` methods for other MIME types in order to enable richer display @@ -1269,7 +1269,7 @@ A `Polar` object will then display automatically using HTML in an environment th display, but you can call `show` manually to get HTML output if you want: ```jldoctest polartype -julia> show(STDOUT, "text/html", Polar(3.0,4.0)) +julia> show(stdout, "text/html", Polar(3.0,4.0)) Polar{Float64} complex number: 3.0 e4.0 i ``` diff --git a/codex/manual/workflow-tips.md b/codex/manual/workflow-tips.md index bd00c03..857822d 100644 --- a/codex/manual/workflow-tips.md +++ b/codex/manual/workflow-tips.md @@ -55,7 +55,7 @@ which you can run on startup by issuing the command: julia -L _init.jl ``` -If you further add the following to your `.juliarc.jl` file +If you further add the following to your `~/.julia/config/startup.jl` file ```julia isfile("_init.jl") && include(joinpath(pwd(), "_init.jl")) diff --git a/codex/stdlib/Dates.md b/codex/stdlib/Dates.md index 3abee48..2b3adef 100644 --- a/codex/stdlib/Dates.md +++ b/codex/stdlib/Dates.md @@ -1,14 +1,633 @@ -# [Dates and Time](@id stdlib-dates) +# Dates ```@meta DocTestSetup = :(using Dates) ``` -Functionality to handle time and dates is defined in the standard library module `Dates`. -You'll need to import the module using `import Dates` and prefix each -function call with an explicit `Dates.`, e.g. `Dates.dayofweek(dt)`. Alternatively, you can write -`using Dates` to bring all exported functions into `Main` to be used without the `Dates.` -prefix. +The `Dates` module provides two types for working with dates: [`Date`](@ref) and [`DateTime`](@ref), +representing day and millisecond precision, respectively; both are subtypes of the abstract [`TimeType`](@ref). +The motivation for distinct types is simple: some operations are much simpler, both in terms of +code and mental reasoning, when the complexities of greater precision don't have to be dealt with. +For example, since the [`Date`](@ref) type only resolves to the precision of a single date (i.e. +no hours, minutes, or seconds), normal considerations for time zones, daylight savings/summer +time, and leap seconds are unnecessary and avoided. + +Both [`Date`](@ref) and [`DateTime`](@ref) are basically immutable [`Int64`](@ref) wrappers. +The single `instant` field of either type is actually a `UTInstant{P}` type, which +represents a continuously increasing machine timeline based on the UT second [^1]. The +[`DateTime`](@ref) type is not aware of time zones (*naive*, in Python parlance), +analogous to a *LocalDateTime* in Java 8. Additional time zone functionality +can be added through the [TimeZones.jl package](https://github.com/JuliaTime/TimeZones.jl/), which +compiles the [IANA time zone database](http://www.iana.org/time-zones). Both [`Date`](@ref) and +[`DateTime`](@ref) are based on the [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) standard, which follows the proleptic Gregorian calendar. +One note is that the ISO 8601 standard is particular about BC/BCE dates. In general, the last +day of the BC/BCE era, 1-12-31 BC/BCE, was followed by 1-1-1 AD/CE, thus no year zero exists. +The ISO standard, however, states that 1 BC/BCE is year zero, so `0000-12-31` is the day before +`0001-01-01`, and year `-0001` (yes, negative one for the year) is 2 BC/BCE, year `-0002` is 3 +BC/BCE, etc. + +[^1]: + The notion of the UT second is actually quite fundamental. There are basically two different notions + of time generally accepted, one based on the physical rotation of the earth (one full rotation + = 1 day), the other based on the SI second (a fixed, constant value). These are radically different! + Think about it, a "UT second", as defined relative to the rotation of the earth, may have a different + absolute length depending on the day! Anyway, the fact that [`Date`](@ref) and [`DateTime`](@ref) + are based on UT seconds is a simplifying, yet honest assumption so that things like leap seconds + and all their complexity can be avoided. This basis of time is formally called [UT](https://en.wikipedia.org/wiki/Universal_Time) + or UT1. Basing types on the UT second basically means that every minute has 60 seconds and every + day has 24 hours and leads to more natural calculations when working with calendar dates. + +## Constructors + +[`Date`](@ref) and [`DateTime`](@ref) types can be constructed by integer or [`Period`](@ref) +types, by parsing, or through adjusters (more on those later): + +```jldoctest +julia> DateTime(2013) +2013-01-01T00:00:00 + +julia> DateTime(2013,7) +2013-07-01T00:00:00 + +julia> DateTime(2013,7,1) +2013-07-01T00:00:00 + +julia> DateTime(2013,7,1,12) +2013-07-01T12:00:00 + +julia> DateTime(2013,7,1,12,30) +2013-07-01T12:30:00 + +julia> DateTime(2013,7,1,12,30,59) +2013-07-01T12:30:59 + +julia> DateTime(2013,7,1,12,30,59,1) +2013-07-01T12:30:59.001 + +julia> Date(2013) +2013-01-01 + +julia> Date(2013,7) +2013-07-01 + +julia> Date(2013,7,1) +2013-07-01 + +julia> Date(Dates.Year(2013),Dates.Month(7),Dates.Day(1)) +2013-07-01 + +julia> Date(Dates.Month(7),Dates.Year(2013)) +2013-07-01 +``` + +[`Date`](@ref) or [`DateTime`](@ref) parsing is accomplished by the use of format strings. Format +strings work by the notion of defining *delimited* or *fixed-width* "slots" that contain a period +to parse and passing the text to parse and format string to a [`Date`](@ref) or [`DateTime`](@ref) +constructor, of the form `Date("2015-01-01","y-m-d")` or `DateTime("20150101","yyyymmdd")`. + +Delimited slots are marked by specifying the delimiter the parser should expect between two subsequent +periods; so `"y-m-d"` lets the parser know that between the first and second slots in a date string +like `"2014-07-16"`, it should find the `-` character. The `y`, `m`, and `d` characters let the +parser know which periods to parse in each slot. + +Fixed-width slots are specified by repeating the period character the number of times corresponding +to the width with no delimiter between characters. So `"yyyymmdd"` would correspond to a date +string like `"20140716"`. The parser distinguishes a fixed-width slot by the absence of a delimiter, +noting the transition `"yyyymm"` from one period character to the next. + +Support for text-form month parsing is also supported through the `u` and `U` characters, for +abbreviated and full-length month names, respectively. By default, only English month names are +supported, so `u` corresponds to "Jan", "Feb", "Mar", etc. And `U` corresponds to "January", "February", +"March", etc. Similar to other name=>value mapping functions [`dayname`](@ref) and [`monthname`](@ref), +custom locales can be loaded by passing in the `locale=>Dict{String,Int}` mapping to the `MONTHTOVALUEABBR` +and `MONTHTOVALUE` dicts for abbreviated and full-name month names, respectively. + +One note on parsing performance: using the `Date(date_string,format_string)` function is fine +if only called a few times. If there are many similarly formatted date strings to parse however, +it is much more efficient to first create a [`Dates.DateFormat`](@ref), and pass it instead of +a raw format string. + +```jldoctest +julia> df = DateFormat("y-m-d"); + +julia> dt = Date("2015-01-01",df) +2015-01-01 + +julia> dt2 = Date("2015-01-02",df) +2015-01-02 +``` + +You can also use the `dateformat""` string macro. This macro creates the `DateFormat` object once when the macro is expanded and uses the same `DateFormat` object even if a code snippet is run multiple times. + +```jldoctest +julia> for i = 1:10^5 + Date("2015-01-01", dateformat"y-m-d") + end +``` + +A full suite of parsing and formatting tests and examples is available in [`stdlib/Dates/test/io.jl`](https://github.com/JuliaLang/julia/blob/master/stdlib/Dates/test/io.jl). + +## Durations/Comparisons + +Finding the length of time between two [`Date`](@ref) or [`DateTime`](@ref) is straightforward +given their underlying representation as `UTInstant{Day}` and `UTInstant{Millisecond}`, respectively. +The difference between [`Date`](@ref) is returned in the number of [`Day`](@ref), and [`DateTime`](@ref) +in the number of [`Millisecond`](@ref). Similarly, comparing [`TimeType`](@ref) is a simple matter +of comparing the underlying machine instants (which in turn compares the internal [`Int64`](@ref) values). + +```jldoctest +julia> dt = Date(2012,2,29) +2012-02-29 + +julia> dt2 = Date(2000,2,1) +2000-02-01 + +julia> dump(dt) +Date + instant: Dates.UTInstant{Dates.Day} + periods: Dates.Day + value: Int64 734562 + +julia> dump(dt2) +Date + instant: Dates.UTInstant{Dates.Day} + periods: Dates.Day + value: Int64 730151 + +julia> dt > dt2 +true + +julia> dt != dt2 +true + +julia> dt + dt2 +ERROR: MethodError: no method matching +(::Date, ::Date) +[...] + +julia> dt * dt2 +ERROR: MethodError: no method matching *(::Date, ::Date) +[...] + +julia> dt / dt2 +ERROR: MethodError: no method matching /(::Date, ::Date) +[...] + +julia> dt - dt2 +4411 days + +julia> dt2 - dt +-4411 days + +julia> dt = DateTime(2012,2,29) +2012-02-29T00:00:00 + +julia> dt2 = DateTime(2000,2,1) +2000-02-01T00:00:00 + +julia> dt - dt2 +381110400000 milliseconds +``` + +## Accessor Functions + +Because the [`Date`](@ref) and [`DateTime`](@ref) types are stored as single [`Int64`](@ref) values, date +parts or fields can be retrieved through accessor functions. The lowercase accessors return the +field as an integer: + +```jldoctest tdate +julia> t = Date(2014, 1, 31) +2014-01-31 + +julia> Dates.year(t) +2014 + +julia> Dates.month(t) +1 + +julia> Dates.week(t) +5 + +julia> Dates.day(t) +31 +``` + +While propercase return the same value in the corresponding [`Period`](@ref) type: + +```jldoctest tdate +julia> Dates.Year(t) +2014 years + +julia> Dates.Day(t) +31 days +``` + +Compound methods are provided, as they provide a measure of efficiency if multiple fields are +needed at the same time: + +```jldoctest tdate +julia> Dates.yearmonth(t) +(2014, 1) + +julia> Dates.monthday(t) +(1, 31) + +julia> Dates.yearmonthday(t) +(2014, 1, 31) +``` + +One may also access the underlying `UTInstant` or integer value: + +```jldoctest tdate +julia> dump(t) +Date + instant: Dates.UTInstant{Dates.Day} + periods: Dates.Day + value: Int64 735264 + +julia> t.instant +Dates.UTInstant{Dates.Day}(735264 days) + +julia> Dates.value(t) +735264 +``` + +## Query Functions + +Query functions provide calendrical information about a [`TimeType`](@ref). They include information +about the day of the week: + +```jldoctest tdate2 +julia> t = Date(2014, 1, 31) +2014-01-31 + +julia> Dates.dayofweek(t) +5 + +julia> Dates.dayname(t) +"Friday" + +julia> Dates.dayofweekofmonth(t) # 5th Friday of January +5 +``` + +Month of the year: + +```jldoctest tdate2 +julia> Dates.monthname(t) +"January" + +julia> Dates.daysinmonth(t) +31 +``` + +As well as information about the [`TimeType`](@ref)'s year and quarter: + +```jldoctest tdate2 +julia> Dates.isleapyear(t) +false + +julia> Dates.dayofyear(t) +31 + +julia> Dates.quarterofyear(t) +1 + +julia> Dates.dayofquarter(t) +31 +``` + +The [`dayname`](@ref) and [`monthname`](@ref) methods can also take an optional `locale` keyword +that can be used to return the name of the day or month of the year for other languages/locales. +There are also versions of these functions returning the abbreviated names, namely +[`dayabbr`](@ref) and [`monthabbr`](@ref). +First the mapping is loaded into the `LOCALES` variable: + +```jldoctest tdate2 +julia> french_months = ["janvier", "février", "mars", "avril", "mai", "juin", + "juillet", "août", "septembre", "octobre", "novembre", "décembre"]; + +julia> french_monts_abbrev = ["janv","févr","mars","avril","mai","juin", + "juil","août","sept","oct","nov","déc"]; + +julia> french_days = ["lundi","mardi","mercredi","jeudi","vendredi","samedi","dimanche"]; + +julia> Dates.LOCALES["french"] = Dates.DateLocale(french_months, french_monts_abbrev, french_days, [""]); +``` + + The above mentioned functions can then be used to perform the queries: + +```jldoctest tdate2 +julia> Dates.dayname(t;locale="french") +"vendredi" + +julia> Dates.monthname(t;locale="french") +"janvier" + +julia> Dates.monthabbr(t;locale="french") +"janv" +``` + +Since the abbreviated versions of the days are not loaded, trying to use the +function `dayabbr` will error. + +```jldoctest tdate2 +julia> Dates.dayabbr(t;locale="french") +ERROR: BoundsError: attempt to access 1-element Array{String,1} at index [5] +Stacktrace: +[...] +``` + + +## TimeType-Period Arithmetic + +It's good practice when using any language/date framework to be familiar with how date-period +arithmetic is handled as there are some [tricky issues](https://codeblog.jonskeet.uk/2010/12/01/the-joys-of-date-time-arithmetic/) +to deal with (though much less so for day-precision types). + +The `Dates` module approach tries to follow the simple principle of trying to change as +little as possible when doing [`Period`](@ref) arithmetic. This approach is also often known as +*calendrical* arithmetic or what you would probably guess if someone were to ask you the same +calculation in a conversation. Why all the fuss about this? Let's take a classic example: add +1 month to January 31st, 2014. What's the answer? Javascript will say [March 3](http://www.markhneedham.com/blog/2009/01/07/javascript-add-a-month-to-a-date/) +(assumes 31 days). PHP says [March 2](https://stackoverflow.com/questions/5760262/php-adding-months-to-a-date-while-not-exceeding-the-last-day-of-the-month) +(assumes 30 days). The fact is, there is no right answer. In the `Dates` module, it gives +the result of February 28th. How does it figure that out? I like to think of the classic 7-7-7 +gambling game in casinos. + +Now just imagine that instead of 7-7-7, the slots are Year-Month-Day, or in our example, 2014-01-31. +When you ask to add 1 month to this date, the month slot is incremented, so now we have 2014-02-31. +Then the day number is checked if it is greater than the last valid day of the new month; if it +is (as in the case above), the day number is adjusted down to the last valid day (28). What are +the ramifications with this approach? Go ahead and add another month to our date, `2014-02-28 + Month(1) == 2014-03-28`. +What? Were you expecting the last day of March? Nope, sorry, remember the 7-7-7 slots. As few +slots as possible are going to change, so we first increment the month slot by 1, 2014-03-28, +and boom, we're done because that's a valid date. On the other hand, if we were to add 2 months +to our original date, 2014-01-31, then we end up with 2014-03-31, as expected. The other ramification +of this approach is a loss in associativity when a specific ordering is forced (i.e. adding things +in different orders results in different outcomes). For example: + +```jldoctest +julia> (Date(2014,1,29)+Dates.Day(1)) + Dates.Month(1) +2014-02-28 + +julia> (Date(2014,1,29)+Dates.Month(1)) + Dates.Day(1) +2014-03-01 +``` + +What's going on there? In the first line, we're adding 1 day to January 29th, which results in +2014-01-30; then we add 1 month, so we get 2014-02-30, which then adjusts down to 2014-02-28. +In the second example, we add 1 month *first*, where we get 2014-02-29, which adjusts down to +2014-02-28, and *then* add 1 day, which results in 2014-03-01. One design principle that helps +in this case is that, in the presence of multiple Periods, the operations will be ordered by the +Periods' *types*, not their value or positional order; this means `Year` will always be added +first, then `Month`, then `Week`, etc. Hence the following *does* result in associativity and +Just Works: + +```jldoctest +julia> Date(2014,1,29) + Dates.Day(1) + Dates.Month(1) +2014-03-01 + +julia> Date(2014,1,29) + Dates.Month(1) + Dates.Day(1) +2014-03-01 +``` + +Tricky? Perhaps. What is an innocent `Dates` user to do? The bottom line is to be aware +that explicitly forcing a certain associativity, when dealing with months, may lead to some unexpected +results, but otherwise, everything should work as expected. Thankfully, that's pretty much the +extent of the odd cases in date-period arithmetic when dealing with time in UT (avoiding the "joys" +of dealing with daylight savings, leap seconds, etc.). + +As a bonus, all period arithmetic objects work directly with ranges: + +```jldoctest +julia> dr = Date(2014,1,29):Date(2014,2,3) +2014-01-29:1 day:2014-02-03 + +julia> collect(dr) +6-element Array{Date,1}: + 2014-01-29 + 2014-01-30 + 2014-01-31 + 2014-02-01 + 2014-02-02 + 2014-02-03 + +julia> dr = Date(2014,1,29):Dates.Month(1):Date(2014,07,29) +2014-01-29:1 month:2014-07-29 + +julia> collect(dr) +7-element Array{Date,1}: + 2014-01-29 + 2014-02-28 + 2014-03-29 + 2014-04-29 + 2014-05-29 + 2014-06-29 + 2014-07-29 +``` + +## Adjuster Functions + +As convenient as date-period arithmetics are, often the kinds of calculations needed on dates +take on a *calendrical* or *temporal* nature rather than a fixed number of periods. Holidays are +a perfect example; most follow rules such as "Memorial Day = Last Monday of May", or "Thanksgiving += 4th Thursday of November". These kinds of temporal expressions deal with rules relative to the +calendar, like first or last of the month, next Tuesday, or the first and third Wednesdays, etc. + +The `Dates` module provides the *adjuster* API through several convenient methods that +aid in simply and succinctly expressing temporal rules. The first group of adjuster methods deal +with the first and last of weeks, months, quarters, and years. They each take a single [`TimeType`](@ref) +as input and return or *adjust to* the first or last of the desired period relative to the input. + +```jldoctest +julia> Dates.firstdayofweek(Date(2014,7,16)) # Adjusts the input to the Monday of the input's week +2014-07-14 + +julia> Dates.lastdayofmonth(Date(2014,7,16)) # Adjusts to the last day of the input's month +2014-07-31 + +julia> Dates.lastdayofquarter(Date(2014,7,16)) # Adjusts to the last day of the input's quarter +2014-09-30 +``` + +The next two higher-order methods, [`tonext`](@ref), and [`toprev`](@ref), generalize working +with temporal expressions by taking a `DateFunction` as first argument, along with a starting +[`TimeType`](@ref). A `DateFunction` is just a function, usually anonymous, that takes a single +[`TimeType`](@ref) as input and returns a [`Bool`](@ref), `true` indicating a satisfied +adjustment criterion. +For example: + +```jldoctest +julia> istuesday = x->Dates.dayofweek(x) == Dates.Tuesday; # Returns true if the day of the week of x is Tuesday + +julia> Dates.tonext(istuesday, Date(2014,7,13)) # 2014-07-13 is a Sunday +2014-07-15 + +julia> Dates.tonext(Date(2014,7,13), Dates.Tuesday) # Convenience method provided for day of the week adjustments +2014-07-15 +``` + +This is useful with the do-block syntax for more complex temporal expressions: + +```jldoctest +julia> Dates.tonext(Date(2014,7,13)) do x + # Return true on the 4th Thursday of November (Thanksgiving) + Dates.dayofweek(x) == Dates.Thursday && + Dates.dayofweekofmonth(x) == 4 && + Dates.month(x) == Dates.November + end +2014-11-27 +``` + +The [`Base.filter`](@ref) method can be used to obtain all valid dates/moments in a specified +range: + +```jldoctest +# Pittsburgh street cleaning; Every 2nd Tuesday from April to November +# Date range from January 1st, 2014 to January 1st, 2015 +julia> dr = Dates.Date(2014):Dates.Date(2015); + +julia> filter(dr) do x + Dates.dayofweek(x) == Dates.Tue && + Dates.April <= Dates.month(x) <= Dates.Nov && + Dates.dayofweekofmonth(x) == 2 + end +8-element Array{Date,1}: + 2014-04-08 + 2014-05-13 + 2014-06-10 + 2014-07-08 + 2014-08-12 + 2014-09-09 + 2014-10-14 + 2014-11-11 +``` + +Additional examples and tests are available in [`stdlib/Dates/test/adjusters.jl`](https://github.com/JuliaLang/julia/blob/master/stdlib/Dates/test/adjusters.jl). + +## Period Types + +Periods are a human view of discrete, sometimes irregular durations of time. Consider 1 month; +it could represent, in days, a value of 28, 29, 30, or 31 depending on the year and month context. +Or a year could represent 365 or 366 days in the case of a leap year. [`Period`](@ref) types are +simple [`Int64`](@ref) wrappers and are constructed by wrapping any `Int64` convertible type, i.e. `Year(1)` +or `Month(3.0)`. Arithmetic between [`Period`](@ref) of the same type behave like integers, and +limited `Period-Real` arithmetic is available. + +```jldoctest +julia> y1 = Dates.Year(1) +1 year + +julia> y2 = Dates.Year(2) +2 years + +julia> y3 = Dates.Year(10) +10 years + +julia> y1 + y2 +3 years + +julia> div(y3,y2) +5 + +julia> y3 - y2 +8 years + +julia> y3 % y2 +0 years + +julia> div(y3,3) # mirrors integer division +3 years +``` + +## Rounding + +[`Date`](@ref) and [`DateTime`](@ref) values can be rounded to a specified resolution (e.g., 1 +month or 15 minutes) with [`floor`](@ref), [`ceil`](@ref), or [`round`](@ref): + +```jldoctest +julia> floor(Date(1985, 8, 16), Dates.Month) +1985-08-01 + +julia> ceil(DateTime(2013, 2, 13, 0, 31, 20), Dates.Minute(15)) +2013-02-13T00:45:00 + +julia> round(DateTime(2016, 8, 6, 20, 15), Dates.Day) +2016-08-07T00:00:00 +``` + +Unlike the numeric [`round`](@ref) method, which breaks ties toward the even number by default, +the [`TimeType`](@ref)[`round`](@ref) method uses the `RoundNearestTiesUp` rounding mode. (It's +difficult to guess what breaking ties to nearest "even" [`TimeType`](@ref) would entail.) Further +details on the available `RoundingMode` s can be found in the [API reference](@ref stdlib-dates). + +Rounding should generally behave as expected, but there are a few cases in which the expected +behaviour is not obvious. + +### Rounding Epoch + +In many cases, the resolution specified for rounding (e.g., `Dates.Second(30)`) divides evenly +into the next largest period (in this case, `Dates.Minute(1)`). But rounding behaviour in cases +in which this is not true may lead to confusion. What is the expected result of rounding a [`DateTime`](@ref) +to the nearest 10 hours? + +```jldoctest +julia> round(DateTime(2016, 7, 17, 11, 55), Dates.Hour(10)) +2016-07-17T12:00:00 +``` + +That may seem confusing, given that the hour (12) is not divisible by 10. The reason that `2016-07-17T12:00:00` +was chosen is that it is 17,676,660 hours after `0000-01-01T00:00:00`, and 17,676,660 is divisible +by 10. + +As Julia [`Date`](@ref) and [`DateTime`](@ref) values are represented according to the ISO 8601 +standard, `0000-01-01T00:00:00` was chosen as base (or "rounding epoch") from which to begin the +count of days (and milliseconds) used in rounding calculations. (Note that this differs slightly +from Julia's internal representation of [`Date`](@ref) s using Rata Die notation; but since the +ISO 8601 standard is most visible to the end user, `0000-01-01T00:00:00` was chosen as the rounding +epoch instead of the `0000-12-31T00:00:00` used internally to minimize confusion.) + +The only exception to the use of `0000-01-01T00:00:00` as the rounding epoch is when rounding +to weeks. Rounding to the nearest week will always return a Monday (the first day of the week +as specified by ISO 8601). For this reason, we use `0000-01-03T00:00:00` (the first day of the +first week of year 0000, as defined by ISO 8601) as the base when rounding to a number of weeks. + +Here is a related case in which the expected behaviour is not necessarily obvious: What happens +when we round to the nearest `P(2)`, where `P` is a [`Period`](@ref) type? In some cases (specifically, +when `P <: Dates.TimePeriod`) the answer is clear: + +```jldoctest +julia> round(DateTime(2016, 7, 17, 8, 55, 30), Dates.Hour(2)) +2016-07-17T08:00:00 + +julia> round(DateTime(2016, 7, 17, 8, 55, 30), Dates.Minute(2)) +2016-07-17T08:56:00 +``` + +This seems obvious, because two of each of these periods still divides evenly into the next larger +order period. But in the case of two months (which still divides evenly into one year), the answer +may be surprising: + +```jldoctest +julia> round(DateTime(2016, 7, 17, 8, 55, 30), Dates.Month(2)) +2016-07-01T00:00:00 +``` + +Why round to the first day in July, even though it is month 7 (an odd number)? The key is that +months are 1-indexed (the first month is assigned 1), unlike hours, minutes, seconds, and milliseconds +(the first of which are assigned 0). + +This means that rounding a [`DateTime`](@ref) to an even multiple of seconds, minutes, hours, +or years (because the ISO 8601 specification includes a year zero) will result in a [`DateTime`](@ref) +with an even value in that field, while rounding a [`DateTime`](@ref) to an even multiple of months +will result in the months field having an odd value. Because both months and years may contain +an irregular number of days, whether rounding to an even number of days will result in an even +value in the days field is uncertain. + +See the [API reference](@ref stdlib-dates-api) for additional information +on methods exported from the `Dates` module. + +# [API reference](@id stdlib-dates-api) ## Dates and Time Types diff --git a/codex/stdlib/REPL.md b/codex/stdlib/REPL.md index 34422a2..68b3937 100644 --- a/codex/stdlib/REPL.md +++ b/codex/stdlib/REPL.md @@ -191,7 +191,7 @@ Meta plus `x` can be written `"\\Mx"`. The values of the custom keymap must be ` that the input should be ignored) or functions that accept the signature `(PromptState, AbstractREPL, Char)`. The `REPL.setup_interface` function must be called before the REPL is initialized, by registering the operation with [`atreplinit`](@ref) . For example, to bind the up and down arrow keys to move through -history without prefix search, one could put the following code in `.juliarc.jl`: +history without prefix search, one could put the following code in `~/.julia/config/startup.jl`: ```julia import REPL @@ -324,7 +324,7 @@ fields if the function is type stable. The colors used by Julia and the REPL can be customized, as well. To change the color of the Julia prompt you can add something like the following to your -`.juliarc.jl` file, which is to be placed inside your home directory: +`~/.julia/config/startup.jl` file, which is to be placed inside your home directory: ```julia function customize_colors(repl) @@ -345,7 +345,7 @@ latter two, be sure that the `envcolors` field is also set to false. It is also possible to apply boldface formatting by using `Base.text_colors[:bold]` as a color. For instance, to print answers in -boldface font, one can use the following as a `.juliarc.jl`: +boldface font, one can use the following as a `~/.julia/config/startup.jl`: ```julia function customize_colors(repl) @@ -358,7 +358,8 @@ atreplinit(customize_colors) You can also customize the color used to render warning and informational messages by setting the appropriate environment variables. For instance, to render error, warning, and informational -messages respectively in magenta, yellow, and cyan you can add the following to your `.juliarc.jl` file: +messages respectively in magenta, yellow, and cyan you can add the following to your +`~/.julia/config/startup.jl` file: ```julia ENV["JULIA_ERROR_COLOR"] = :magenta diff --git a/codex/stdlib/dates.md b/codex/stdlib/dates.md index 3abee48..2b3adef 100644 --- a/codex/stdlib/dates.md +++ b/codex/stdlib/dates.md @@ -1,14 +1,633 @@ -# [Dates and Time](@id stdlib-dates) +# Dates ```@meta DocTestSetup = :(using Dates) ``` -Functionality to handle time and dates is defined in the standard library module `Dates`. -You'll need to import the module using `import Dates` and prefix each -function call with an explicit `Dates.`, e.g. `Dates.dayofweek(dt)`. Alternatively, you can write -`using Dates` to bring all exported functions into `Main` to be used without the `Dates.` -prefix. +The `Dates` module provides two types for working with dates: [`Date`](@ref) and [`DateTime`](@ref), +representing day and millisecond precision, respectively; both are subtypes of the abstract [`TimeType`](@ref). +The motivation for distinct types is simple: some operations are much simpler, both in terms of +code and mental reasoning, when the complexities of greater precision don't have to be dealt with. +For example, since the [`Date`](@ref) type only resolves to the precision of a single date (i.e. +no hours, minutes, or seconds), normal considerations for time zones, daylight savings/summer +time, and leap seconds are unnecessary and avoided. + +Both [`Date`](@ref) and [`DateTime`](@ref) are basically immutable [`Int64`](@ref) wrappers. +The single `instant` field of either type is actually a `UTInstant{P}` type, which +represents a continuously increasing machine timeline based on the UT second [^1]. The +[`DateTime`](@ref) type is not aware of time zones (*naive*, in Python parlance), +analogous to a *LocalDateTime* in Java 8. Additional time zone functionality +can be added through the [TimeZones.jl package](https://github.com/JuliaTime/TimeZones.jl/), which +compiles the [IANA time zone database](http://www.iana.org/time-zones). Both [`Date`](@ref) and +[`DateTime`](@ref) are based on the [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) standard, which follows the proleptic Gregorian calendar. +One note is that the ISO 8601 standard is particular about BC/BCE dates. In general, the last +day of the BC/BCE era, 1-12-31 BC/BCE, was followed by 1-1-1 AD/CE, thus no year zero exists. +The ISO standard, however, states that 1 BC/BCE is year zero, so `0000-12-31` is the day before +`0001-01-01`, and year `-0001` (yes, negative one for the year) is 2 BC/BCE, year `-0002` is 3 +BC/BCE, etc. + +[^1]: + The notion of the UT second is actually quite fundamental. There are basically two different notions + of time generally accepted, one based on the physical rotation of the earth (one full rotation + = 1 day), the other based on the SI second (a fixed, constant value). These are radically different! + Think about it, a "UT second", as defined relative to the rotation of the earth, may have a different + absolute length depending on the day! Anyway, the fact that [`Date`](@ref) and [`DateTime`](@ref) + are based on UT seconds is a simplifying, yet honest assumption so that things like leap seconds + and all their complexity can be avoided. This basis of time is formally called [UT](https://en.wikipedia.org/wiki/Universal_Time) + or UT1. Basing types on the UT second basically means that every minute has 60 seconds and every + day has 24 hours and leads to more natural calculations when working with calendar dates. + +## Constructors + +[`Date`](@ref) and [`DateTime`](@ref) types can be constructed by integer or [`Period`](@ref) +types, by parsing, or through adjusters (more on those later): + +```jldoctest +julia> DateTime(2013) +2013-01-01T00:00:00 + +julia> DateTime(2013,7) +2013-07-01T00:00:00 + +julia> DateTime(2013,7,1) +2013-07-01T00:00:00 + +julia> DateTime(2013,7,1,12) +2013-07-01T12:00:00 + +julia> DateTime(2013,7,1,12,30) +2013-07-01T12:30:00 + +julia> DateTime(2013,7,1,12,30,59) +2013-07-01T12:30:59 + +julia> DateTime(2013,7,1,12,30,59,1) +2013-07-01T12:30:59.001 + +julia> Date(2013) +2013-01-01 + +julia> Date(2013,7) +2013-07-01 + +julia> Date(2013,7,1) +2013-07-01 + +julia> Date(Dates.Year(2013),Dates.Month(7),Dates.Day(1)) +2013-07-01 + +julia> Date(Dates.Month(7),Dates.Year(2013)) +2013-07-01 +``` + +[`Date`](@ref) or [`DateTime`](@ref) parsing is accomplished by the use of format strings. Format +strings work by the notion of defining *delimited* or *fixed-width* "slots" that contain a period +to parse and passing the text to parse and format string to a [`Date`](@ref) or [`DateTime`](@ref) +constructor, of the form `Date("2015-01-01","y-m-d")` or `DateTime("20150101","yyyymmdd")`. + +Delimited slots are marked by specifying the delimiter the parser should expect between two subsequent +periods; so `"y-m-d"` lets the parser know that between the first and second slots in a date string +like `"2014-07-16"`, it should find the `-` character. The `y`, `m`, and `d` characters let the +parser know which periods to parse in each slot. + +Fixed-width slots are specified by repeating the period character the number of times corresponding +to the width with no delimiter between characters. So `"yyyymmdd"` would correspond to a date +string like `"20140716"`. The parser distinguishes a fixed-width slot by the absence of a delimiter, +noting the transition `"yyyymm"` from one period character to the next. + +Support for text-form month parsing is also supported through the `u` and `U` characters, for +abbreviated and full-length month names, respectively. By default, only English month names are +supported, so `u` corresponds to "Jan", "Feb", "Mar", etc. And `U` corresponds to "January", "February", +"March", etc. Similar to other name=>value mapping functions [`dayname`](@ref) and [`monthname`](@ref), +custom locales can be loaded by passing in the `locale=>Dict{String,Int}` mapping to the `MONTHTOVALUEABBR` +and `MONTHTOVALUE` dicts for abbreviated and full-name month names, respectively. + +One note on parsing performance: using the `Date(date_string,format_string)` function is fine +if only called a few times. If there are many similarly formatted date strings to parse however, +it is much more efficient to first create a [`Dates.DateFormat`](@ref), and pass it instead of +a raw format string. + +```jldoctest +julia> df = DateFormat("y-m-d"); + +julia> dt = Date("2015-01-01",df) +2015-01-01 + +julia> dt2 = Date("2015-01-02",df) +2015-01-02 +``` + +You can also use the `dateformat""` string macro. This macro creates the `DateFormat` object once when the macro is expanded and uses the same `DateFormat` object even if a code snippet is run multiple times. + +```jldoctest +julia> for i = 1:10^5 + Date("2015-01-01", dateformat"y-m-d") + end +``` + +A full suite of parsing and formatting tests and examples is available in [`stdlib/Dates/test/io.jl`](https://github.com/JuliaLang/julia/blob/master/stdlib/Dates/test/io.jl). + +## Durations/Comparisons + +Finding the length of time between two [`Date`](@ref) or [`DateTime`](@ref) is straightforward +given their underlying representation as `UTInstant{Day}` and `UTInstant{Millisecond}`, respectively. +The difference between [`Date`](@ref) is returned in the number of [`Day`](@ref), and [`DateTime`](@ref) +in the number of [`Millisecond`](@ref). Similarly, comparing [`TimeType`](@ref) is a simple matter +of comparing the underlying machine instants (which in turn compares the internal [`Int64`](@ref) values). + +```jldoctest +julia> dt = Date(2012,2,29) +2012-02-29 + +julia> dt2 = Date(2000,2,1) +2000-02-01 + +julia> dump(dt) +Date + instant: Dates.UTInstant{Dates.Day} + periods: Dates.Day + value: Int64 734562 + +julia> dump(dt2) +Date + instant: Dates.UTInstant{Dates.Day} + periods: Dates.Day + value: Int64 730151 + +julia> dt > dt2 +true + +julia> dt != dt2 +true + +julia> dt + dt2 +ERROR: MethodError: no method matching +(::Date, ::Date) +[...] + +julia> dt * dt2 +ERROR: MethodError: no method matching *(::Date, ::Date) +[...] + +julia> dt / dt2 +ERROR: MethodError: no method matching /(::Date, ::Date) +[...] + +julia> dt - dt2 +4411 days + +julia> dt2 - dt +-4411 days + +julia> dt = DateTime(2012,2,29) +2012-02-29T00:00:00 + +julia> dt2 = DateTime(2000,2,1) +2000-02-01T00:00:00 + +julia> dt - dt2 +381110400000 milliseconds +``` + +## Accessor Functions + +Because the [`Date`](@ref) and [`DateTime`](@ref) types are stored as single [`Int64`](@ref) values, date +parts or fields can be retrieved through accessor functions. The lowercase accessors return the +field as an integer: + +```jldoctest tdate +julia> t = Date(2014, 1, 31) +2014-01-31 + +julia> Dates.year(t) +2014 + +julia> Dates.month(t) +1 + +julia> Dates.week(t) +5 + +julia> Dates.day(t) +31 +``` + +While propercase return the same value in the corresponding [`Period`](@ref) type: + +```jldoctest tdate +julia> Dates.Year(t) +2014 years + +julia> Dates.Day(t) +31 days +``` + +Compound methods are provided, as they provide a measure of efficiency if multiple fields are +needed at the same time: + +```jldoctest tdate +julia> Dates.yearmonth(t) +(2014, 1) + +julia> Dates.monthday(t) +(1, 31) + +julia> Dates.yearmonthday(t) +(2014, 1, 31) +``` + +One may also access the underlying `UTInstant` or integer value: + +```jldoctest tdate +julia> dump(t) +Date + instant: Dates.UTInstant{Dates.Day} + periods: Dates.Day + value: Int64 735264 + +julia> t.instant +Dates.UTInstant{Dates.Day}(735264 days) + +julia> Dates.value(t) +735264 +``` + +## Query Functions + +Query functions provide calendrical information about a [`TimeType`](@ref). They include information +about the day of the week: + +```jldoctest tdate2 +julia> t = Date(2014, 1, 31) +2014-01-31 + +julia> Dates.dayofweek(t) +5 + +julia> Dates.dayname(t) +"Friday" + +julia> Dates.dayofweekofmonth(t) # 5th Friday of January +5 +``` + +Month of the year: + +```jldoctest tdate2 +julia> Dates.monthname(t) +"January" + +julia> Dates.daysinmonth(t) +31 +``` + +As well as information about the [`TimeType`](@ref)'s year and quarter: + +```jldoctest tdate2 +julia> Dates.isleapyear(t) +false + +julia> Dates.dayofyear(t) +31 + +julia> Dates.quarterofyear(t) +1 + +julia> Dates.dayofquarter(t) +31 +``` + +The [`dayname`](@ref) and [`monthname`](@ref) methods can also take an optional `locale` keyword +that can be used to return the name of the day or month of the year for other languages/locales. +There are also versions of these functions returning the abbreviated names, namely +[`dayabbr`](@ref) and [`monthabbr`](@ref). +First the mapping is loaded into the `LOCALES` variable: + +```jldoctest tdate2 +julia> french_months = ["janvier", "février", "mars", "avril", "mai", "juin", + "juillet", "août", "septembre", "octobre", "novembre", "décembre"]; + +julia> french_monts_abbrev = ["janv","févr","mars","avril","mai","juin", + "juil","août","sept","oct","nov","déc"]; + +julia> french_days = ["lundi","mardi","mercredi","jeudi","vendredi","samedi","dimanche"]; + +julia> Dates.LOCALES["french"] = Dates.DateLocale(french_months, french_monts_abbrev, french_days, [""]); +``` + + The above mentioned functions can then be used to perform the queries: + +```jldoctest tdate2 +julia> Dates.dayname(t;locale="french") +"vendredi" + +julia> Dates.monthname(t;locale="french") +"janvier" + +julia> Dates.monthabbr(t;locale="french") +"janv" +``` + +Since the abbreviated versions of the days are not loaded, trying to use the +function `dayabbr` will error. + +```jldoctest tdate2 +julia> Dates.dayabbr(t;locale="french") +ERROR: BoundsError: attempt to access 1-element Array{String,1} at index [5] +Stacktrace: +[...] +``` + + +## TimeType-Period Arithmetic + +It's good practice when using any language/date framework to be familiar with how date-period +arithmetic is handled as there are some [tricky issues](https://codeblog.jonskeet.uk/2010/12/01/the-joys-of-date-time-arithmetic/) +to deal with (though much less so for day-precision types). + +The `Dates` module approach tries to follow the simple principle of trying to change as +little as possible when doing [`Period`](@ref) arithmetic. This approach is also often known as +*calendrical* arithmetic or what you would probably guess if someone were to ask you the same +calculation in a conversation. Why all the fuss about this? Let's take a classic example: add +1 month to January 31st, 2014. What's the answer? Javascript will say [March 3](http://www.markhneedham.com/blog/2009/01/07/javascript-add-a-month-to-a-date/) +(assumes 31 days). PHP says [March 2](https://stackoverflow.com/questions/5760262/php-adding-months-to-a-date-while-not-exceeding-the-last-day-of-the-month) +(assumes 30 days). The fact is, there is no right answer. In the `Dates` module, it gives +the result of February 28th. How does it figure that out? I like to think of the classic 7-7-7 +gambling game in casinos. + +Now just imagine that instead of 7-7-7, the slots are Year-Month-Day, or in our example, 2014-01-31. +When you ask to add 1 month to this date, the month slot is incremented, so now we have 2014-02-31. +Then the day number is checked if it is greater than the last valid day of the new month; if it +is (as in the case above), the day number is adjusted down to the last valid day (28). What are +the ramifications with this approach? Go ahead and add another month to our date, `2014-02-28 + Month(1) == 2014-03-28`. +What? Were you expecting the last day of March? Nope, sorry, remember the 7-7-7 slots. As few +slots as possible are going to change, so we first increment the month slot by 1, 2014-03-28, +and boom, we're done because that's a valid date. On the other hand, if we were to add 2 months +to our original date, 2014-01-31, then we end up with 2014-03-31, as expected. The other ramification +of this approach is a loss in associativity when a specific ordering is forced (i.e. adding things +in different orders results in different outcomes). For example: + +```jldoctest +julia> (Date(2014,1,29)+Dates.Day(1)) + Dates.Month(1) +2014-02-28 + +julia> (Date(2014,1,29)+Dates.Month(1)) + Dates.Day(1) +2014-03-01 +``` + +What's going on there? In the first line, we're adding 1 day to January 29th, which results in +2014-01-30; then we add 1 month, so we get 2014-02-30, which then adjusts down to 2014-02-28. +In the second example, we add 1 month *first*, where we get 2014-02-29, which adjusts down to +2014-02-28, and *then* add 1 day, which results in 2014-03-01. One design principle that helps +in this case is that, in the presence of multiple Periods, the operations will be ordered by the +Periods' *types*, not their value or positional order; this means `Year` will always be added +first, then `Month`, then `Week`, etc. Hence the following *does* result in associativity and +Just Works: + +```jldoctest +julia> Date(2014,1,29) + Dates.Day(1) + Dates.Month(1) +2014-03-01 + +julia> Date(2014,1,29) + Dates.Month(1) + Dates.Day(1) +2014-03-01 +``` + +Tricky? Perhaps. What is an innocent `Dates` user to do? The bottom line is to be aware +that explicitly forcing a certain associativity, when dealing with months, may lead to some unexpected +results, but otherwise, everything should work as expected. Thankfully, that's pretty much the +extent of the odd cases in date-period arithmetic when dealing with time in UT (avoiding the "joys" +of dealing with daylight savings, leap seconds, etc.). + +As a bonus, all period arithmetic objects work directly with ranges: + +```jldoctest +julia> dr = Date(2014,1,29):Date(2014,2,3) +2014-01-29:1 day:2014-02-03 + +julia> collect(dr) +6-element Array{Date,1}: + 2014-01-29 + 2014-01-30 + 2014-01-31 + 2014-02-01 + 2014-02-02 + 2014-02-03 + +julia> dr = Date(2014,1,29):Dates.Month(1):Date(2014,07,29) +2014-01-29:1 month:2014-07-29 + +julia> collect(dr) +7-element Array{Date,1}: + 2014-01-29 + 2014-02-28 + 2014-03-29 + 2014-04-29 + 2014-05-29 + 2014-06-29 + 2014-07-29 +``` + +## Adjuster Functions + +As convenient as date-period arithmetics are, often the kinds of calculations needed on dates +take on a *calendrical* or *temporal* nature rather than a fixed number of periods. Holidays are +a perfect example; most follow rules such as "Memorial Day = Last Monday of May", or "Thanksgiving += 4th Thursday of November". These kinds of temporal expressions deal with rules relative to the +calendar, like first or last of the month, next Tuesday, or the first and third Wednesdays, etc. + +The `Dates` module provides the *adjuster* API through several convenient methods that +aid in simply and succinctly expressing temporal rules. The first group of adjuster methods deal +with the first and last of weeks, months, quarters, and years. They each take a single [`TimeType`](@ref) +as input and return or *adjust to* the first or last of the desired period relative to the input. + +```jldoctest +julia> Dates.firstdayofweek(Date(2014,7,16)) # Adjusts the input to the Monday of the input's week +2014-07-14 + +julia> Dates.lastdayofmonth(Date(2014,7,16)) # Adjusts to the last day of the input's month +2014-07-31 + +julia> Dates.lastdayofquarter(Date(2014,7,16)) # Adjusts to the last day of the input's quarter +2014-09-30 +``` + +The next two higher-order methods, [`tonext`](@ref), and [`toprev`](@ref), generalize working +with temporal expressions by taking a `DateFunction` as first argument, along with a starting +[`TimeType`](@ref). A `DateFunction` is just a function, usually anonymous, that takes a single +[`TimeType`](@ref) as input and returns a [`Bool`](@ref), `true` indicating a satisfied +adjustment criterion. +For example: + +```jldoctest +julia> istuesday = x->Dates.dayofweek(x) == Dates.Tuesday; # Returns true if the day of the week of x is Tuesday + +julia> Dates.tonext(istuesday, Date(2014,7,13)) # 2014-07-13 is a Sunday +2014-07-15 + +julia> Dates.tonext(Date(2014,7,13), Dates.Tuesday) # Convenience method provided for day of the week adjustments +2014-07-15 +``` + +This is useful with the do-block syntax for more complex temporal expressions: + +```jldoctest +julia> Dates.tonext(Date(2014,7,13)) do x + # Return true on the 4th Thursday of November (Thanksgiving) + Dates.dayofweek(x) == Dates.Thursday && + Dates.dayofweekofmonth(x) == 4 && + Dates.month(x) == Dates.November + end +2014-11-27 +``` + +The [`Base.filter`](@ref) method can be used to obtain all valid dates/moments in a specified +range: + +```jldoctest +# Pittsburgh street cleaning; Every 2nd Tuesday from April to November +# Date range from January 1st, 2014 to January 1st, 2015 +julia> dr = Dates.Date(2014):Dates.Date(2015); + +julia> filter(dr) do x + Dates.dayofweek(x) == Dates.Tue && + Dates.April <= Dates.month(x) <= Dates.Nov && + Dates.dayofweekofmonth(x) == 2 + end +8-element Array{Date,1}: + 2014-04-08 + 2014-05-13 + 2014-06-10 + 2014-07-08 + 2014-08-12 + 2014-09-09 + 2014-10-14 + 2014-11-11 +``` + +Additional examples and tests are available in [`stdlib/Dates/test/adjusters.jl`](https://github.com/JuliaLang/julia/blob/master/stdlib/Dates/test/adjusters.jl). + +## Period Types + +Periods are a human view of discrete, sometimes irregular durations of time. Consider 1 month; +it could represent, in days, a value of 28, 29, 30, or 31 depending on the year and month context. +Or a year could represent 365 or 366 days in the case of a leap year. [`Period`](@ref) types are +simple [`Int64`](@ref) wrappers and are constructed by wrapping any `Int64` convertible type, i.e. `Year(1)` +or `Month(3.0)`. Arithmetic between [`Period`](@ref) of the same type behave like integers, and +limited `Period-Real` arithmetic is available. + +```jldoctest +julia> y1 = Dates.Year(1) +1 year + +julia> y2 = Dates.Year(2) +2 years + +julia> y3 = Dates.Year(10) +10 years + +julia> y1 + y2 +3 years + +julia> div(y3,y2) +5 + +julia> y3 - y2 +8 years + +julia> y3 % y2 +0 years + +julia> div(y3,3) # mirrors integer division +3 years +``` + +## Rounding + +[`Date`](@ref) and [`DateTime`](@ref) values can be rounded to a specified resolution (e.g., 1 +month or 15 minutes) with [`floor`](@ref), [`ceil`](@ref), or [`round`](@ref): + +```jldoctest +julia> floor(Date(1985, 8, 16), Dates.Month) +1985-08-01 + +julia> ceil(DateTime(2013, 2, 13, 0, 31, 20), Dates.Minute(15)) +2013-02-13T00:45:00 + +julia> round(DateTime(2016, 8, 6, 20, 15), Dates.Day) +2016-08-07T00:00:00 +``` + +Unlike the numeric [`round`](@ref) method, which breaks ties toward the even number by default, +the [`TimeType`](@ref)[`round`](@ref) method uses the `RoundNearestTiesUp` rounding mode. (It's +difficult to guess what breaking ties to nearest "even" [`TimeType`](@ref) would entail.) Further +details on the available `RoundingMode` s can be found in the [API reference](@ref stdlib-dates). + +Rounding should generally behave as expected, but there are a few cases in which the expected +behaviour is not obvious. + +### Rounding Epoch + +In many cases, the resolution specified for rounding (e.g., `Dates.Second(30)`) divides evenly +into the next largest period (in this case, `Dates.Minute(1)`). But rounding behaviour in cases +in which this is not true may lead to confusion. What is the expected result of rounding a [`DateTime`](@ref) +to the nearest 10 hours? + +```jldoctest +julia> round(DateTime(2016, 7, 17, 11, 55), Dates.Hour(10)) +2016-07-17T12:00:00 +``` + +That may seem confusing, given that the hour (12) is not divisible by 10. The reason that `2016-07-17T12:00:00` +was chosen is that it is 17,676,660 hours after `0000-01-01T00:00:00`, and 17,676,660 is divisible +by 10. + +As Julia [`Date`](@ref) and [`DateTime`](@ref) values are represented according to the ISO 8601 +standard, `0000-01-01T00:00:00` was chosen as base (or "rounding epoch") from which to begin the +count of days (and milliseconds) used in rounding calculations. (Note that this differs slightly +from Julia's internal representation of [`Date`](@ref) s using Rata Die notation; but since the +ISO 8601 standard is most visible to the end user, `0000-01-01T00:00:00` was chosen as the rounding +epoch instead of the `0000-12-31T00:00:00` used internally to minimize confusion.) + +The only exception to the use of `0000-01-01T00:00:00` as the rounding epoch is when rounding +to weeks. Rounding to the nearest week will always return a Monday (the first day of the week +as specified by ISO 8601). For this reason, we use `0000-01-03T00:00:00` (the first day of the +first week of year 0000, as defined by ISO 8601) as the base when rounding to a number of weeks. + +Here is a related case in which the expected behaviour is not necessarily obvious: What happens +when we round to the nearest `P(2)`, where `P` is a [`Period`](@ref) type? In some cases (specifically, +when `P <: Dates.TimePeriod`) the answer is clear: + +```jldoctest +julia> round(DateTime(2016, 7, 17, 8, 55, 30), Dates.Hour(2)) +2016-07-17T08:00:00 + +julia> round(DateTime(2016, 7, 17, 8, 55, 30), Dates.Minute(2)) +2016-07-17T08:56:00 +``` + +This seems obvious, because two of each of these periods still divides evenly into the next larger +order period. But in the case of two months (which still divides evenly into one year), the answer +may be surprising: + +```jldoctest +julia> round(DateTime(2016, 7, 17, 8, 55, 30), Dates.Month(2)) +2016-07-01T00:00:00 +``` + +Why round to the first day in July, even though it is month 7 (an odd number)? The key is that +months are 1-indexed (the first month is assigned 1), unlike hours, minutes, seconds, and milliseconds +(the first of which are assigned 0). + +This means that rounding a [`DateTime`](@ref) to an even multiple of seconds, minutes, hours, +or years (because the ISO 8601 specification includes a year zero) will result in a [`DateTime`](@ref) +with an even value in that field, while rounding a [`DateTime`](@ref) to an even multiple of months +will result in the months field having an odd value. Because both months and years may contain +an irregular number of days, whether rounding to an even number of days will result in an even +value in the days field is uncertain. + +See the [API reference](@ref stdlib-dates-api) for additional information +on methods exported from the `Dates` module. + +# [API reference](@id stdlib-dates-api) ## Dates and Time Types diff --git a/make.jl b/make.jl index fa66f20..34db692 100644 --- a/make.jl +++ b/make.jl @@ -57,7 +57,6 @@ const PAGES = [ "manual/missing.md", "manual/networking-and-streams.md", "manual/parallel-computing.md", - "manual/dates.md", "manual/running-external-programs.md", "manual/calling-c-and-fortran-code.md", "manual/handling-operating-system-variation.md", diff --git a/src/NEWS.md b/src/NEWS.md index 85d84a8..a09d1bf 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -187,6 +187,9 @@ Language changes * `=>` now has its own precedence level, giving it strictly higher precedence than `=` and `,` ([#25391](https://github.com/JuliaLang/julia/issues/25391)). + * The conditions under which unary operators followed by `(` are parsed as prefix function + calls have changed ([#26154](https://github.com/JuliaLang/julia/issues/26154)). + * `begin` is disallowed inside indexing expressions, in order to enable the syntax `a[begin]` (for selecting the first element) in the future ([#23354](https://github.com/JuliaLang/julia/issues/23354)). @@ -251,7 +254,10 @@ This section lists changes that do not have deprecation warnings. of the socket. Previously the address of the remote endpoint was being returned ([#21825](https://github.com/JuliaLang/julia/issues/21825)). - * Using `ARGS` within the ~/.juliarc.jl or within a .jl file loaded with `--load` will no + * The `~/.juliarc.jl` file has been moved to `~/.julia/config/startup.jl` and + `/etc/julia/juliarc.jl` file has been renamed to `/etc/julia/startup.jl` ([#26161](https://github.com/JuliaLang/julia/issues/26161)). + + * Using `ARGS` within `startup.jl` files or within a .jl file loaded with `--load` will no longer contain the script name as the first argument. Instead, the script name will be assigned to `PROGRAM_FILE`. ([#22092](https://github.com/JuliaLang/julia/issues/22092)) @@ -789,7 +795,7 @@ Deprecated or removed * Calling `write` on non-isbits arrays is deprecated in favor of explicit loops or `serialize` ([#6466](https://github.com/JuliaLang/julia/issues/6466)). - * The default `juliarc.jl` file on Windows has been removed. Now must explicitly include the + * The default `startup.jl` file on Windows has been removed. Now must explicitly include the full path if you need access to executables or libraries in the `Sys.BINDIR` directory, e.g. `joinpath(Sys.BINDIR, "7z.exe")` for `7z.exe` ([#21540](https://github.com/JuliaLang/julia/issues/21540)). @@ -1060,6 +1066,9 @@ Deprecated or removed * The fallback method `^(x, p::Integer)` is deprecated. If your type relied on this definition, add a method such as `^(x::MyType, p::Integer) = Base.power_by_squaring(x, p)` ([#23332](https://github.com/JuliaLang/julia/issues/23332)). + * `DevNull`, `STDIN`, `STDOUT`, and `STDERR` have been renamed to `devnull`, `stdin`, `stdout`, + and `stderr`, respectively ([#25786](https://github.com/JuliaLang/julia/issues/25786)). + * `wait` and `fetch` on `Task` now resemble the interface of `Future` Command-line option changes diff --git a/src/base/base.md b/src/base/base.md index bdb3264..254dc03 100644 --- a/src/base/base.md +++ b/src/base/base.md @@ -230,7 +230,7 @@ Base.skipmissing ```@docs Base.run Base.spawn -Base.DevNull +Base.devnull Base.success Base.process_running Base.process_exited @@ -274,7 +274,6 @@ Core.throw Base.rethrow Base.backtrace Base.catch_backtrace -Base.assert Base.@assert Base.ArgumentError Base.AssertionError diff --git a/src/base/constants.md b/src/base/constants.md index 0f4c321..b56659e 100644 --- a/src/base/constants.md +++ b/src/base/constants.md @@ -17,9 +17,9 @@ Base.Sys.MACHINE See also: - * [`STDIN`](@ref) - * [`STDOUT`](@ref) - * [`STDERR`](@ref) + * [`stdin`](@ref) + * [`stdout`](@ref) + * [`stderr`](@ref) * [`ENV`](@ref) * [`ENDIAN_BOM`](@ref) * `Libc.MS_ASYNC` diff --git a/src/base/index.md b/src/base/index.md deleted file mode 100644 index 637a62a..0000000 --- a/src/base/index.md +++ /dev/null @@ -1,36 +0,0 @@ -# The Julia Standard Library - - * [Essentials](@ref) - * [Collections and Data Structures](@ref) - * [Mathematics](@ref) - * [Numbers](@ref lib-numbers) - * [Strings](@ref lib-strings) - * [Arrays](@ref lib-arrays) - * [Tasks](@ref) - * [Distributed Computing](@ref) - * [Shared Arrays](@ref) - * [Multi-Threading](@ref) - * [Constants](@ref lib-constants) - * [Filesystem](@ref) - * [Delimited Files](@ref) - * [I/O and Network](@ref) - * [Punctuation](@ref) - * [Sorting and Related Functions](@ref) - * [Package Manager Functions](@ref) - * [Dates and Time](@ref stdlib-dates) - * [Iteration utilities](@ref) - * [Unit Testing](@ref) - * [C Interface](@ref) - * [LLVM Interface](@ref) - * [C Standard Library](@ref) - * [Dynamic Linker](@ref) - * [StackTraces](@ref) - * [SIMD Support](@ref) - * [Profiling](@ref lib-profiling) - * [Memory-mapped I/O](@ref) - * [Base64](@ref) - * [File Events](@ref lib-filewatching) - * [Sparse Arrays](@ref) - * [Iterative Eigensolvers](@ref lib-itereigen) - * [Printf](@ref) - * [Random Numbers](@ref) diff --git a/src/base/io-network.md b/src/base/io-network.md index 396c0ef..b28cf9d 100644 --- a/src/base/io-network.md +++ b/src/base/io-network.md @@ -3,9 +3,9 @@ ## General I/O ```@docs -Base.STDOUT -Base.STDERR -Base.STDIN +Base.stdout +Base.stderr +Base.stdin Base.open Base.IOBuffer Base.take!(::Base.GenericIOBuffer) diff --git a/src/devdocs/stdio.md b/src/devdocs/stdio.md index 2adc259..d17f7ab 100644 --- a/src/devdocs/stdio.md +++ b/src/devdocs/stdio.md @@ -29,24 +29,24 @@ void jl_safe_printf(const char *str, ...); ## Interface between JL_STD* and Julia code -[`Base.STDIN`](@ref), [`Base.STDOUT`](@ref) and [`Base.STDERR`](@ref) are bound to the `JL_STD*` libuv +[`Base.stdin`](@ref), [`Base.stdout`](@ref) and [`Base.stderr`](@ref) are bound to the `JL_STD*` libuv streams defined in the runtime. Julia's `__init__()` function (in `base/sysimg.jl`) calls `reinit_stdio()` (in `base/stream.jl`) -to create Julia objects for [`Base.STDIN`](@ref), [`Base.STDOUT`](@ref) and [`Base.STDERR`](@ref). +to create Julia objects for [`Base.stdin`](@ref), [`Base.stdout`](@ref) and [`Base.stderr`](@ref). `reinit_stdio()` uses [`ccall`](@ref) to retrieve pointers to `JL_STD*` and calls `jl_uv_handle_type()` to inspect the type of each stream. It then creates a Julia `Base.IOStream`, `Base.TTY` or `Base.PipeEndpoint` object to represent each stream, e.g.: ``` -$ julia -e 'println(typeof((STDIN, STDOUT, STDERR)))' +$ julia -e 'println(typeof((stdin, stdout, stderr)))' Tuple{Base.TTY,Base.TTY,Base.TTY} -$ julia -e 'println(typeof((STDIN, STDOUT, STDERR)))' < /dev/null 2>/dev/null +$ julia -e 'println(typeof((stdin, stdout, stderr)))' < /dev/null 2>/dev/null Tuple{IOStream,Base.TTY,IOStream} -$ echo hello | julia -e 'println(typeof((STDIN, STDOUT, STDERR)))' | cat +$ echo hello | julia -e 'println(typeof((stdin, stdout, stderr)))' | cat Tuple{Base.PipeEndpoint,Base.PipeEndpoint,Base.TTY} ``` diff --git a/src/index.md b/src/index.md index a4a79aa..ab3aa22 100644 --- a/src/index.md +++ b/src/index.md @@ -35,7 +35,6 @@ * [Missing Values](@ref missing) * [Networking and Streams](@ref) * [Parallel Computing](@ref) - * [Date and DateTime](@ref) * [Running External Programs](@ref) * [Calling C and Fortran Code](@ref) * [Handling Operating System Variation](@ref) @@ -82,7 +81,7 @@ * [Base64](@ref) * [CRC32c](@ref) * [SHA](@ref) - * [Dates and Time](@ref stdlib-dates) + * [Dates](@ref stdlib-dates) * [Delimited Files](@ref) * [Distributed Computing](@ref) * [File Events](@ref lib-filewatching) diff --git a/src/manual/dates.md b/src/manual/dates.md deleted file mode 100644 index 5496eb7..0000000 --- a/src/manual/dates.md +++ /dev/null @@ -1,628 +0,0 @@ -# Date and DateTime - -```@meta -CurrentModule = Dates -``` - -The `Dates` module provides two types for working with dates: [`Date`](@ref) and [`DateTime`](@ref), -representing day and millisecond precision, respectively; both are subtypes of the abstract [`TimeType`](@ref). -The motivation for distinct types is simple: some operations are much simpler, both in terms of -code and mental reasoning, when the complexities of greater precision don't have to be dealt with. -For example, since the [`Date`](@ref) type only resolves to the precision of a single date (i.e. -no hours, minutes, or seconds), normal considerations for time zones, daylight savings/summer -time, and leap seconds are unnecessary and avoided. - -Both [`Date`](@ref) and [`DateTime`](@ref) are basically immutable [`Int64`](@ref) wrappers. -The single `instant` field of either type is actually a `UTInstant{P}` type, which -represents a continuously increasing machine timeline based on the UT second [^1]. The -[`DateTime`](@ref) type is not aware of time zones (*naive*, in Python parlance), -analogous to a *LocalDateTime* in Java 8. Additional time zone functionality -can be added through the [TimeZones.jl package](https://github.com/JuliaTime/TimeZones.jl/), which -compiles the [IANA time zone database](http://www.iana.org/time-zones). Both [`Date`](@ref) and -[`DateTime`](@ref) are based on the [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) standard, which follows the proleptic Gregorian calendar. -One note is that the ISO 8601 standard is particular about BC/BCE dates. In general, the last -day of the BC/BCE era, 1-12-31 BC/BCE, was followed by 1-1-1 AD/CE, thus no year zero exists. -The ISO standard, however, states that 1 BC/BCE is year zero, so `0000-12-31` is the day before -`0001-01-01`, and year `-0001` (yes, negative one for the year) is 2 BC/BCE, year `-0002` is 3 -BC/BCE, etc. - -[^1]: - The notion of the UT second is actually quite fundamental. There are basically two different notions - of time generally accepted, one based on the physical rotation of the earth (one full rotation - = 1 day), the other based on the SI second (a fixed, constant value). These are radically different! - Think about it, a "UT second", as defined relative to the rotation of the earth, may have a different - absolute length depending on the day! Anyway, the fact that [`Date`](@ref) and [`DateTime`](@ref) - are based on UT seconds is a simplifying, yet honest assumption so that things like leap seconds - and all their complexity can be avoided. This basis of time is formally called [UT](https://en.wikipedia.org/wiki/Universal_Time) - or UT1. Basing types on the UT second basically means that every minute has 60 seconds and every - day has 24 hours and leads to more natural calculations when working with calendar dates. - -## Constructors - -[`Date`](@ref) and [`DateTime`](@ref) types can be constructed by integer or [`Period`](@ref) -types, by parsing, or through adjusters (more on those later): - -```jldoctest -julia> DateTime(2013) -2013-01-01T00:00:00 - -julia> DateTime(2013,7) -2013-07-01T00:00:00 - -julia> DateTime(2013,7,1) -2013-07-01T00:00:00 - -julia> DateTime(2013,7,1,12) -2013-07-01T12:00:00 - -julia> DateTime(2013,7,1,12,30) -2013-07-01T12:30:00 - -julia> DateTime(2013,7,1,12,30,59) -2013-07-01T12:30:59 - -julia> DateTime(2013,7,1,12,30,59,1) -2013-07-01T12:30:59.001 - -julia> Date(2013) -2013-01-01 - -julia> Date(2013,7) -2013-07-01 - -julia> Date(2013,7,1) -2013-07-01 - -julia> Date(Dates.Year(2013),Dates.Month(7),Dates.Day(1)) -2013-07-01 - -julia> Date(Dates.Month(7),Dates.Year(2013)) -2013-07-01 -``` - -[`Date`](@ref) or [`DateTime`](@ref) parsing is accomplished by the use of format strings. Format -strings work by the notion of defining *delimited* or *fixed-width* "slots" that contain a period -to parse and passing the text to parse and format string to a [`Date`](@ref) or [`DateTime`](@ref) -constructor, of the form `Date("2015-01-01","y-m-d")` or `DateTime("20150101","yyyymmdd")`. - -Delimited slots are marked by specifying the delimiter the parser should expect between two subsequent -periods; so `"y-m-d"` lets the parser know that between the first and second slots in a date string -like `"2014-07-16"`, it should find the `-` character. The `y`, `m`, and `d` characters let the -parser know which periods to parse in each slot. - -Fixed-width slots are specified by repeating the period character the number of times corresponding -to the width with no delimiter between characters. So `"yyyymmdd"` would correspond to a date -string like `"20140716"`. The parser distinguishes a fixed-width slot by the absence of a delimiter, -noting the transition `"yyyymm"` from one period character to the next. - -Support for text-form month parsing is also supported through the `u` and `U` characters, for -abbreviated and full-length month names, respectively. By default, only English month names are -supported, so `u` corresponds to "Jan", "Feb", "Mar", etc. And `U` corresponds to "January", "February", -"March", etc. Similar to other name=>value mapping functions [`dayname`](@ref) and [`monthname`](@ref), -custom locales can be loaded by passing in the `locale=>Dict{String,Int}` mapping to the `MONTHTOVALUEABBR` -and `MONTHTOVALUE` dicts for abbreviated and full-name month names, respectively. - -One note on parsing performance: using the `Date(date_string,format_string)` function is fine -if only called a few times. If there are many similarly formatted date strings to parse however, -it is much more efficient to first create a [`Dates.DateFormat`](@ref), and pass it instead of -a raw format string. - -```jldoctest -julia> df = DateFormat("y-m-d"); - -julia> dt = Date("2015-01-01",df) -2015-01-01 - -julia> dt2 = Date("2015-01-02",df) -2015-01-02 -``` - -You can also use the `dateformat""` string macro. This macro creates the `DateFormat` object once when the macro is expanded and uses the same `DateFormat` object even if a code snippet is run multiple times. - -```jldoctest -julia> for i = 1:10^5 - Date("2015-01-01", dateformat"y-m-d") - end -``` - -A full suite of parsing and formatting tests and examples is available in [`stdlib/Dates/test/io.jl`](https://github.com/JuliaLang/julia/blob/master/stdlib/Dates/test/io.jl). - -## Durations/Comparisons - -Finding the length of time between two [`Date`](@ref) or [`DateTime`](@ref) is straightforward -given their underlying representation as `UTInstant{Day}` and `UTInstant{Millisecond}`, respectively. -The difference between [`Date`](@ref) is returned in the number of [`Day`](@ref), and [`DateTime`](@ref) -in the number of [`Millisecond`](@ref). Similarly, comparing [`TimeType`](@ref) is a simple matter -of comparing the underlying machine instants (which in turn compares the internal [`Int64`](@ref) values). - -```jldoctest -julia> dt = Date(2012,2,29) -2012-02-29 - -julia> dt2 = Date(2000,2,1) -2000-02-01 - -julia> dump(dt) -Date - instant: Dates.UTInstant{Dates.Day} - periods: Dates.Day - value: Int64 734562 - -julia> dump(dt2) -Date - instant: Dates.UTInstant{Dates.Day} - periods: Dates.Day - value: Int64 730151 - -julia> dt > dt2 -true - -julia> dt != dt2 -true - -julia> dt + dt2 -ERROR: MethodError: no method matching +(::Date, ::Date) -[...] - -julia> dt * dt2 -ERROR: MethodError: no method matching *(::Date, ::Date) -[...] - -julia> dt / dt2 -ERROR: MethodError: no method matching /(::Date, ::Date) -[...] - -julia> dt - dt2 -4411 days - -julia> dt2 - dt --4411 days - -julia> dt = DateTime(2012,2,29) -2012-02-29T00:00:00 - -julia> dt2 = DateTime(2000,2,1) -2000-02-01T00:00:00 - -julia> dt - dt2 -381110400000 milliseconds -``` - -## Accessor Functions - -Because the [`Date`](@ref) and [`DateTime`](@ref) types are stored as single [`Int64`](@ref) values, date -parts or fields can be retrieved through accessor functions. The lowercase accessors return the -field as an integer: - -```jldoctest tdate -julia> t = Date(2014, 1, 31) -2014-01-31 - -julia> Dates.year(t) -2014 - -julia> Dates.month(t) -1 - -julia> Dates.week(t) -5 - -julia> Dates.day(t) -31 -``` - -While propercase return the same value in the corresponding [`Period`](@ref) type: - -```jldoctest tdate -julia> Dates.Year(t) -2014 years - -julia> Dates.Day(t) -31 days -``` - -Compound methods are provided, as they provide a measure of efficiency if multiple fields are -needed at the same time: - -```jldoctest tdate -julia> Dates.yearmonth(t) -(2014, 1) - -julia> Dates.monthday(t) -(1, 31) - -julia> Dates.yearmonthday(t) -(2014, 1, 31) -``` - -One may also access the underlying `UTInstant` or integer value: - -```jldoctest tdate -julia> dump(t) -Date - instant: Dates.UTInstant{Dates.Day} - periods: Dates.Day - value: Int64 735264 - -julia> t.instant -Dates.UTInstant{Dates.Day}(735264 days) - -julia> Dates.value(t) -735264 -``` - -## Query Functions - -Query functions provide calendrical information about a [`TimeType`](@ref). They include information -about the day of the week: - -```jldoctest tdate2 -julia> t = Date(2014, 1, 31) -2014-01-31 - -julia> Dates.dayofweek(t) -5 - -julia> Dates.dayname(t) -"Friday" - -julia> Dates.dayofweekofmonth(t) # 5th Friday of January -5 -``` - -Month of the year: - -```jldoctest tdate2 -julia> Dates.monthname(t) -"January" - -julia> Dates.daysinmonth(t) -31 -``` - -As well as information about the [`TimeType`](@ref)'s year and quarter: - -```jldoctest tdate2 -julia> Dates.isleapyear(t) -false - -julia> Dates.dayofyear(t) -31 - -julia> Dates.quarterofyear(t) -1 - -julia> Dates.dayofquarter(t) -31 -``` - -The [`dayname`](@ref) and [`monthname`](@ref) methods can also take an optional `locale` keyword -that can be used to return the name of the day or month of the year for other languages/locales. -There are also versions of these functions returning the abbreviated names, namely -[`dayabbr`](@ref) and [`monthabbr`](@ref). -First the mapping is loaded into the `LOCALES` variable: - -```jldoctest tdate2 -julia> french_months = ["janvier", "février", "mars", "avril", "mai", "juin", - "juillet", "août", "septembre", "octobre", "novembre", "décembre"]; - -julia> french_monts_abbrev = ["janv","févr","mars","avril","mai","juin", - "juil","août","sept","oct","nov","déc"]; - -julia> french_days = ["lundi","mardi","mercredi","jeudi","vendredi","samedi","dimanche"]; - -julia> Dates.LOCALES["french"] = Dates.DateLocale(french_months, french_monts_abbrev, french_days, [""]); -``` - - The above mentioned functions can then be used to perform the queries: - -```jldoctest tdate2 -julia> Dates.dayname(t;locale="french") -"vendredi" - -julia> Dates.monthname(t;locale="french") -"janvier" - -julia> Dates.monthabbr(t;locale="french") -"janv" -``` - -Since the abbreviated versions of the days are not loaded, trying to use the -function `dayabbr` will error. - -```jldoctest tdate2 -julia> Dates.dayabbr(t;locale="french") -ERROR: BoundsError: attempt to access 1-element Array{String,1} at index [5] -Stacktrace: -[...] -``` - - -## TimeType-Period Arithmetic - -It's good practice when using any language/date framework to be familiar with how date-period -arithmetic is handled as there are some [tricky issues](https://codeblog.jonskeet.uk/2010/12/01/the-joys-of-date-time-arithmetic/) -to deal with (though much less so for day-precision types). - -The `Dates` module approach tries to follow the simple principle of trying to change as -little as possible when doing [`Period`](@ref) arithmetic. This approach is also often known as -*calendrical* arithmetic or what you would probably guess if someone were to ask you the same -calculation in a conversation. Why all the fuss about this? Let's take a classic example: add -1 month to January 31st, 2014. What's the answer? Javascript will say [March 3](http://www.markhneedham.com/blog/2009/01/07/javascript-add-a-month-to-a-date/) -(assumes 31 days). PHP says [March 2](https://stackoverflow.com/questions/5760262/php-adding-months-to-a-date-while-not-exceeding-the-last-day-of-the-month) -(assumes 30 days). The fact is, there is no right answer. In the `Dates` module, it gives -the result of February 28th. How does it figure that out? I like to think of the classic 7-7-7 -gambling game in casinos. - -Now just imagine that instead of 7-7-7, the slots are Year-Month-Day, or in our example, 2014-01-31. -When you ask to add 1 month to this date, the month slot is incremented, so now we have 2014-02-31. -Then the day number is checked if it is greater than the last valid day of the new month; if it -is (as in the case above), the day number is adjusted down to the last valid day (28). What are -the ramifications with this approach? Go ahead and add another month to our date, `2014-02-28 + Month(1) == 2014-03-28`. -What? Were you expecting the last day of March? Nope, sorry, remember the 7-7-7 slots. As few -slots as possible are going to change, so we first increment the month slot by 1, 2014-03-28, -and boom, we're done because that's a valid date. On the other hand, if we were to add 2 months -to our original date, 2014-01-31, then we end up with 2014-03-31, as expected. The other ramification -of this approach is a loss in associativity when a specific ordering is forced (i.e. adding things -in different orders results in different outcomes). For example: - -```jldoctest -julia> (Date(2014,1,29)+Dates.Day(1)) + Dates.Month(1) -2014-02-28 - -julia> (Date(2014,1,29)+Dates.Month(1)) + Dates.Day(1) -2014-03-01 -``` - -What's going on there? In the first line, we're adding 1 day to January 29th, which results in -2014-01-30; then we add 1 month, so we get 2014-02-30, which then adjusts down to 2014-02-28. -In the second example, we add 1 month *first*, where we get 2014-02-29, which adjusts down to -2014-02-28, and *then* add 1 day, which results in 2014-03-01. One design principle that helps -in this case is that, in the presence of multiple Periods, the operations will be ordered by the -Periods' *types*, not their value or positional order; this means `Year` will always be added -first, then `Month`, then `Week`, etc. Hence the following *does* result in associativity and -Just Works: - -```jldoctest -julia> Date(2014,1,29) + Dates.Day(1) + Dates.Month(1) -2014-03-01 - -julia> Date(2014,1,29) + Dates.Month(1) + Dates.Day(1) -2014-03-01 -``` - -Tricky? Perhaps. What is an innocent `Dates` user to do? The bottom line is to be aware -that explicitly forcing a certain associativity, when dealing with months, may lead to some unexpected -results, but otherwise, everything should work as expected. Thankfully, that's pretty much the -extent of the odd cases in date-period arithmetic when dealing with time in UT (avoiding the "joys" -of dealing with daylight savings, leap seconds, etc.). - -As a bonus, all period arithmetic objects work directly with ranges: - -```jldoctest -julia> dr = Date(2014,1,29):Date(2014,2,3) -2014-01-29:1 day:2014-02-03 - -julia> collect(dr) -6-element Array{Date,1}: - 2014-01-29 - 2014-01-30 - 2014-01-31 - 2014-02-01 - 2014-02-02 - 2014-02-03 - -julia> dr = Date(2014,1,29):Dates.Month(1):Date(2014,07,29) -2014-01-29:1 month:2014-07-29 - -julia> collect(dr) -7-element Array{Date,1}: - 2014-01-29 - 2014-02-28 - 2014-03-29 - 2014-04-29 - 2014-05-29 - 2014-06-29 - 2014-07-29 -``` - -## Adjuster Functions - -As convenient as date-period arithmetics are, often the kinds of calculations needed on dates -take on a *calendrical* or *temporal* nature rather than a fixed number of periods. Holidays are -a perfect example; most follow rules such as "Memorial Day = Last Monday of May", or "Thanksgiving -= 4th Thursday of November". These kinds of temporal expressions deal with rules relative to the -calendar, like first or last of the month, next Tuesday, or the first and third Wednesdays, etc. - -The `Dates` module provides the *adjuster* API through several convenient methods that -aid in simply and succinctly expressing temporal rules. The first group of adjuster methods deal -with the first and last of weeks, months, quarters, and years. They each take a single [`TimeType`](@ref) -as input and return or *adjust to* the first or last of the desired period relative to the input. - -```jldoctest -julia> Dates.firstdayofweek(Date(2014,7,16)) # Adjusts the input to the Monday of the input's week -2014-07-14 - -julia> Dates.lastdayofmonth(Date(2014,7,16)) # Adjusts to the last day of the input's month -2014-07-31 - -julia> Dates.lastdayofquarter(Date(2014,7,16)) # Adjusts to the last day of the input's quarter -2014-09-30 -``` - -The next two higher-order methods, [`tonext`](@ref), and [`toprev`](@ref), generalize working -with temporal expressions by taking a `DateFunction` as first argument, along with a starting -[`TimeType`](@ref). A `DateFunction` is just a function, usually anonymous, that takes a single -[`TimeType`](@ref) as input and returns a [`Bool`](@ref), `true` indicating a satisfied -adjustment criterion. -For example: - -```jldoctest -julia> istuesday = x->Dates.dayofweek(x) == Dates.Tuesday; # Returns true if the day of the week of x is Tuesday - -julia> Dates.tonext(istuesday, Date(2014,7,13)) # 2014-07-13 is a Sunday -2014-07-15 - -julia> Dates.tonext(Date(2014,7,13), Dates.Tuesday) # Convenience method provided for day of the week adjustments -2014-07-15 -``` - -This is useful with the do-block syntax for more complex temporal expressions: - -```jldoctest -julia> Dates.tonext(Date(2014,7,13)) do x - # Return true on the 4th Thursday of November (Thanksgiving) - Dates.dayofweek(x) == Dates.Thursday && - Dates.dayofweekofmonth(x) == 4 && - Dates.month(x) == Dates.November - end -2014-11-27 -``` - -The [`Base.filter`](@ref) method can be used to obtain all valid dates/moments in a specified -range: - -```jldoctest -# Pittsburgh street cleaning; Every 2nd Tuesday from April to November -# Date range from January 1st, 2014 to January 1st, 2015 -julia> dr = Dates.Date(2014):Dates.Date(2015); - -julia> filter(dr) do x - Dates.dayofweek(x) == Dates.Tue && - Dates.April <= Dates.month(x) <= Dates.Nov && - Dates.dayofweekofmonth(x) == 2 - end -8-element Array{Date,1}: - 2014-04-08 - 2014-05-13 - 2014-06-10 - 2014-07-08 - 2014-08-12 - 2014-09-09 - 2014-10-14 - 2014-11-11 -``` - -Additional examples and tests are available in [`stdlib/Dates/test/adjusters.jl`](https://github.com/JuliaLang/julia/blob/master/stdlib/Dates/test/adjusters.jl). - -## Period Types - -Periods are a human view of discrete, sometimes irregular durations of time. Consider 1 month; -it could represent, in days, a value of 28, 29, 30, or 31 depending on the year and month context. -Or a year could represent 365 or 366 days in the case of a leap year. [`Period`](@ref) types are -simple [`Int64`](@ref) wrappers and are constructed by wrapping any `Int64` convertible type, i.e. `Year(1)` -or `Month(3.0)`. Arithmetic between [`Period`](@ref) of the same type behave like integers, and -limited `Period-Real` arithmetic is available. - -```jldoctest -julia> y1 = Dates.Year(1) -1 year - -julia> y2 = Dates.Year(2) -2 years - -julia> y3 = Dates.Year(10) -10 years - -julia> y1 + y2 -3 years - -julia> div(y3,y2) -5 - -julia> y3 - y2 -8 years - -julia> y3 % y2 -0 years - -julia> div(y3,3) # mirrors integer division -3 years -``` - -## Rounding - -[`Date`](@ref) and [`DateTime`](@ref) values can be rounded to a specified resolution (e.g., 1 -month or 15 minutes) with [`floor`](@ref), [`ceil`](@ref), or [`round`](@ref): - -```jldoctest -julia> floor(Date(1985, 8, 16), Dates.Month) -1985-08-01 - -julia> ceil(DateTime(2013, 2, 13, 0, 31, 20), Dates.Minute(15)) -2013-02-13T00:45:00 - -julia> round(DateTime(2016, 8, 6, 20, 15), Dates.Day) -2016-08-07T00:00:00 -``` - -Unlike the numeric [`round`](@ref) method, which breaks ties toward the even number by default, -the [`TimeType`](@ref)[`round`](@ref) method uses the `RoundNearestTiesUp` rounding mode. (It's -difficult to guess what breaking ties to nearest "even" [`TimeType`](@ref) would entail.) Further -details on the available `RoundingMode` s can be found in the [API reference](@ref stdlib-dates). - -Rounding should generally behave as expected, but there are a few cases in which the expected -behaviour is not obvious. - -### Rounding Epoch - -In many cases, the resolution specified for rounding (e.g., `Dates.Second(30)`) divides evenly -into the next largest period (in this case, `Dates.Minute(1)`). But rounding behaviour in cases -in which this is not true may lead to confusion. What is the expected result of rounding a [`DateTime`](@ref) -to the nearest 10 hours? - -```jldoctest -julia> round(DateTime(2016, 7, 17, 11, 55), Dates.Hour(10)) -2016-07-17T12:00:00 -``` - -That may seem confusing, given that the hour (12) is not divisible by 10. The reason that `2016-07-17T12:00:00` -was chosen is that it is 17,676,660 hours after `0000-01-01T00:00:00`, and 17,676,660 is divisible -by 10. - -As Julia [`Date`](@ref) and [`DateTime`](@ref) values are represented according to the ISO 8601 -standard, `0000-01-01T00:00:00` was chosen as base (or "rounding epoch") from which to begin the -count of days (and milliseconds) used in rounding calculations. (Note that this differs slightly -from Julia's internal representation of [`Date`](@ref) s using Rata Die notation; but since the -ISO 8601 standard is most visible to the end user, `0000-01-01T00:00:00` was chosen as the rounding -epoch instead of the `0000-12-31T00:00:00` used internally to minimize confusion.) - -The only exception to the use of `0000-01-01T00:00:00` as the rounding epoch is when rounding -to weeks. Rounding to the nearest week will always return a Monday (the first day of the week -as specified by ISO 8601). For this reason, we use `0000-01-03T00:00:00` (the first day of the -first week of year 0000, as defined by ISO 8601) as the base when rounding to a number of weeks. - -Here is a related case in which the expected behaviour is not necessarily obvious: What happens -when we round to the nearest `P(2)`, where `P` is a [`Period`](@ref) type? In some cases (specifically, -when `P <: Dates.TimePeriod`) the answer is clear: - -```jldoctest -julia> round(DateTime(2016, 7, 17, 8, 55, 30), Dates.Hour(2)) -2016-07-17T08:00:00 - -julia> round(DateTime(2016, 7, 17, 8, 55, 30), Dates.Minute(2)) -2016-07-17T08:56:00 -``` - -This seems obvious, because two of each of these periods still divides evenly into the next larger -order period. But in the case of two months (which still divides evenly into one year), the answer -may be surprising: - -```jldoctest -julia> round(DateTime(2016, 7, 17, 8, 55, 30), Dates.Month(2)) -2016-07-01T00:00:00 -``` - -Why round to the first day in July, even though it is month 7 (an odd number)? The key is that -months are 1-indexed (the first month is assigned 1), unlike hours, minutes, seconds, and milliseconds -(the first of which are assigned 0). - -This means that rounding a [`DateTime`](@ref) to an even multiple of seconds, minutes, hours, -or years (because the ISO 8601 specification includes a year zero) will result in a [`DateTime`](@ref) -with an even value in that field, while rounding a [`DateTime`](@ref) to an even multiple of months -will result in the months field having an odd value. Because both months and years may contain -an irregular number of days, whether rounding to an even number of days will result in an even -value in the days field is uncertain. - -See the [API reference](@ref stdlib-dates) for additional information -on methods exported from the `Dates` module. diff --git a/src/manual/environment-variables.md b/src/manual/environment-variables.md index ebc4617..28dbf15 100644 --- a/src/manual/environment-variables.md +++ b/src/manual/environment-variables.md @@ -5,7 +5,7 @@ usual way of the operating system, or in a portable way from within Julia. Suppose you want to set the environment variable `JULIA_EDITOR` to `vim`, then either type `ENV["JULIA_EDITOR"] = "vim"` for instance in the REPL to make this change on a case by case basis, or add the same to the user -configuration file `.juliarc.jl` in the user's home directory to have +configuration file `~/.julia/config/startup.jl` in the user's home directory to have a permanent effect. The current value of the same environment variable is determined by evaluating `ENV["JULIA_EDITOR"]`. @@ -42,14 +42,14 @@ determines the directory in which Julia initially searches for source files (via `Base.find_source_file()`). Likewise, the global variable `Base.SYSCONFDIR` determines a relative path to the -configuration file directory. Then Julia searches for a `juliarc.jl` file at +configuration file directory. Then Julia searches for a `startup.jl` file at ``` -$JULIA_BINDIR/$SYSCONFDIR/julia/juliarc.jl -$JULIA_BINDIR/../etc/julia/juliarc.jl +$JULIA_BINDIR/$SYSCONFDIR/julia/startup.jl +$JULIA_BINDIR/../etc/julia/startup.jl ``` -by default (via `Base.load_juliarc()`). +by default (via `Base.load_julia_startup()`). For example, a Linux installation with a Julia executable located at `/bin/julia`, a `DATAROOTDIR` of `../share`, and a `SYSCONFDIR` of `../etc` will @@ -62,7 +62,7 @@ have `JULIA_BINDIR` set to `/bin`, a source-file search path of and a global configuration search path of ``` -/etc/julia/juliarc.jl +/etc/julia/startup.jl ``` ### `JULIA_LOAD_PATH` diff --git a/src/manual/faq.md b/src/manual/faq.md index d367791..fe8ca94 100644 --- a/src/manual/faq.md +++ b/src/manual/faq.md @@ -693,7 +693,7 @@ Consider the printed output from the following: ```jldoctest julia> @sync for i in 1:3 - @async write(STDOUT, string(i), " Foo ", " Bar ") + @async write(stdout, string(i), " Foo ", " Bar ") end 123 Foo Foo Foo Bar Bar Bar ``` @@ -706,7 +706,7 @@ in the above example results in: ```jldoctest julia> @sync for i in 1:3 - @async println(STDOUT, string(i), " Foo ", " Bar ") + @async println(stdout, string(i), " Foo ", " Bar ") end 1 Foo Bar 2 Foo Bar @@ -723,7 +723,7 @@ julia> @sync for i in 1:3 @async begin lock(l) try - write(STDOUT, string(i), " Foo ", " Bar ") + write(stdout, string(i), " Foo ", " Bar ") finally unlock(l) end diff --git a/src/manual/functions.md b/src/manual/functions.md index fc79f56..db16602 100644 --- a/src/manual/functions.md +++ b/src/manual/functions.md @@ -125,6 +125,18 @@ There are three possible points of return from this function, returning the valu expressions, depending on the values of `x` and `y`. The `return` on the last line could be omitted since it is the last expression. +A return type can also be specified in the function declaration using the `::` operator. This converts +the return value to the specified type. + +```jldoctest +function g(x,y)::Int8 + return x * y +end +``` + +This function will always return an `Int8` regardless of the types of `x` and `y`. +See [Type Declarations](@ref) for more on return types. + ## Operators Are Functions In Julia, most operators are just functions with support for special syntax. (The exceptions are diff --git a/src/manual/getting-started.md b/src/manual/getting-started.md index 127408f..d0f5ac2 100644 --- a/src/manual/getting-started.md +++ b/src/manual/getting-started.md @@ -66,7 +66,7 @@ Julia는 `-p` 옵션이나 `--machine-file` 옵션을 이용하여 병렬 환경 만약 Julia가 실행할 때마다 실행되는 코드가 있다면, 그 코드를 `~/.juliarc.ji` 에 넣으면 된다. ``` -$ echo 'println("Greetings! 你好! 안녕하세요?")' > ~/.juliarc.jl +$ echo 'println("Greetings! 你好! 안녕하세요?")' > ~/.julia/config/startup.jl $ julia Greetings! 你好! 안녕하세요? @@ -82,7 +82,7 @@ julia [switches] -- [programfile] [args...] -J, --sysimage 이라는 시스템 이미지 파일을 로드한 뒤 실행한다. -H, --home julia 실행파일의 위치를 지정한다. - --startup-file={yes|no} ~/.juliarc.jl를 불러온다. + --startup-file={yes|no} `~/.julia/config/startup.jl` 를 불러온다. --handle-signals={yes|no} Julia의 기본 시그널 핸들러를 켜거나 끈다. --sysimage-native-code={yes|no} 시스템 이미지의 기존 코드 사용/사용하지 않는다. diff --git a/src/manual/modules.md b/src/manual/modules.md index 1442f89..20930e2 100644 --- a/src/manual/modules.md +++ b/src/manual/modules.md @@ -191,8 +191,9 @@ The global variable [`LOAD_PATH`](@ref) contains the directories Julia searches push!(LOAD_PATH, "/Path/To/My/Module/") ``` -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`. +Putting this statement in the file `~/.julia/config/startup.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 @@ -342,11 +343,11 @@ Other known potential failure scenarios include: of via its lookup path. For example, (in global scope): ```julia - #mystdout = Base.STDOUT #= will not work correctly, since this will copy Base.STDOUT into this module =# + #mystdout = Base.stdout #= will not work correctly, since this will copy Base.stdout into this module =# # instead use accessor functions: - getstdout() = Base.STDOUT #= best option =# + getstdout() = Base.stdout #= best option =# # or move the assignment into the runtime: - __init__() = global mystdout = Base.STDOUT #= also works =# + __init__() = global mystdout = Base.stdout #= also works =# ``` Several additional restrictions are placed on the operations that can be done while precompiling diff --git a/src/manual/networking-and-streams.md b/src/manual/networking-and-streams.md index d43c0d1..4d75c59 100644 --- a/src/manual/networking-and-streams.md +++ b/src/manual/networking-and-streams.md @@ -12,14 +12,14 @@ All Julia streams expose at least a [`read`](@ref) and a [`write`](@ref) method, stream as their first argument, e.g.: ```julia-repl -julia> write(STDOUT, "Hello World"); # suppress return value 11 with ; +julia> write(stdout, "Hello World"); # suppress return value 11 with ; Hello World -julia> read(STDIN, Char) +julia> read(stdin, Char) '\n': ASCII/Unicode U+000a (category Cc: Other, control) ``` -Note that [`write`](@ref) returns 11, the number of bytes (in `"Hello World"`) written to [`STDOUT`](@ref), +Note that [`write`](@ref) returns 11, the number of bytes (in `"Hello World"`) written to [`stdout`](@ref), but this return value is suppressed with the `;`. Here Enter was pressed again so that Julia would read the newline. Now, as you can see from this @@ -36,7 +36,7 @@ julia> x = zeros(UInt8, 4) 0x00 0x00 -julia> read!(STDIN, x) +julia> read!(stdin, x) abcd 4-element Array{UInt8,1}: 0x61 @@ -49,7 +49,7 @@ However, since this is slightly cumbersome, there are several convenience method example, we could have written the above as: ```julia-repl -julia> read(STDIN, 4) +julia> read(stdin, 4) abcd 4-element Array{UInt8,1}: 0x61 @@ -61,7 +61,7 @@ abcd or if we had wanted to read the entire line instead: ```julia-repl -julia> readline(STDIN) +julia> readline(stdin) abcd "abcd" ``` @@ -69,10 +69,10 @@ abcd Note that depending on your terminal settings, your TTY may be line buffered and might thus require an additional enter before the data is sent to Julia. -To read every line from [`STDIN`](@ref) you can use [`eachline`](@ref): +To read every line from [`stdin`](@ref) you can use [`eachline`](@ref): ```julia -for line in eachline(STDIN) +for line in eachline(stdin) print("Found $line") end ``` @@ -80,8 +80,8 @@ end or [`read`](@ref) if you wanted to read by character instead: ```julia -while !eof(STDIN) - x = read(STDIN, Char) +while !eof(stdin) + x = read(stdin, Char) println("Found: $x") end ``` @@ -92,18 +92,18 @@ Note that the [`write`](@ref) method mentioned above operates on binary streams. values do not get converted to any canonical text representation but are written out as is: ```jldoctest -julia> write(STDOUT, 0x61); # suppress return value 1 with ; +julia> write(stdout, 0x61); # suppress return value 1 with ; a ``` -Note that `a` is written to [`STDOUT`](@ref) by the [`write`](@ref) function and that the returned +Note that `a` is written to [`stdout`](@ref) by the [`write`](@ref) function and that the returned value is `1` (since `0x61` is one byte). For text I/O, use the [`print`](@ref) or [`show`](@ref) methods, depending on your needs (see the Julia Base reference for a detailed discussion of the difference between the two): ```jldoctest -julia> print(STDOUT, 0x61) +julia> print(stdout, 0x61) 97 ``` @@ -272,7 +272,7 @@ julia> clientside = connect(2001) TCPSocket(RawFD(28) open, 0 bytes waiting) julia> @async while true - write(STDOUT,readline(clientside)) + write(stdout,readline(clientside)) end Task (runnable) @0x00007fd31dc11870 diff --git a/src/manual/parallel-computing.md b/src/manual/parallel-computing.md index 876ca90..410122d 100644 --- a/src/manual/parallel-computing.md +++ b/src/manual/parallel-computing.md @@ -221,9 +221,9 @@ julia> addprocs(2) Module `Distributed` must be explicitly loaded on the master process before invoking [`addprocs`](@ref). It is automatically made available on the worker processes. -Note that workers do not run a `.juliarc.jl` startup script, nor do they synchronize their global -state (such as global variables, new method definitions, and loaded modules) with any of the other -running processes. +Note that workers do not run a `~/.julia/config/startup.jl` startup script, nor do they synchronize +their global state (such as global variables, new method definitions, and loaded modules) with any +of the other running processes. Other types of clusters can be supported by writing your own custom `ClusterManager`, as described below in the [ClusterManagers](@ref) section. @@ -1071,8 +1071,8 @@ manner: * [`addprocs`](@ref) is called on the master process with a `ClusterManager` object. * [`addprocs`](@ref) calls the appropriate [`launch`](@ref) method which spawns required number of worker processes on appropriate machines. - * Each worker starts listening on a free port and writes out its host and port information to [`STDOUT`](@ref). - * The cluster manager captures the [`STDOUT`](@ref) of each worker and makes it available to the + * Each worker starts listening on a free port and writes out its host and port information to [`stdout`](@ref). + * The cluster manager captures the [`stdout`](@ref) of each worker and makes it available to the master process. * The master process parses this information and sets up TCP/IP connections to each worker. * Every worker is also notified of other workers in the cluster. @@ -1315,7 +1315,7 @@ on the master process: are allowed to connect to each other. * The cookie may be passed to the workers at startup via argument `--worker=`. If argument `--worker` is specified without the cookie, the worker tries to read the cookie from its - standard input ([`STDIN`](@ref)). The `STDIN` is closed immediately after the cookie is retrieved. + standard input ([`stdin`](@ref)). The `stdin` is closed immediately after the cookie is retrieved. * `ClusterManager`s can retrieve the cookie on the master by calling [`cluster_cookie()`](@ref). Cluster managers not using the default TCP/IP transport (and hence not specifying `--worker`) must call `init_worker(cookie, manager)` with the same cookie as on the master. diff --git a/src/manual/profile.md b/src/manual/profile.md index 29cda5c..00d91cf 100644 --- a/src/manual/profile.md +++ b/src/manual/profile.md @@ -210,12 +210,12 @@ be very useful, but sometimes you want to start fresh; you can do so with [`Prof [`Profile.print`](@ref) has more options than we've described so far. Let's see the full declaration: ```julia -function print(io::IO = STDOUT, data = fetch(); kwargs...) +function print(io::IO = stdout, data = fetch(); kwargs...) ``` Let's first discuss the two positional arguments, and later the keyword arguments: - * `io` -- Allows you to save the results to a buffer, e.g. a file, but the default is to print to `STDOUT` + * `io` -- Allows you to save the results to a buffer, e.g. a file, but the default is to print to `stdout` (the console). * `data` -- Contains the data you want to analyze; by default that is obtained from [`Profile.fetch()`](@ref), which pulls out the backtraces from a pre-allocated buffer. For example, if you want to profile @@ -224,7 +224,7 @@ Let's first discuss the two positional arguments, and later the keyword argument ```julia data = copy(Profile.fetch()) Profile.clear() - @profile Profile.print(STDOUT, data) # Prints the previous results + @profile Profile.print(stdout, data) # Prints the previous results Profile.print() # Prints results from Profile.print() ``` diff --git a/src/manual/running-external-programs.md b/src/manual/running-external-programs.md index 065b402..88fc044 100644 --- a/src/manual/running-external-programs.md +++ b/src/manual/running-external-programs.md @@ -14,7 +14,7 @@ differs in several aspects from the behavior in various shells, Perl, or Ruby: You can use this object to connect the command to others via pipes, [`run`](@ref) it, and [`read`](@ref) or [`write`](@ref) to it. * When the command is run, Julia does not capture its output unless you specifically arrange for - it to. Instead, the output of the command by default goes to [`STDOUT`](@ref) as it would using + it to. Instead, the output of the command by default goes to [`stdout`](@ref) as it would using `libc`'s `system` call. * The command is never run with a shell. Instead, Julia parses the command syntax directly, appropriately interpolating variables and splitting on words as the shell would, respecting shell quoting syntax. @@ -33,7 +33,7 @@ julia> run(mycommand) hello ``` -The `hello` is the output of the `echo` command, sent to [`STDOUT`](@ref). The run method itself +The `hello` is the output of the `echo` command, sent to [`stdout`](@ref). The run method itself returns `nothing`, and throws an [`ErrorException`](@ref) if the external command fails to run successfully. @@ -50,7 +50,7 @@ true More generally, you can use [`open`](@ref) to read from or write to an external command. ```jldoctest -julia> open(`less`, "w", STDOUT) do io +julia> open(`less`, "w", stdout) do io for i = 1:3 println(io, i) end @@ -280,7 +280,7 @@ hello ``` The order of the output here is non-deterministic because the two `echo` processes are started -nearly simultaneously, and race to make the first write to the [`STDOUT`](@ref) descriptor they +nearly simultaneously, and race to make the first write to the [`stdout`](@ref) descriptor they share with each other and the `julia` parent process. Julia lets you pipe the output from both of these processes to another program: @@ -347,7 +347,7 @@ generates lines with the numbers 0 through 9 on them, while two parallel process output, one prefixing lines with the letter "A", the other with the letter "B". Which consumer gets the first line is non-deterministic, but once that race has been won, the lines are consumed alternately by one process and then the other. (Setting `$|=1` in Perl causes each print statement -to flush the [`STDOUT`](@ref) handle, which is necessary for this example to work. Otherwise all +to flush the [`stdout`](@ref) handle, which is necessary for this example to work. Otherwise all the output is buffered and printed to the pipe at once, to be read by just one consumer process.) Here is an even more complex multi-stage producer-consumer example: diff --git a/src/manual/types.md b/src/manual/types.md index e30405b..c64215b 100644 --- a/src/manual/types.md +++ b/src/manual/types.md @@ -1251,8 +1251,8 @@ julia> [Polar(3, 4.0), Polar(4.0,5.3)] ``` where the single-line `show(io, z)` form is still used for an array of `Polar` values. Technically, -the REPL calls `display(z)` to display the result of executing a line, which defaults to `show(STDOUT, MIME("text/plain"), z)`, -which in turn defaults to `show(STDOUT, z)`, but you should *not* define new [`display`](@ref) +the REPL calls `display(z)` to display the result of executing a line, which defaults to `show(stdout, MIME("text/plain"), z)`, +which in turn defaults to `show(stdout, z)`, but you should *not* define new [`display`](@ref) methods unless you are defining a new multimedia display handler (see [Multimedia I/O](@ref)). Moreover, you can also define `show` methods for other MIME types in order to enable richer display @@ -1269,7 +1269,7 @@ A `Polar` object will then display automatically using HTML in an environment th display, but you can call `show` manually to get HTML output if you want: ```jldoctest polartype -julia> show(STDOUT, "text/html", Polar(3.0,4.0)) +julia> show(stdout, "text/html", Polar(3.0,4.0)) Polar{Float64} complex number: 3.0 e4.0 i ``` diff --git a/src/manual/workflow-tips.md b/src/manual/workflow-tips.md index bd00c03..857822d 100644 --- a/src/manual/workflow-tips.md +++ b/src/manual/workflow-tips.md @@ -55,7 +55,7 @@ which you can run on startup by issuing the command: julia -L _init.jl ``` -If you further add the following to your `.juliarc.jl` file +If you further add the following to your `~/.julia/config/startup.jl` file ```julia isfile("_init.jl") && include(joinpath(pwd(), "_init.jl")) diff --git a/src/stdlib/Dates.md b/src/stdlib/Dates.md index 3abee48..2b3adef 100644 --- a/src/stdlib/Dates.md +++ b/src/stdlib/Dates.md @@ -1,14 +1,633 @@ -# [Dates and Time](@id stdlib-dates) +# Dates ```@meta DocTestSetup = :(using Dates) ``` -Functionality to handle time and dates is defined in the standard library module `Dates`. -You'll need to import the module using `import Dates` and prefix each -function call with an explicit `Dates.`, e.g. `Dates.dayofweek(dt)`. Alternatively, you can write -`using Dates` to bring all exported functions into `Main` to be used without the `Dates.` -prefix. +The `Dates` module provides two types for working with dates: [`Date`](@ref) and [`DateTime`](@ref), +representing day and millisecond precision, respectively; both are subtypes of the abstract [`TimeType`](@ref). +The motivation for distinct types is simple: some operations are much simpler, both in terms of +code and mental reasoning, when the complexities of greater precision don't have to be dealt with. +For example, since the [`Date`](@ref) type only resolves to the precision of a single date (i.e. +no hours, minutes, or seconds), normal considerations for time zones, daylight savings/summer +time, and leap seconds are unnecessary and avoided. + +Both [`Date`](@ref) and [`DateTime`](@ref) are basically immutable [`Int64`](@ref) wrappers. +The single `instant` field of either type is actually a `UTInstant{P}` type, which +represents a continuously increasing machine timeline based on the UT second [^1]. The +[`DateTime`](@ref) type is not aware of time zones (*naive*, in Python parlance), +analogous to a *LocalDateTime* in Java 8. Additional time zone functionality +can be added through the [TimeZones.jl package](https://github.com/JuliaTime/TimeZones.jl/), which +compiles the [IANA time zone database](http://www.iana.org/time-zones). Both [`Date`](@ref) and +[`DateTime`](@ref) are based on the [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) standard, which follows the proleptic Gregorian calendar. +One note is that the ISO 8601 standard is particular about BC/BCE dates. In general, the last +day of the BC/BCE era, 1-12-31 BC/BCE, was followed by 1-1-1 AD/CE, thus no year zero exists. +The ISO standard, however, states that 1 BC/BCE is year zero, so `0000-12-31` is the day before +`0001-01-01`, and year `-0001` (yes, negative one for the year) is 2 BC/BCE, year `-0002` is 3 +BC/BCE, etc. + +[^1]: + The notion of the UT second is actually quite fundamental. There are basically two different notions + of time generally accepted, one based on the physical rotation of the earth (one full rotation + = 1 day), the other based on the SI second (a fixed, constant value). These are radically different! + Think about it, a "UT second", as defined relative to the rotation of the earth, may have a different + absolute length depending on the day! Anyway, the fact that [`Date`](@ref) and [`DateTime`](@ref) + are based on UT seconds is a simplifying, yet honest assumption so that things like leap seconds + and all their complexity can be avoided. This basis of time is formally called [UT](https://en.wikipedia.org/wiki/Universal_Time) + or UT1. Basing types on the UT second basically means that every minute has 60 seconds and every + day has 24 hours and leads to more natural calculations when working with calendar dates. + +## Constructors + +[`Date`](@ref) and [`DateTime`](@ref) types can be constructed by integer or [`Period`](@ref) +types, by parsing, or through adjusters (more on those later): + +```jldoctest +julia> DateTime(2013) +2013-01-01T00:00:00 + +julia> DateTime(2013,7) +2013-07-01T00:00:00 + +julia> DateTime(2013,7,1) +2013-07-01T00:00:00 + +julia> DateTime(2013,7,1,12) +2013-07-01T12:00:00 + +julia> DateTime(2013,7,1,12,30) +2013-07-01T12:30:00 + +julia> DateTime(2013,7,1,12,30,59) +2013-07-01T12:30:59 + +julia> DateTime(2013,7,1,12,30,59,1) +2013-07-01T12:30:59.001 + +julia> Date(2013) +2013-01-01 + +julia> Date(2013,7) +2013-07-01 + +julia> Date(2013,7,1) +2013-07-01 + +julia> Date(Dates.Year(2013),Dates.Month(7),Dates.Day(1)) +2013-07-01 + +julia> Date(Dates.Month(7),Dates.Year(2013)) +2013-07-01 +``` + +[`Date`](@ref) or [`DateTime`](@ref) parsing is accomplished by the use of format strings. Format +strings work by the notion of defining *delimited* or *fixed-width* "slots" that contain a period +to parse and passing the text to parse and format string to a [`Date`](@ref) or [`DateTime`](@ref) +constructor, of the form `Date("2015-01-01","y-m-d")` or `DateTime("20150101","yyyymmdd")`. + +Delimited slots are marked by specifying the delimiter the parser should expect between two subsequent +periods; so `"y-m-d"` lets the parser know that between the first and second slots in a date string +like `"2014-07-16"`, it should find the `-` character. The `y`, `m`, and `d` characters let the +parser know which periods to parse in each slot. + +Fixed-width slots are specified by repeating the period character the number of times corresponding +to the width with no delimiter between characters. So `"yyyymmdd"` would correspond to a date +string like `"20140716"`. The parser distinguishes a fixed-width slot by the absence of a delimiter, +noting the transition `"yyyymm"` from one period character to the next. + +Support for text-form month parsing is also supported through the `u` and `U` characters, for +abbreviated and full-length month names, respectively. By default, only English month names are +supported, so `u` corresponds to "Jan", "Feb", "Mar", etc. And `U` corresponds to "January", "February", +"March", etc. Similar to other name=>value mapping functions [`dayname`](@ref) and [`monthname`](@ref), +custom locales can be loaded by passing in the `locale=>Dict{String,Int}` mapping to the `MONTHTOVALUEABBR` +and `MONTHTOVALUE` dicts for abbreviated and full-name month names, respectively. + +One note on parsing performance: using the `Date(date_string,format_string)` function is fine +if only called a few times. If there are many similarly formatted date strings to parse however, +it is much more efficient to first create a [`Dates.DateFormat`](@ref), and pass it instead of +a raw format string. + +```jldoctest +julia> df = DateFormat("y-m-d"); + +julia> dt = Date("2015-01-01",df) +2015-01-01 + +julia> dt2 = Date("2015-01-02",df) +2015-01-02 +``` + +You can also use the `dateformat""` string macro. This macro creates the `DateFormat` object once when the macro is expanded and uses the same `DateFormat` object even if a code snippet is run multiple times. + +```jldoctest +julia> for i = 1:10^5 + Date("2015-01-01", dateformat"y-m-d") + end +``` + +A full suite of parsing and formatting tests and examples is available in [`stdlib/Dates/test/io.jl`](https://github.com/JuliaLang/julia/blob/master/stdlib/Dates/test/io.jl). + +## Durations/Comparisons + +Finding the length of time between two [`Date`](@ref) or [`DateTime`](@ref) is straightforward +given their underlying representation as `UTInstant{Day}` and `UTInstant{Millisecond}`, respectively. +The difference between [`Date`](@ref) is returned in the number of [`Day`](@ref), and [`DateTime`](@ref) +in the number of [`Millisecond`](@ref). Similarly, comparing [`TimeType`](@ref) is a simple matter +of comparing the underlying machine instants (which in turn compares the internal [`Int64`](@ref) values). + +```jldoctest +julia> dt = Date(2012,2,29) +2012-02-29 + +julia> dt2 = Date(2000,2,1) +2000-02-01 + +julia> dump(dt) +Date + instant: Dates.UTInstant{Dates.Day} + periods: Dates.Day + value: Int64 734562 + +julia> dump(dt2) +Date + instant: Dates.UTInstant{Dates.Day} + periods: Dates.Day + value: Int64 730151 + +julia> dt > dt2 +true + +julia> dt != dt2 +true + +julia> dt + dt2 +ERROR: MethodError: no method matching +(::Date, ::Date) +[...] + +julia> dt * dt2 +ERROR: MethodError: no method matching *(::Date, ::Date) +[...] + +julia> dt / dt2 +ERROR: MethodError: no method matching /(::Date, ::Date) +[...] + +julia> dt - dt2 +4411 days + +julia> dt2 - dt +-4411 days + +julia> dt = DateTime(2012,2,29) +2012-02-29T00:00:00 + +julia> dt2 = DateTime(2000,2,1) +2000-02-01T00:00:00 + +julia> dt - dt2 +381110400000 milliseconds +``` + +## Accessor Functions + +Because the [`Date`](@ref) and [`DateTime`](@ref) types are stored as single [`Int64`](@ref) values, date +parts or fields can be retrieved through accessor functions. The lowercase accessors return the +field as an integer: + +```jldoctest tdate +julia> t = Date(2014, 1, 31) +2014-01-31 + +julia> Dates.year(t) +2014 + +julia> Dates.month(t) +1 + +julia> Dates.week(t) +5 + +julia> Dates.day(t) +31 +``` + +While propercase return the same value in the corresponding [`Period`](@ref) type: + +```jldoctest tdate +julia> Dates.Year(t) +2014 years + +julia> Dates.Day(t) +31 days +``` + +Compound methods are provided, as they provide a measure of efficiency if multiple fields are +needed at the same time: + +```jldoctest tdate +julia> Dates.yearmonth(t) +(2014, 1) + +julia> Dates.monthday(t) +(1, 31) + +julia> Dates.yearmonthday(t) +(2014, 1, 31) +``` + +One may also access the underlying `UTInstant` or integer value: + +```jldoctest tdate +julia> dump(t) +Date + instant: Dates.UTInstant{Dates.Day} + periods: Dates.Day + value: Int64 735264 + +julia> t.instant +Dates.UTInstant{Dates.Day}(735264 days) + +julia> Dates.value(t) +735264 +``` + +## Query Functions + +Query functions provide calendrical information about a [`TimeType`](@ref). They include information +about the day of the week: + +```jldoctest tdate2 +julia> t = Date(2014, 1, 31) +2014-01-31 + +julia> Dates.dayofweek(t) +5 + +julia> Dates.dayname(t) +"Friday" + +julia> Dates.dayofweekofmonth(t) # 5th Friday of January +5 +``` + +Month of the year: + +```jldoctest tdate2 +julia> Dates.monthname(t) +"January" + +julia> Dates.daysinmonth(t) +31 +``` + +As well as information about the [`TimeType`](@ref)'s year and quarter: + +```jldoctest tdate2 +julia> Dates.isleapyear(t) +false + +julia> Dates.dayofyear(t) +31 + +julia> Dates.quarterofyear(t) +1 + +julia> Dates.dayofquarter(t) +31 +``` + +The [`dayname`](@ref) and [`monthname`](@ref) methods can also take an optional `locale` keyword +that can be used to return the name of the day or month of the year for other languages/locales. +There are also versions of these functions returning the abbreviated names, namely +[`dayabbr`](@ref) and [`monthabbr`](@ref). +First the mapping is loaded into the `LOCALES` variable: + +```jldoctest tdate2 +julia> french_months = ["janvier", "février", "mars", "avril", "mai", "juin", + "juillet", "août", "septembre", "octobre", "novembre", "décembre"]; + +julia> french_monts_abbrev = ["janv","févr","mars","avril","mai","juin", + "juil","août","sept","oct","nov","déc"]; + +julia> french_days = ["lundi","mardi","mercredi","jeudi","vendredi","samedi","dimanche"]; + +julia> Dates.LOCALES["french"] = Dates.DateLocale(french_months, french_monts_abbrev, french_days, [""]); +``` + + The above mentioned functions can then be used to perform the queries: + +```jldoctest tdate2 +julia> Dates.dayname(t;locale="french") +"vendredi" + +julia> Dates.monthname(t;locale="french") +"janvier" + +julia> Dates.monthabbr(t;locale="french") +"janv" +``` + +Since the abbreviated versions of the days are not loaded, trying to use the +function `dayabbr` will error. + +```jldoctest tdate2 +julia> Dates.dayabbr(t;locale="french") +ERROR: BoundsError: attempt to access 1-element Array{String,1} at index [5] +Stacktrace: +[...] +``` + + +## TimeType-Period Arithmetic + +It's good practice when using any language/date framework to be familiar with how date-period +arithmetic is handled as there are some [tricky issues](https://codeblog.jonskeet.uk/2010/12/01/the-joys-of-date-time-arithmetic/) +to deal with (though much less so for day-precision types). + +The `Dates` module approach tries to follow the simple principle of trying to change as +little as possible when doing [`Period`](@ref) arithmetic. This approach is also often known as +*calendrical* arithmetic or what you would probably guess if someone were to ask you the same +calculation in a conversation. Why all the fuss about this? Let's take a classic example: add +1 month to January 31st, 2014. What's the answer? Javascript will say [March 3](http://www.markhneedham.com/blog/2009/01/07/javascript-add-a-month-to-a-date/) +(assumes 31 days). PHP says [March 2](https://stackoverflow.com/questions/5760262/php-adding-months-to-a-date-while-not-exceeding-the-last-day-of-the-month) +(assumes 30 days). The fact is, there is no right answer. In the `Dates` module, it gives +the result of February 28th. How does it figure that out? I like to think of the classic 7-7-7 +gambling game in casinos. + +Now just imagine that instead of 7-7-7, the slots are Year-Month-Day, or in our example, 2014-01-31. +When you ask to add 1 month to this date, the month slot is incremented, so now we have 2014-02-31. +Then the day number is checked if it is greater than the last valid day of the new month; if it +is (as in the case above), the day number is adjusted down to the last valid day (28). What are +the ramifications with this approach? Go ahead and add another month to our date, `2014-02-28 + Month(1) == 2014-03-28`. +What? Were you expecting the last day of March? Nope, sorry, remember the 7-7-7 slots. As few +slots as possible are going to change, so we first increment the month slot by 1, 2014-03-28, +and boom, we're done because that's a valid date. On the other hand, if we were to add 2 months +to our original date, 2014-01-31, then we end up with 2014-03-31, as expected. The other ramification +of this approach is a loss in associativity when a specific ordering is forced (i.e. adding things +in different orders results in different outcomes). For example: + +```jldoctest +julia> (Date(2014,1,29)+Dates.Day(1)) + Dates.Month(1) +2014-02-28 + +julia> (Date(2014,1,29)+Dates.Month(1)) + Dates.Day(1) +2014-03-01 +``` + +What's going on there? In the first line, we're adding 1 day to January 29th, which results in +2014-01-30; then we add 1 month, so we get 2014-02-30, which then adjusts down to 2014-02-28. +In the second example, we add 1 month *first*, where we get 2014-02-29, which adjusts down to +2014-02-28, and *then* add 1 day, which results in 2014-03-01. One design principle that helps +in this case is that, in the presence of multiple Periods, the operations will be ordered by the +Periods' *types*, not their value or positional order; this means `Year` will always be added +first, then `Month`, then `Week`, etc. Hence the following *does* result in associativity and +Just Works: + +```jldoctest +julia> Date(2014,1,29) + Dates.Day(1) + Dates.Month(1) +2014-03-01 + +julia> Date(2014,1,29) + Dates.Month(1) + Dates.Day(1) +2014-03-01 +``` + +Tricky? Perhaps. What is an innocent `Dates` user to do? The bottom line is to be aware +that explicitly forcing a certain associativity, when dealing with months, may lead to some unexpected +results, but otherwise, everything should work as expected. Thankfully, that's pretty much the +extent of the odd cases in date-period arithmetic when dealing with time in UT (avoiding the "joys" +of dealing with daylight savings, leap seconds, etc.). + +As a bonus, all period arithmetic objects work directly with ranges: + +```jldoctest +julia> dr = Date(2014,1,29):Date(2014,2,3) +2014-01-29:1 day:2014-02-03 + +julia> collect(dr) +6-element Array{Date,1}: + 2014-01-29 + 2014-01-30 + 2014-01-31 + 2014-02-01 + 2014-02-02 + 2014-02-03 + +julia> dr = Date(2014,1,29):Dates.Month(1):Date(2014,07,29) +2014-01-29:1 month:2014-07-29 + +julia> collect(dr) +7-element Array{Date,1}: + 2014-01-29 + 2014-02-28 + 2014-03-29 + 2014-04-29 + 2014-05-29 + 2014-06-29 + 2014-07-29 +``` + +## Adjuster Functions + +As convenient as date-period arithmetics are, often the kinds of calculations needed on dates +take on a *calendrical* or *temporal* nature rather than a fixed number of periods. Holidays are +a perfect example; most follow rules such as "Memorial Day = Last Monday of May", or "Thanksgiving += 4th Thursday of November". These kinds of temporal expressions deal with rules relative to the +calendar, like first or last of the month, next Tuesday, or the first and third Wednesdays, etc. + +The `Dates` module provides the *adjuster* API through several convenient methods that +aid in simply and succinctly expressing temporal rules. The first group of adjuster methods deal +with the first and last of weeks, months, quarters, and years. They each take a single [`TimeType`](@ref) +as input and return or *adjust to* the first or last of the desired period relative to the input. + +```jldoctest +julia> Dates.firstdayofweek(Date(2014,7,16)) # Adjusts the input to the Monday of the input's week +2014-07-14 + +julia> Dates.lastdayofmonth(Date(2014,7,16)) # Adjusts to the last day of the input's month +2014-07-31 + +julia> Dates.lastdayofquarter(Date(2014,7,16)) # Adjusts to the last day of the input's quarter +2014-09-30 +``` + +The next two higher-order methods, [`tonext`](@ref), and [`toprev`](@ref), generalize working +with temporal expressions by taking a `DateFunction` as first argument, along with a starting +[`TimeType`](@ref). A `DateFunction` is just a function, usually anonymous, that takes a single +[`TimeType`](@ref) as input and returns a [`Bool`](@ref), `true` indicating a satisfied +adjustment criterion. +For example: + +```jldoctest +julia> istuesday = x->Dates.dayofweek(x) == Dates.Tuesday; # Returns true if the day of the week of x is Tuesday + +julia> Dates.tonext(istuesday, Date(2014,7,13)) # 2014-07-13 is a Sunday +2014-07-15 + +julia> Dates.tonext(Date(2014,7,13), Dates.Tuesday) # Convenience method provided for day of the week adjustments +2014-07-15 +``` + +This is useful with the do-block syntax for more complex temporal expressions: + +```jldoctest +julia> Dates.tonext(Date(2014,7,13)) do x + # Return true on the 4th Thursday of November (Thanksgiving) + Dates.dayofweek(x) == Dates.Thursday && + Dates.dayofweekofmonth(x) == 4 && + Dates.month(x) == Dates.November + end +2014-11-27 +``` + +The [`Base.filter`](@ref) method can be used to obtain all valid dates/moments in a specified +range: + +```jldoctest +# Pittsburgh street cleaning; Every 2nd Tuesday from April to November +# Date range from January 1st, 2014 to January 1st, 2015 +julia> dr = Dates.Date(2014):Dates.Date(2015); + +julia> filter(dr) do x + Dates.dayofweek(x) == Dates.Tue && + Dates.April <= Dates.month(x) <= Dates.Nov && + Dates.dayofweekofmonth(x) == 2 + end +8-element Array{Date,1}: + 2014-04-08 + 2014-05-13 + 2014-06-10 + 2014-07-08 + 2014-08-12 + 2014-09-09 + 2014-10-14 + 2014-11-11 +``` + +Additional examples and tests are available in [`stdlib/Dates/test/adjusters.jl`](https://github.com/JuliaLang/julia/blob/master/stdlib/Dates/test/adjusters.jl). + +## Period Types + +Periods are a human view of discrete, sometimes irregular durations of time. Consider 1 month; +it could represent, in days, a value of 28, 29, 30, or 31 depending on the year and month context. +Or a year could represent 365 or 366 days in the case of a leap year. [`Period`](@ref) types are +simple [`Int64`](@ref) wrappers and are constructed by wrapping any `Int64` convertible type, i.e. `Year(1)` +or `Month(3.0)`. Arithmetic between [`Period`](@ref) of the same type behave like integers, and +limited `Period-Real` arithmetic is available. + +```jldoctest +julia> y1 = Dates.Year(1) +1 year + +julia> y2 = Dates.Year(2) +2 years + +julia> y3 = Dates.Year(10) +10 years + +julia> y1 + y2 +3 years + +julia> div(y3,y2) +5 + +julia> y3 - y2 +8 years + +julia> y3 % y2 +0 years + +julia> div(y3,3) # mirrors integer division +3 years +``` + +## Rounding + +[`Date`](@ref) and [`DateTime`](@ref) values can be rounded to a specified resolution (e.g., 1 +month or 15 minutes) with [`floor`](@ref), [`ceil`](@ref), or [`round`](@ref): + +```jldoctest +julia> floor(Date(1985, 8, 16), Dates.Month) +1985-08-01 + +julia> ceil(DateTime(2013, 2, 13, 0, 31, 20), Dates.Minute(15)) +2013-02-13T00:45:00 + +julia> round(DateTime(2016, 8, 6, 20, 15), Dates.Day) +2016-08-07T00:00:00 +``` + +Unlike the numeric [`round`](@ref) method, which breaks ties toward the even number by default, +the [`TimeType`](@ref)[`round`](@ref) method uses the `RoundNearestTiesUp` rounding mode. (It's +difficult to guess what breaking ties to nearest "even" [`TimeType`](@ref) would entail.) Further +details on the available `RoundingMode` s can be found in the [API reference](@ref stdlib-dates). + +Rounding should generally behave as expected, but there are a few cases in which the expected +behaviour is not obvious. + +### Rounding Epoch + +In many cases, the resolution specified for rounding (e.g., `Dates.Second(30)`) divides evenly +into the next largest period (in this case, `Dates.Minute(1)`). But rounding behaviour in cases +in which this is not true may lead to confusion. What is the expected result of rounding a [`DateTime`](@ref) +to the nearest 10 hours? + +```jldoctest +julia> round(DateTime(2016, 7, 17, 11, 55), Dates.Hour(10)) +2016-07-17T12:00:00 +``` + +That may seem confusing, given that the hour (12) is not divisible by 10. The reason that `2016-07-17T12:00:00` +was chosen is that it is 17,676,660 hours after `0000-01-01T00:00:00`, and 17,676,660 is divisible +by 10. + +As Julia [`Date`](@ref) and [`DateTime`](@ref) values are represented according to the ISO 8601 +standard, `0000-01-01T00:00:00` was chosen as base (or "rounding epoch") from which to begin the +count of days (and milliseconds) used in rounding calculations. (Note that this differs slightly +from Julia's internal representation of [`Date`](@ref) s using Rata Die notation; but since the +ISO 8601 standard is most visible to the end user, `0000-01-01T00:00:00` was chosen as the rounding +epoch instead of the `0000-12-31T00:00:00` used internally to minimize confusion.) + +The only exception to the use of `0000-01-01T00:00:00` as the rounding epoch is when rounding +to weeks. Rounding to the nearest week will always return a Monday (the first day of the week +as specified by ISO 8601). For this reason, we use `0000-01-03T00:00:00` (the first day of the +first week of year 0000, as defined by ISO 8601) as the base when rounding to a number of weeks. + +Here is a related case in which the expected behaviour is not necessarily obvious: What happens +when we round to the nearest `P(2)`, where `P` is a [`Period`](@ref) type? In some cases (specifically, +when `P <: Dates.TimePeriod`) the answer is clear: + +```jldoctest +julia> round(DateTime(2016, 7, 17, 8, 55, 30), Dates.Hour(2)) +2016-07-17T08:00:00 + +julia> round(DateTime(2016, 7, 17, 8, 55, 30), Dates.Minute(2)) +2016-07-17T08:56:00 +``` + +This seems obvious, because two of each of these periods still divides evenly into the next larger +order period. But in the case of two months (which still divides evenly into one year), the answer +may be surprising: + +```jldoctest +julia> round(DateTime(2016, 7, 17, 8, 55, 30), Dates.Month(2)) +2016-07-01T00:00:00 +``` + +Why round to the first day in July, even though it is month 7 (an odd number)? The key is that +months are 1-indexed (the first month is assigned 1), unlike hours, minutes, seconds, and milliseconds +(the first of which are assigned 0). + +This means that rounding a [`DateTime`](@ref) to an even multiple of seconds, minutes, hours, +or years (because the ISO 8601 specification includes a year zero) will result in a [`DateTime`](@ref) +with an even value in that field, while rounding a [`DateTime`](@ref) to an even multiple of months +will result in the months field having an odd value. Because both months and years may contain +an irregular number of days, whether rounding to an even number of days will result in an even +value in the days field is uncertain. + +See the [API reference](@ref stdlib-dates-api) for additional information +on methods exported from the `Dates` module. + +# [API reference](@id stdlib-dates-api) ## Dates and Time Types diff --git a/src/stdlib/REPL.md b/src/stdlib/REPL.md index 34422a2..68b3937 100644 --- a/src/stdlib/REPL.md +++ b/src/stdlib/REPL.md @@ -191,7 +191,7 @@ Meta plus `x` can be written `"\\Mx"`. The values of the custom keymap must be ` that the input should be ignored) or functions that accept the signature `(PromptState, AbstractREPL, Char)`. The `REPL.setup_interface` function must be called before the REPL is initialized, by registering the operation with [`atreplinit`](@ref) . For example, to bind the up and down arrow keys to move through -history without prefix search, one could put the following code in `.juliarc.jl`: +history without prefix search, one could put the following code in `~/.julia/config/startup.jl`: ```julia import REPL @@ -324,7 +324,7 @@ fields if the function is type stable. The colors used by Julia and the REPL can be customized, as well. To change the color of the Julia prompt you can add something like the following to your -`.juliarc.jl` file, which is to be placed inside your home directory: +`~/.julia/config/startup.jl` file, which is to be placed inside your home directory: ```julia function customize_colors(repl) @@ -345,7 +345,7 @@ latter two, be sure that the `envcolors` field is also set to false. It is also possible to apply boldface formatting by using `Base.text_colors[:bold]` as a color. For instance, to print answers in -boldface font, one can use the following as a `.juliarc.jl`: +boldface font, one can use the following as a `~/.julia/config/startup.jl`: ```julia function customize_colors(repl) @@ -358,7 +358,8 @@ atreplinit(customize_colors) You can also customize the color used to render warning and informational messages by setting the appropriate environment variables. For instance, to render error, warning, and informational -messages respectively in magenta, yellow, and cyan you can add the following to your `.juliarc.jl` file: +messages respectively in magenta, yellow, and cyan you can add the following to your +`~/.julia/config/startup.jl` file: ```julia ENV["JULIA_ERROR_COLOR"] = :magenta diff --git a/src/stdlib/dates.md b/src/stdlib/dates.md index 3abee48..2b3adef 100644 --- a/src/stdlib/dates.md +++ b/src/stdlib/dates.md @@ -1,14 +1,633 @@ -# [Dates and Time](@id stdlib-dates) +# Dates ```@meta DocTestSetup = :(using Dates) ``` -Functionality to handle time and dates is defined in the standard library module `Dates`. -You'll need to import the module using `import Dates` and prefix each -function call with an explicit `Dates.`, e.g. `Dates.dayofweek(dt)`. Alternatively, you can write -`using Dates` to bring all exported functions into `Main` to be used without the `Dates.` -prefix. +The `Dates` module provides two types for working with dates: [`Date`](@ref) and [`DateTime`](@ref), +representing day and millisecond precision, respectively; both are subtypes of the abstract [`TimeType`](@ref). +The motivation for distinct types is simple: some operations are much simpler, both in terms of +code and mental reasoning, when the complexities of greater precision don't have to be dealt with. +For example, since the [`Date`](@ref) type only resolves to the precision of a single date (i.e. +no hours, minutes, or seconds), normal considerations for time zones, daylight savings/summer +time, and leap seconds are unnecessary and avoided. + +Both [`Date`](@ref) and [`DateTime`](@ref) are basically immutable [`Int64`](@ref) wrappers. +The single `instant` field of either type is actually a `UTInstant{P}` type, which +represents a continuously increasing machine timeline based on the UT second [^1]. The +[`DateTime`](@ref) type is not aware of time zones (*naive*, in Python parlance), +analogous to a *LocalDateTime* in Java 8. Additional time zone functionality +can be added through the [TimeZones.jl package](https://github.com/JuliaTime/TimeZones.jl/), which +compiles the [IANA time zone database](http://www.iana.org/time-zones). Both [`Date`](@ref) and +[`DateTime`](@ref) are based on the [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) standard, which follows the proleptic Gregorian calendar. +One note is that the ISO 8601 standard is particular about BC/BCE dates. In general, the last +day of the BC/BCE era, 1-12-31 BC/BCE, was followed by 1-1-1 AD/CE, thus no year zero exists. +The ISO standard, however, states that 1 BC/BCE is year zero, so `0000-12-31` is the day before +`0001-01-01`, and year `-0001` (yes, negative one for the year) is 2 BC/BCE, year `-0002` is 3 +BC/BCE, etc. + +[^1]: + The notion of the UT second is actually quite fundamental. There are basically two different notions + of time generally accepted, one based on the physical rotation of the earth (one full rotation + = 1 day), the other based on the SI second (a fixed, constant value). These are radically different! + Think about it, a "UT second", as defined relative to the rotation of the earth, may have a different + absolute length depending on the day! Anyway, the fact that [`Date`](@ref) and [`DateTime`](@ref) + are based on UT seconds is a simplifying, yet honest assumption so that things like leap seconds + and all their complexity can be avoided. This basis of time is formally called [UT](https://en.wikipedia.org/wiki/Universal_Time) + or UT1. Basing types on the UT second basically means that every minute has 60 seconds and every + day has 24 hours and leads to more natural calculations when working with calendar dates. + +## Constructors + +[`Date`](@ref) and [`DateTime`](@ref) types can be constructed by integer or [`Period`](@ref) +types, by parsing, or through adjusters (more on those later): + +```jldoctest +julia> DateTime(2013) +2013-01-01T00:00:00 + +julia> DateTime(2013,7) +2013-07-01T00:00:00 + +julia> DateTime(2013,7,1) +2013-07-01T00:00:00 + +julia> DateTime(2013,7,1,12) +2013-07-01T12:00:00 + +julia> DateTime(2013,7,1,12,30) +2013-07-01T12:30:00 + +julia> DateTime(2013,7,1,12,30,59) +2013-07-01T12:30:59 + +julia> DateTime(2013,7,1,12,30,59,1) +2013-07-01T12:30:59.001 + +julia> Date(2013) +2013-01-01 + +julia> Date(2013,7) +2013-07-01 + +julia> Date(2013,7,1) +2013-07-01 + +julia> Date(Dates.Year(2013),Dates.Month(7),Dates.Day(1)) +2013-07-01 + +julia> Date(Dates.Month(7),Dates.Year(2013)) +2013-07-01 +``` + +[`Date`](@ref) or [`DateTime`](@ref) parsing is accomplished by the use of format strings. Format +strings work by the notion of defining *delimited* or *fixed-width* "slots" that contain a period +to parse and passing the text to parse and format string to a [`Date`](@ref) or [`DateTime`](@ref) +constructor, of the form `Date("2015-01-01","y-m-d")` or `DateTime("20150101","yyyymmdd")`. + +Delimited slots are marked by specifying the delimiter the parser should expect between two subsequent +periods; so `"y-m-d"` lets the parser know that between the first and second slots in a date string +like `"2014-07-16"`, it should find the `-` character. The `y`, `m`, and `d` characters let the +parser know which periods to parse in each slot. + +Fixed-width slots are specified by repeating the period character the number of times corresponding +to the width with no delimiter between characters. So `"yyyymmdd"` would correspond to a date +string like `"20140716"`. The parser distinguishes a fixed-width slot by the absence of a delimiter, +noting the transition `"yyyymm"` from one period character to the next. + +Support for text-form month parsing is also supported through the `u` and `U` characters, for +abbreviated and full-length month names, respectively. By default, only English month names are +supported, so `u` corresponds to "Jan", "Feb", "Mar", etc. And `U` corresponds to "January", "February", +"March", etc. Similar to other name=>value mapping functions [`dayname`](@ref) and [`monthname`](@ref), +custom locales can be loaded by passing in the `locale=>Dict{String,Int}` mapping to the `MONTHTOVALUEABBR` +and `MONTHTOVALUE` dicts for abbreviated and full-name month names, respectively. + +One note on parsing performance: using the `Date(date_string,format_string)` function is fine +if only called a few times. If there are many similarly formatted date strings to parse however, +it is much more efficient to first create a [`Dates.DateFormat`](@ref), and pass it instead of +a raw format string. + +```jldoctest +julia> df = DateFormat("y-m-d"); + +julia> dt = Date("2015-01-01",df) +2015-01-01 + +julia> dt2 = Date("2015-01-02",df) +2015-01-02 +``` + +You can also use the `dateformat""` string macro. This macro creates the `DateFormat` object once when the macro is expanded and uses the same `DateFormat` object even if a code snippet is run multiple times. + +```jldoctest +julia> for i = 1:10^5 + Date("2015-01-01", dateformat"y-m-d") + end +``` + +A full suite of parsing and formatting tests and examples is available in [`stdlib/Dates/test/io.jl`](https://github.com/JuliaLang/julia/blob/master/stdlib/Dates/test/io.jl). + +## Durations/Comparisons + +Finding the length of time between two [`Date`](@ref) or [`DateTime`](@ref) is straightforward +given their underlying representation as `UTInstant{Day}` and `UTInstant{Millisecond}`, respectively. +The difference between [`Date`](@ref) is returned in the number of [`Day`](@ref), and [`DateTime`](@ref) +in the number of [`Millisecond`](@ref). Similarly, comparing [`TimeType`](@ref) is a simple matter +of comparing the underlying machine instants (which in turn compares the internal [`Int64`](@ref) values). + +```jldoctest +julia> dt = Date(2012,2,29) +2012-02-29 + +julia> dt2 = Date(2000,2,1) +2000-02-01 + +julia> dump(dt) +Date + instant: Dates.UTInstant{Dates.Day} + periods: Dates.Day + value: Int64 734562 + +julia> dump(dt2) +Date + instant: Dates.UTInstant{Dates.Day} + periods: Dates.Day + value: Int64 730151 + +julia> dt > dt2 +true + +julia> dt != dt2 +true + +julia> dt + dt2 +ERROR: MethodError: no method matching +(::Date, ::Date) +[...] + +julia> dt * dt2 +ERROR: MethodError: no method matching *(::Date, ::Date) +[...] + +julia> dt / dt2 +ERROR: MethodError: no method matching /(::Date, ::Date) +[...] + +julia> dt - dt2 +4411 days + +julia> dt2 - dt +-4411 days + +julia> dt = DateTime(2012,2,29) +2012-02-29T00:00:00 + +julia> dt2 = DateTime(2000,2,1) +2000-02-01T00:00:00 + +julia> dt - dt2 +381110400000 milliseconds +``` + +## Accessor Functions + +Because the [`Date`](@ref) and [`DateTime`](@ref) types are stored as single [`Int64`](@ref) values, date +parts or fields can be retrieved through accessor functions. The lowercase accessors return the +field as an integer: + +```jldoctest tdate +julia> t = Date(2014, 1, 31) +2014-01-31 + +julia> Dates.year(t) +2014 + +julia> Dates.month(t) +1 + +julia> Dates.week(t) +5 + +julia> Dates.day(t) +31 +``` + +While propercase return the same value in the corresponding [`Period`](@ref) type: + +```jldoctest tdate +julia> Dates.Year(t) +2014 years + +julia> Dates.Day(t) +31 days +``` + +Compound methods are provided, as they provide a measure of efficiency if multiple fields are +needed at the same time: + +```jldoctest tdate +julia> Dates.yearmonth(t) +(2014, 1) + +julia> Dates.monthday(t) +(1, 31) + +julia> Dates.yearmonthday(t) +(2014, 1, 31) +``` + +One may also access the underlying `UTInstant` or integer value: + +```jldoctest tdate +julia> dump(t) +Date + instant: Dates.UTInstant{Dates.Day} + periods: Dates.Day + value: Int64 735264 + +julia> t.instant +Dates.UTInstant{Dates.Day}(735264 days) + +julia> Dates.value(t) +735264 +``` + +## Query Functions + +Query functions provide calendrical information about a [`TimeType`](@ref). They include information +about the day of the week: + +```jldoctest tdate2 +julia> t = Date(2014, 1, 31) +2014-01-31 + +julia> Dates.dayofweek(t) +5 + +julia> Dates.dayname(t) +"Friday" + +julia> Dates.dayofweekofmonth(t) # 5th Friday of January +5 +``` + +Month of the year: + +```jldoctest tdate2 +julia> Dates.monthname(t) +"January" + +julia> Dates.daysinmonth(t) +31 +``` + +As well as information about the [`TimeType`](@ref)'s year and quarter: + +```jldoctest tdate2 +julia> Dates.isleapyear(t) +false + +julia> Dates.dayofyear(t) +31 + +julia> Dates.quarterofyear(t) +1 + +julia> Dates.dayofquarter(t) +31 +``` + +The [`dayname`](@ref) and [`monthname`](@ref) methods can also take an optional `locale` keyword +that can be used to return the name of the day or month of the year for other languages/locales. +There are also versions of these functions returning the abbreviated names, namely +[`dayabbr`](@ref) and [`monthabbr`](@ref). +First the mapping is loaded into the `LOCALES` variable: + +```jldoctest tdate2 +julia> french_months = ["janvier", "février", "mars", "avril", "mai", "juin", + "juillet", "août", "septembre", "octobre", "novembre", "décembre"]; + +julia> french_monts_abbrev = ["janv","févr","mars","avril","mai","juin", + "juil","août","sept","oct","nov","déc"]; + +julia> french_days = ["lundi","mardi","mercredi","jeudi","vendredi","samedi","dimanche"]; + +julia> Dates.LOCALES["french"] = Dates.DateLocale(french_months, french_monts_abbrev, french_days, [""]); +``` + + The above mentioned functions can then be used to perform the queries: + +```jldoctest tdate2 +julia> Dates.dayname(t;locale="french") +"vendredi" + +julia> Dates.monthname(t;locale="french") +"janvier" + +julia> Dates.monthabbr(t;locale="french") +"janv" +``` + +Since the abbreviated versions of the days are not loaded, trying to use the +function `dayabbr` will error. + +```jldoctest tdate2 +julia> Dates.dayabbr(t;locale="french") +ERROR: BoundsError: attempt to access 1-element Array{String,1} at index [5] +Stacktrace: +[...] +``` + + +## TimeType-Period Arithmetic + +It's good practice when using any language/date framework to be familiar with how date-period +arithmetic is handled as there are some [tricky issues](https://codeblog.jonskeet.uk/2010/12/01/the-joys-of-date-time-arithmetic/) +to deal with (though much less so for day-precision types). + +The `Dates` module approach tries to follow the simple principle of trying to change as +little as possible when doing [`Period`](@ref) arithmetic. This approach is also often known as +*calendrical* arithmetic or what you would probably guess if someone were to ask you the same +calculation in a conversation. Why all the fuss about this? Let's take a classic example: add +1 month to January 31st, 2014. What's the answer? Javascript will say [March 3](http://www.markhneedham.com/blog/2009/01/07/javascript-add-a-month-to-a-date/) +(assumes 31 days). PHP says [March 2](https://stackoverflow.com/questions/5760262/php-adding-months-to-a-date-while-not-exceeding-the-last-day-of-the-month) +(assumes 30 days). The fact is, there is no right answer. In the `Dates` module, it gives +the result of February 28th. How does it figure that out? I like to think of the classic 7-7-7 +gambling game in casinos. + +Now just imagine that instead of 7-7-7, the slots are Year-Month-Day, or in our example, 2014-01-31. +When you ask to add 1 month to this date, the month slot is incremented, so now we have 2014-02-31. +Then the day number is checked if it is greater than the last valid day of the new month; if it +is (as in the case above), the day number is adjusted down to the last valid day (28). What are +the ramifications with this approach? Go ahead and add another month to our date, `2014-02-28 + Month(1) == 2014-03-28`. +What? Were you expecting the last day of March? Nope, sorry, remember the 7-7-7 slots. As few +slots as possible are going to change, so we first increment the month slot by 1, 2014-03-28, +and boom, we're done because that's a valid date. On the other hand, if we were to add 2 months +to our original date, 2014-01-31, then we end up with 2014-03-31, as expected. The other ramification +of this approach is a loss in associativity when a specific ordering is forced (i.e. adding things +in different orders results in different outcomes). For example: + +```jldoctest +julia> (Date(2014,1,29)+Dates.Day(1)) + Dates.Month(1) +2014-02-28 + +julia> (Date(2014,1,29)+Dates.Month(1)) + Dates.Day(1) +2014-03-01 +``` + +What's going on there? In the first line, we're adding 1 day to January 29th, which results in +2014-01-30; then we add 1 month, so we get 2014-02-30, which then adjusts down to 2014-02-28. +In the second example, we add 1 month *first*, where we get 2014-02-29, which adjusts down to +2014-02-28, and *then* add 1 day, which results in 2014-03-01. One design principle that helps +in this case is that, in the presence of multiple Periods, the operations will be ordered by the +Periods' *types*, not their value or positional order; this means `Year` will always be added +first, then `Month`, then `Week`, etc. Hence the following *does* result in associativity and +Just Works: + +```jldoctest +julia> Date(2014,1,29) + Dates.Day(1) + Dates.Month(1) +2014-03-01 + +julia> Date(2014,1,29) + Dates.Month(1) + Dates.Day(1) +2014-03-01 +``` + +Tricky? Perhaps. What is an innocent `Dates` user to do? The bottom line is to be aware +that explicitly forcing a certain associativity, when dealing with months, may lead to some unexpected +results, but otherwise, everything should work as expected. Thankfully, that's pretty much the +extent of the odd cases in date-period arithmetic when dealing with time in UT (avoiding the "joys" +of dealing with daylight savings, leap seconds, etc.). + +As a bonus, all period arithmetic objects work directly with ranges: + +```jldoctest +julia> dr = Date(2014,1,29):Date(2014,2,3) +2014-01-29:1 day:2014-02-03 + +julia> collect(dr) +6-element Array{Date,1}: + 2014-01-29 + 2014-01-30 + 2014-01-31 + 2014-02-01 + 2014-02-02 + 2014-02-03 + +julia> dr = Date(2014,1,29):Dates.Month(1):Date(2014,07,29) +2014-01-29:1 month:2014-07-29 + +julia> collect(dr) +7-element Array{Date,1}: + 2014-01-29 + 2014-02-28 + 2014-03-29 + 2014-04-29 + 2014-05-29 + 2014-06-29 + 2014-07-29 +``` + +## Adjuster Functions + +As convenient as date-period arithmetics are, often the kinds of calculations needed on dates +take on a *calendrical* or *temporal* nature rather than a fixed number of periods. Holidays are +a perfect example; most follow rules such as "Memorial Day = Last Monday of May", or "Thanksgiving += 4th Thursday of November". These kinds of temporal expressions deal with rules relative to the +calendar, like first or last of the month, next Tuesday, or the first and third Wednesdays, etc. + +The `Dates` module provides the *adjuster* API through several convenient methods that +aid in simply and succinctly expressing temporal rules. The first group of adjuster methods deal +with the first and last of weeks, months, quarters, and years. They each take a single [`TimeType`](@ref) +as input and return or *adjust to* the first or last of the desired period relative to the input. + +```jldoctest +julia> Dates.firstdayofweek(Date(2014,7,16)) # Adjusts the input to the Monday of the input's week +2014-07-14 + +julia> Dates.lastdayofmonth(Date(2014,7,16)) # Adjusts to the last day of the input's month +2014-07-31 + +julia> Dates.lastdayofquarter(Date(2014,7,16)) # Adjusts to the last day of the input's quarter +2014-09-30 +``` + +The next two higher-order methods, [`tonext`](@ref), and [`toprev`](@ref), generalize working +with temporal expressions by taking a `DateFunction` as first argument, along with a starting +[`TimeType`](@ref). A `DateFunction` is just a function, usually anonymous, that takes a single +[`TimeType`](@ref) as input and returns a [`Bool`](@ref), `true` indicating a satisfied +adjustment criterion. +For example: + +```jldoctest +julia> istuesday = x->Dates.dayofweek(x) == Dates.Tuesday; # Returns true if the day of the week of x is Tuesday + +julia> Dates.tonext(istuesday, Date(2014,7,13)) # 2014-07-13 is a Sunday +2014-07-15 + +julia> Dates.tonext(Date(2014,7,13), Dates.Tuesday) # Convenience method provided for day of the week adjustments +2014-07-15 +``` + +This is useful with the do-block syntax for more complex temporal expressions: + +```jldoctest +julia> Dates.tonext(Date(2014,7,13)) do x + # Return true on the 4th Thursday of November (Thanksgiving) + Dates.dayofweek(x) == Dates.Thursday && + Dates.dayofweekofmonth(x) == 4 && + Dates.month(x) == Dates.November + end +2014-11-27 +``` + +The [`Base.filter`](@ref) method can be used to obtain all valid dates/moments in a specified +range: + +```jldoctest +# Pittsburgh street cleaning; Every 2nd Tuesday from April to November +# Date range from January 1st, 2014 to January 1st, 2015 +julia> dr = Dates.Date(2014):Dates.Date(2015); + +julia> filter(dr) do x + Dates.dayofweek(x) == Dates.Tue && + Dates.April <= Dates.month(x) <= Dates.Nov && + Dates.dayofweekofmonth(x) == 2 + end +8-element Array{Date,1}: + 2014-04-08 + 2014-05-13 + 2014-06-10 + 2014-07-08 + 2014-08-12 + 2014-09-09 + 2014-10-14 + 2014-11-11 +``` + +Additional examples and tests are available in [`stdlib/Dates/test/adjusters.jl`](https://github.com/JuliaLang/julia/blob/master/stdlib/Dates/test/adjusters.jl). + +## Period Types + +Periods are a human view of discrete, sometimes irregular durations of time. Consider 1 month; +it could represent, in days, a value of 28, 29, 30, or 31 depending on the year and month context. +Or a year could represent 365 or 366 days in the case of a leap year. [`Period`](@ref) types are +simple [`Int64`](@ref) wrappers and are constructed by wrapping any `Int64` convertible type, i.e. `Year(1)` +or `Month(3.0)`. Arithmetic between [`Period`](@ref) of the same type behave like integers, and +limited `Period-Real` arithmetic is available. + +```jldoctest +julia> y1 = Dates.Year(1) +1 year + +julia> y2 = Dates.Year(2) +2 years + +julia> y3 = Dates.Year(10) +10 years + +julia> y1 + y2 +3 years + +julia> div(y3,y2) +5 + +julia> y3 - y2 +8 years + +julia> y3 % y2 +0 years + +julia> div(y3,3) # mirrors integer division +3 years +``` + +## Rounding + +[`Date`](@ref) and [`DateTime`](@ref) values can be rounded to a specified resolution (e.g., 1 +month or 15 minutes) with [`floor`](@ref), [`ceil`](@ref), or [`round`](@ref): + +```jldoctest +julia> floor(Date(1985, 8, 16), Dates.Month) +1985-08-01 + +julia> ceil(DateTime(2013, 2, 13, 0, 31, 20), Dates.Minute(15)) +2013-02-13T00:45:00 + +julia> round(DateTime(2016, 8, 6, 20, 15), Dates.Day) +2016-08-07T00:00:00 +``` + +Unlike the numeric [`round`](@ref) method, which breaks ties toward the even number by default, +the [`TimeType`](@ref)[`round`](@ref) method uses the `RoundNearestTiesUp` rounding mode. (It's +difficult to guess what breaking ties to nearest "even" [`TimeType`](@ref) would entail.) Further +details on the available `RoundingMode` s can be found in the [API reference](@ref stdlib-dates). + +Rounding should generally behave as expected, but there are a few cases in which the expected +behaviour is not obvious. + +### Rounding Epoch + +In many cases, the resolution specified for rounding (e.g., `Dates.Second(30)`) divides evenly +into the next largest period (in this case, `Dates.Minute(1)`). But rounding behaviour in cases +in which this is not true may lead to confusion. What is the expected result of rounding a [`DateTime`](@ref) +to the nearest 10 hours? + +```jldoctest +julia> round(DateTime(2016, 7, 17, 11, 55), Dates.Hour(10)) +2016-07-17T12:00:00 +``` + +That may seem confusing, given that the hour (12) is not divisible by 10. The reason that `2016-07-17T12:00:00` +was chosen is that it is 17,676,660 hours after `0000-01-01T00:00:00`, and 17,676,660 is divisible +by 10. + +As Julia [`Date`](@ref) and [`DateTime`](@ref) values are represented according to the ISO 8601 +standard, `0000-01-01T00:00:00` was chosen as base (or "rounding epoch") from which to begin the +count of days (and milliseconds) used in rounding calculations. (Note that this differs slightly +from Julia's internal representation of [`Date`](@ref) s using Rata Die notation; but since the +ISO 8601 standard is most visible to the end user, `0000-01-01T00:00:00` was chosen as the rounding +epoch instead of the `0000-12-31T00:00:00` used internally to minimize confusion.) + +The only exception to the use of `0000-01-01T00:00:00` as the rounding epoch is when rounding +to weeks. Rounding to the nearest week will always return a Monday (the first day of the week +as specified by ISO 8601). For this reason, we use `0000-01-03T00:00:00` (the first day of the +first week of year 0000, as defined by ISO 8601) as the base when rounding to a number of weeks. + +Here is a related case in which the expected behaviour is not necessarily obvious: What happens +when we round to the nearest `P(2)`, where `P` is a [`Period`](@ref) type? In some cases (specifically, +when `P <: Dates.TimePeriod`) the answer is clear: + +```jldoctest +julia> round(DateTime(2016, 7, 17, 8, 55, 30), Dates.Hour(2)) +2016-07-17T08:00:00 + +julia> round(DateTime(2016, 7, 17, 8, 55, 30), Dates.Minute(2)) +2016-07-17T08:56:00 +``` + +This seems obvious, because two of each of these periods still divides evenly into the next larger +order period. But in the case of two months (which still divides evenly into one year), the answer +may be surprising: + +```jldoctest +julia> round(DateTime(2016, 7, 17, 8, 55, 30), Dates.Month(2)) +2016-07-01T00:00:00 +``` + +Why round to the first day in July, even though it is month 7 (an odd number)? The key is that +months are 1-indexed (the first month is assigned 1), unlike hours, minutes, seconds, and milliseconds +(the first of which are assigned 0). + +This means that rounding a [`DateTime`](@ref) to an even multiple of seconds, minutes, hours, +or years (because the ISO 8601 specification includes a year zero) will result in a [`DateTime`](@ref) +with an even value in that field, while rounding a [`DateTime`](@ref) to an even multiple of months +will result in the months field having an odd value. Because both months and years may contain +an irregular number of days, whether rounding to an even number of days will result in an even +value in the days field is uncertain. + +See the [API reference](@ref stdlib-dates-api) for additional information +on methods exported from the `Dates` module. + +# [API reference](@id stdlib-dates-api) ## Dates and Time Types From 6b1ba2d6f368520bcd643f73f243705e820e2b66 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Sat, 3 Mar 2018 01:34:49 +0900 Subject: [PATCH 009/153] update Julia Commit df489f0b88 --- codex/NEWS.md | 6 ++ codex/base/arrays.md | 2 +- codex/base/base.md | 1 - codex/base/io-network.md | 20 ------ codex/base/numbers.md | 5 -- codex/devdocs/offset-arrays.md | 2 +- codex/devdocs/ssair.md | 103 +++++++++++++++++++++++++++++ codex/manual/documentation.md | 5 ++ codex/manual/parallel-computing.md | 6 +- codex/manual/strings.md | 2 +- codex/manual/unicode-input.md | 2 +- codex/stdlib/Sockets.md | 25 +++++++ make.jl | 1 + src/NEWS.md | 6 ++ src/base/arrays.md | 2 +- src/base/base.md | 1 - src/base/io-network.md | 20 ------ src/base/numbers.md | 5 -- src/devdocs/offset-arrays.md | 2 +- src/devdocs/ssair.md | 103 +++++++++++++++++++++++++++++ src/manual/documentation.md | 5 ++ src/manual/parallel-computing.md | 6 +- src/manual/strings.md | 2 +- src/manual/unicode-input.md | 2 +- src/stdlib/Sockets.md | 25 +++++++ 25 files changed, 293 insertions(+), 66 deletions(-) create mode 100644 codex/devdocs/ssair.md create mode 100644 codex/stdlib/Sockets.md create mode 100644 src/devdocs/ssair.md create mode 100644 src/stdlib/Sockets.md diff --git a/codex/NEWS.md b/codex/NEWS.md index 88552c2..3e85604 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -208,6 +208,8 @@ Language changes * Underscores for `_italics_` and `__bold__` are now supported by the Base Markdown parser. ([#25564](https://github.com/JuliaLang/julia/issues/25564)) + * `…` (`\dots`) and `⁝` (`\tricolon`) are now parsed as binary operators ([#26262](https://github.com/JuliaLang/julia/issues/26262)). + Breaking changes ---------------- @@ -230,6 +232,10 @@ This section lists changes that do not have deprecation warnings. * `ntuple(f, n::Integer)` throws `ArgumentError` if `n` is negative. Previously an empty tuple was returned ([#21697](https://github.com/JuliaLang/julia/issues/21697)). + * `⋮`, `⋱`, `⋰`, and `⋯` are now parsed as binary operators, not ordinary + identifiers. `≔`, `≕`, and `⩴` now parse with assignment rather than comparison + precedence ([#26262](https://github.com/JuliaLang/julia/issues/26262)). + * Juxtaposing string literals (e.g. `"x"y`) is now a syntax error ([#20575](https://github.com/JuliaLang/julia/issues/20575)). * `finalizer(function, object)` now returns `object` rather than `nothing` ([#24679](https://github.com/JuliaLang/julia/issues/24679)). diff --git a/codex/base/arrays.md b/codex/base/arrays.md index 6ea60b5..402ebab 100644 --- a/codex/base/arrays.md +++ b/codex/base/arrays.md @@ -144,7 +144,7 @@ Base.cumprod Base.cumprod! Base.cumsum Base.cumsum! -LinearAlgebra.diff +Base.diff Base.repeat Base.rot180 Base.rotl90 diff --git a/codex/base/base.md b/codex/base/base.md index 254dc03..2c1db70 100644 --- a/codex/base/base.md +++ b/codex/base/base.md @@ -229,7 +229,6 @@ Base.skipmissing ```@docs Base.run -Base.spawn Base.devnull Base.success Base.process_running diff --git a/codex/base/io-network.md b/codex/base/io-network.md index b28cf9d..c99684c 100644 --- a/codex/base/io-network.md +++ b/codex/base/io-network.md @@ -126,27 +126,7 @@ Base.Multimedia.istextmime ## Network I/O ```@docs -Base.connect(::TCPSocket, ::Integer) -Base.connect(::AbstractString) -Base.listen(::Any) -Base.listen(::AbstractString) -Base.getaddrinfo -Base.getalladdrinfo -Base.getnameinfo -Base.getsockname -Base.getpeername -Base.IPv4 -Base.IPv6 -Base.TCPSocket -Base.UDPSocket Base.bytesavailable -Base.accept -Base.listenany -Base.bind -Base.send -Base.recv -Base.recvfrom -Base.setopt Base.ntoh Base.hton Base.ltoh diff --git a/codex/base/numbers.md b/codex/base/numbers.md index 033590a..deea1c2 100644 --- a/codex/base/numbers.md +++ b/codex/base/numbers.md @@ -41,11 +41,6 @@ Base.Irrational ## Data Formats ```@docs -Base.bin -Base.hex -Base.dec -Base.oct -Base.base Base.digits Base.digits! Base.bitstring diff --git a/codex/devdocs/offset-arrays.md b/codex/devdocs/offset-arrays.md index c26ac58..5288f30 100644 --- a/codex/devdocs/offset-arrays.md +++ b/codex/devdocs/offset-arrays.md @@ -1,4 +1,4 @@ -# Arrays with custom indices +# [Arrays with custom indices](@id man-custom-indices) Julia 0.5 adds experimental support for arrays with arbitrary indices. Conventionally, Julia's arrays are indexed starting at 1, whereas some other languages start numbering at 0, and yet others diff --git a/codex/devdocs/ssair.md b/codex/devdocs/ssair.md new file mode 100644 index 0000000..5ef925e --- /dev/null +++ b/codex/devdocs/ssair.md @@ -0,0 +1,103 @@ +# Julia SSA-form IR + +## Background + +Beginning in Julia 0.7, parts of the compiler use a new [SSA-form](https://en.wikipedia.org/wiki/Static_single_assignment_form) +intermediate representation. Historically, the compiler used to directly generate LLVM IR, from a lowered form of the Julia +AST. This form had most syntactic abstractions removed, but still looked a lot like an abstract syntax tree. +Over time, in order to facilitate optimizations, SSA values were introduced to this IR and the IR was +linearized (i.e. a form where function arguments may only be SSA values or constants). However, non-ssa values +(slots) remained in the IR due to the lack of Phi nodes in the IR (necessary for back-edges and re-merging of +conditional control flow), negating much of the usefulfulness of the SSA form representation to perform +middle end optimizations. Some heroic effort was put into making these optimizations work without a complete SSA +form representation, but the lack of such a representation ultimately proved prohibitive. + +## New IR nodes + +With the new IR representation, the compiler learned to handle two new IR nodes, Phi nodes and Pi +nodes. Phi nodes are part of generic SSA abstraction (see the link above if you're not familar with +the concept). In the Julia IR, these nodes are represented as: +``` +struct PhiNode + edges::Vector{Int} + values::Vector{Any} +end +``` +where we ensure that both vectors always have the same length. In the canonical representation (the one +handles by codegen and the interpreter), the edge values indicate come-from statement numbers (i.e. +if edge has an entry of `15`, there must be a `goto`, `gotoifnot` or implicit fall through from +statement `15` that targets this phi node). Values are either SSA values or constants. It is also +possible for a value to be unassigned if the variable was not defined on this path. However, undefinedness +checks get explicitly inserted and represented as booleans after middle end optimizations, so code generators +may assume that any use of a phi node will have an assigned value in the corresponding slot. It is also legal +for the mapping to be incomplete, i.e. for a phi node to have missing incoming edges. In that case, it must +be dynamically guaranteed that the corresponding value will not be used. + +PiNodes encode statically proven information that may be implicitly assumed in basic blocks dominated by a given +phi node. They are conceptually equivalent to the technique introduced in the paper +"ABCD: Eliminating Array Bounds Checks on Demand" or the predicate info nodes in LLVM. To see how they work, consider, +e.g. + +```julia +%x::Union{Int, Float64} # %x is some Union{Int, Float64} typed ssa value +if isa(x, Int) + # use x +else + # use x +end +``` + +we can perform predicate insertion and turn this into: + +```julia +%x::Union{Int, Float64} # %x is some Union{Int, Float64} typed ssa value +if isa(x, Int) + %x_int = PiNode(x, Int) + # use %x_int +else + %x_float = PiNode(x, Float64) + # use %x_float +end +``` + +Pi nodes are generally ignored in the interpreter, since they don't have any effect on the values, +but they may sometimes lead to code generation in the compiler (e.g. to change from an implicitly +union split representation to a plain unboxed representation). The main usefulness of PiNodes stems +from the fact that path conditions of the values can be accumulated simply by def-use chain walking +that is generally done for most optimizations that care about these conditions anyway. + +# Main SSA data structure + +The main `SSAIR` data structure is worthy of discussion. It draws inspiration from LLVM and Webkit's B3 IR. +The core of the data structure is a flat vector of statements. Each statement is implicitly assigned +an SSA values based on its position in the vector (i.e. the result of the statement at idx 1 can be +accessed using `SSAValue(1)` etc). For each SSA value, we additionally maintain its type. Since, SSA values +are definitionally assigned only once, this type is also the result type of the expression at the corresponding +index. However, while this representation is rather efficient (since the assignments don't need to be explicitly) +encoded, if of course carries the drawback that order is semantically significant, so reorderings and insertions +change statement numbers. Additionally, we do not keep use lists (i.e. it is impossible to walk from a def to +all its uses without explicitly computing this map - def lists however are trivial since you can lookup the +corresponding statement from the index), so the LLVM-style RAUW (replace-all-uses-with) operation is unavailable. + +Instead, we do the following: + +- We keep a separate buffer of nodes to insert (including the position to insert them at, the type of the + corresponding value and the node itself). These nodes are numbered by their occurrence in the insertion + buffer, allowing their values to be immediately used elesewhere in the IR (i.e. if there is 12 statements in + the original statement list, the first new statement will be accessible as `SSAValue(13)`) +- RAUW style operations are performed by setting the corresponding statement index to the replacement + value. +- Statements are erased by setting the corresponding statement to `nothing` (this is essentially just a special-case + convention of the above +- if there are any uses of the statement being erased they will be set to `nothing`) + +There is a `compact!` function that compacts the above data structure by performing the insertion of nodes in the appropriate place, trivial copy propagation and renaming of uses to any changed SSA values. However, the clever part +of this scheme is that this compaction can be done lazily as part of the subsequent pass. Most optimization passes +need to walk over the entire list of statements, performing analysis or modifications along the way. We provide an +`IncrementalCompact` iterator that can be used to iterate over the statement list. It will perform any necessary compaction, +and return the new index of the node, as well as the node itself. It is legal at this point to walk def-use chains, +as well as make any modifications or deletions to the IR (insertions are disallowed however). + +The idea behind this arrangement is that, since the optimization passes need to touch the corresponding memory anyway, +and incur the corresponding memory access penalty, performing the extra housekeeping should have comparitively little +overhead (and save the overhead of maintaining these data structures during IR modification). diff --git a/codex/manual/documentation.md b/codex/manual/documentation.md index 8118e39..bfb24a4 100644 --- a/codex/manual/documentation.md +++ b/codex/manual/documentation.md @@ -182,6 +182,11 @@ As in the example above, we recommend following some simple conventions when wri Docstrings are edited using the same tools as code. Therefore, the same conventions should apply. It it advised to add line breaks after 92 characters. +6. Provide information allowing custom types to implement the function in an + `# Implementation` section. These implementation details intended for developers + rather than users, explaining e.g. which functions should be overridden and which functions + automatically use appropriate fallbacks, are better kept separate from the main description of + the function's behavior. ## Accessing Documentation diff --git a/codex/manual/parallel-computing.md b/codex/manual/parallel-computing.md index 410122d..d70befa 100644 --- a/codex/manual/parallel-computing.md +++ b/codex/manual/parallel-computing.md @@ -1511,8 +1511,8 @@ For instance functions that have their [name ending with `!`](https://docs.julialang.org/en/latest/manual/style-guide/#Append-!-to-names-of-functions-that-modify-their-arguments-1) by convention modify their arguments and thus are not pure. However, there are functions that have side effects and their name does not end with `!`. For -instance [`findfirst(regex, str)`](@Ref) mutates its `regex` argument or -[`rand()`](@Ref) changes `Base.GLOBAL_RNG` : +instance [`findfirst(regex, str)`](@ref) mutates its `regex` argument or +[`rand()`](@ref) changes `Base.GLOBAL_RNG` : ```julia-repl julia> using Base.Threads @@ -1574,7 +1574,7 @@ creates separate instances of `Regex` object for each entry of `rx` vector. The case of `rand` is a bit more complex as we have to ensure that each thread uses non-overlapping pseudorandom number sequences. This can be simply ensured -by using [`randjump`](@Ref) function: +by using [`randjump`](@ref) function: ```julia-repl diff --git a/codex/manual/strings.md b/codex/manual/strings.md index 2f680f7..dcfd739 100644 --- a/codex/manual/strings.md +++ b/codex/manual/strings.md @@ -180,7 +180,7 @@ julia> str[end] Many Julia objects, including strings, can be indexed with integers. The index of the first element is returned by [`firstindex(str)`](@ref), and the index of the last element -with [`lastindex(str)`](@ref). The keyword`end` can be used inside an indexing +with [`lastindex(str)`](@ref). The keyword `end` can be used inside an indexing operation as shorthand for the last index along the given dimension. Most indexing in Julia is 1-based: the first element of many integer-indexed objects is found at index 1. (As we will see below, this does not necessarily mean that the last element is found diff --git a/codex/manual/unicode-input.md b/codex/manual/unicode-input.md index b951301..e7dd653 100644 --- a/codex/manual/unicode-input.md +++ b/codex/manual/unicode-input.md @@ -61,7 +61,7 @@ function table_entries(completions, unicode_dict) for (chars, inputs) in sort!(collect(completions), by = first) code_points, unicode_names, characters = String[], String[], String[] for char in chars - push!(code_points, "U+$(uppercase(hex(char, 5)))") + push!(code_points, "U+$(uppercase(string(UInt32(char), base = 16, pad = 5)))") push!(unicode_names, get(unicode_dict, UInt32(char), "(No Unicode name)")) push!(characters, isempty(characters) ? fix_combining_chars(char) : "$char") end diff --git a/codex/stdlib/Sockets.md b/codex/stdlib/Sockets.md new file mode 100644 index 0000000..d457da9 --- /dev/null +++ b/codex/stdlib/Sockets.md @@ -0,0 +1,25 @@ +## Sockets + +```@docs +Sockets.connect(::TCPSocket, ::Integer) +Sockets.connect(::AbstractString) +Sockets.listen(::Any) +Sockets.listen(::AbstractString) +Sockets.getaddrinfo +Sockets.getipaddr +Sockets.getalladdrinfo +Sockets.getnameinfo +Sockets.getsockname +Sockets.getpeername +Sockets.IPv4 +Sockets.IPv6 +Sockets.TCPSocket +Sockets.UDPSocket +Sockets.accept +Sockets.listenany +Sockets.bind +Sockets.send +Sockets.recv +Sockets.recvfrom +Sockets.setopt +``` diff --git a/make.jl b/make.jl index 34db692..392115c 100644 --- a/make.jl +++ b/make.jl @@ -116,6 +116,7 @@ const PAGES = [ "devdocs/offset-arrays.md", "devdocs/require.md", "devdocs/inference.md", + "devdocs/ssair.md", # Julia SSA-form IR ], "Developing/debugging Julia's C code" => [ "devdocs/backtraces.md", diff --git a/src/NEWS.md b/src/NEWS.md index a09d1bf..1dd861e 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -196,6 +196,8 @@ Language changes * Underscores for `_italics_` and `__bold__` are now supported by the Base Markdown parser. ([#25564](https://github.com/JuliaLang/julia/issues/25564)) + * `…` (`\dots`) and `⁝` (`\tricolon`) are now parsed as binary operators ([#26262](https://github.com/JuliaLang/julia/issues/26262)). + Breaking changes ---------------- @@ -218,6 +220,10 @@ This section lists changes that do not have deprecation warnings. * `ntuple(f, n::Integer)` throws `ArgumentError` if `n` is negative. Previously an empty tuple was returned ([#21697](https://github.com/JuliaLang/julia/issues/21697)). + * `⋮`, `⋱`, `⋰`, and `⋯` are now parsed as binary operators, not ordinary + identifiers. `≔`, `≕`, and `⩴` now parse with assignment rather than comparison + precedence ([#26262](https://github.com/JuliaLang/julia/issues/26262)). + * Juxtaposing string literals (e.g. `"x"y`) is now a syntax error ([#20575](https://github.com/JuliaLang/julia/issues/20575)). * `finalizer(function, object)` now returns `object` rather than `nothing` ([#24679](https://github.com/JuliaLang/julia/issues/24679)). diff --git a/src/base/arrays.md b/src/base/arrays.md index 6ea60b5..402ebab 100644 --- a/src/base/arrays.md +++ b/src/base/arrays.md @@ -144,7 +144,7 @@ Base.cumprod Base.cumprod! Base.cumsum Base.cumsum! -LinearAlgebra.diff +Base.diff Base.repeat Base.rot180 Base.rotl90 diff --git a/src/base/base.md b/src/base/base.md index 254dc03..2c1db70 100644 --- a/src/base/base.md +++ b/src/base/base.md @@ -229,7 +229,6 @@ Base.skipmissing ```@docs Base.run -Base.spawn Base.devnull Base.success Base.process_running diff --git a/src/base/io-network.md b/src/base/io-network.md index b28cf9d..c99684c 100644 --- a/src/base/io-network.md +++ b/src/base/io-network.md @@ -126,27 +126,7 @@ Base.Multimedia.istextmime ## Network I/O ```@docs -Base.connect(::TCPSocket, ::Integer) -Base.connect(::AbstractString) -Base.listen(::Any) -Base.listen(::AbstractString) -Base.getaddrinfo -Base.getalladdrinfo -Base.getnameinfo -Base.getsockname -Base.getpeername -Base.IPv4 -Base.IPv6 -Base.TCPSocket -Base.UDPSocket Base.bytesavailable -Base.accept -Base.listenany -Base.bind -Base.send -Base.recv -Base.recvfrom -Base.setopt Base.ntoh Base.hton Base.ltoh diff --git a/src/base/numbers.md b/src/base/numbers.md index 033590a..deea1c2 100644 --- a/src/base/numbers.md +++ b/src/base/numbers.md @@ -41,11 +41,6 @@ Base.Irrational ## Data Formats ```@docs -Base.bin -Base.hex -Base.dec -Base.oct -Base.base Base.digits Base.digits! Base.bitstring diff --git a/src/devdocs/offset-arrays.md b/src/devdocs/offset-arrays.md index c26ac58..5288f30 100644 --- a/src/devdocs/offset-arrays.md +++ b/src/devdocs/offset-arrays.md @@ -1,4 +1,4 @@ -# Arrays with custom indices +# [Arrays with custom indices](@id man-custom-indices) Julia 0.5 adds experimental support for arrays with arbitrary indices. Conventionally, Julia's arrays are indexed starting at 1, whereas some other languages start numbering at 0, and yet others diff --git a/src/devdocs/ssair.md b/src/devdocs/ssair.md new file mode 100644 index 0000000..5ef925e --- /dev/null +++ b/src/devdocs/ssair.md @@ -0,0 +1,103 @@ +# Julia SSA-form IR + +## Background + +Beginning in Julia 0.7, parts of the compiler use a new [SSA-form](https://en.wikipedia.org/wiki/Static_single_assignment_form) +intermediate representation. Historically, the compiler used to directly generate LLVM IR, from a lowered form of the Julia +AST. This form had most syntactic abstractions removed, but still looked a lot like an abstract syntax tree. +Over time, in order to facilitate optimizations, SSA values were introduced to this IR and the IR was +linearized (i.e. a form where function arguments may only be SSA values or constants). However, non-ssa values +(slots) remained in the IR due to the lack of Phi nodes in the IR (necessary for back-edges and re-merging of +conditional control flow), negating much of the usefulfulness of the SSA form representation to perform +middle end optimizations. Some heroic effort was put into making these optimizations work without a complete SSA +form representation, but the lack of such a representation ultimately proved prohibitive. + +## New IR nodes + +With the new IR representation, the compiler learned to handle two new IR nodes, Phi nodes and Pi +nodes. Phi nodes are part of generic SSA abstraction (see the link above if you're not familar with +the concept). In the Julia IR, these nodes are represented as: +``` +struct PhiNode + edges::Vector{Int} + values::Vector{Any} +end +``` +where we ensure that both vectors always have the same length. In the canonical representation (the one +handles by codegen and the interpreter), the edge values indicate come-from statement numbers (i.e. +if edge has an entry of `15`, there must be a `goto`, `gotoifnot` or implicit fall through from +statement `15` that targets this phi node). Values are either SSA values or constants. It is also +possible for a value to be unassigned if the variable was not defined on this path. However, undefinedness +checks get explicitly inserted and represented as booleans after middle end optimizations, so code generators +may assume that any use of a phi node will have an assigned value in the corresponding slot. It is also legal +for the mapping to be incomplete, i.e. for a phi node to have missing incoming edges. In that case, it must +be dynamically guaranteed that the corresponding value will not be used. + +PiNodes encode statically proven information that may be implicitly assumed in basic blocks dominated by a given +phi node. They are conceptually equivalent to the technique introduced in the paper +"ABCD: Eliminating Array Bounds Checks on Demand" or the predicate info nodes in LLVM. To see how they work, consider, +e.g. + +```julia +%x::Union{Int, Float64} # %x is some Union{Int, Float64} typed ssa value +if isa(x, Int) + # use x +else + # use x +end +``` + +we can perform predicate insertion and turn this into: + +```julia +%x::Union{Int, Float64} # %x is some Union{Int, Float64} typed ssa value +if isa(x, Int) + %x_int = PiNode(x, Int) + # use %x_int +else + %x_float = PiNode(x, Float64) + # use %x_float +end +``` + +Pi nodes are generally ignored in the interpreter, since they don't have any effect on the values, +but they may sometimes lead to code generation in the compiler (e.g. to change from an implicitly +union split representation to a plain unboxed representation). The main usefulness of PiNodes stems +from the fact that path conditions of the values can be accumulated simply by def-use chain walking +that is generally done for most optimizations that care about these conditions anyway. + +# Main SSA data structure + +The main `SSAIR` data structure is worthy of discussion. It draws inspiration from LLVM and Webkit's B3 IR. +The core of the data structure is a flat vector of statements. Each statement is implicitly assigned +an SSA values based on its position in the vector (i.e. the result of the statement at idx 1 can be +accessed using `SSAValue(1)` etc). For each SSA value, we additionally maintain its type. Since, SSA values +are definitionally assigned only once, this type is also the result type of the expression at the corresponding +index. However, while this representation is rather efficient (since the assignments don't need to be explicitly) +encoded, if of course carries the drawback that order is semantically significant, so reorderings and insertions +change statement numbers. Additionally, we do not keep use lists (i.e. it is impossible to walk from a def to +all its uses without explicitly computing this map - def lists however are trivial since you can lookup the +corresponding statement from the index), so the LLVM-style RAUW (replace-all-uses-with) operation is unavailable. + +Instead, we do the following: + +- We keep a separate buffer of nodes to insert (including the position to insert them at, the type of the + corresponding value and the node itself). These nodes are numbered by their occurrence in the insertion + buffer, allowing their values to be immediately used elesewhere in the IR (i.e. if there is 12 statements in + the original statement list, the first new statement will be accessible as `SSAValue(13)`) +- RAUW style operations are performed by setting the corresponding statement index to the replacement + value. +- Statements are erased by setting the corresponding statement to `nothing` (this is essentially just a special-case + convention of the above +- if there are any uses of the statement being erased they will be set to `nothing`) + +There is a `compact!` function that compacts the above data structure by performing the insertion of nodes in the appropriate place, trivial copy propagation and renaming of uses to any changed SSA values. However, the clever part +of this scheme is that this compaction can be done lazily as part of the subsequent pass. Most optimization passes +need to walk over the entire list of statements, performing analysis or modifications along the way. We provide an +`IncrementalCompact` iterator that can be used to iterate over the statement list. It will perform any necessary compaction, +and return the new index of the node, as well as the node itself. It is legal at this point to walk def-use chains, +as well as make any modifications or deletions to the IR (insertions are disallowed however). + +The idea behind this arrangement is that, since the optimization passes need to touch the corresponding memory anyway, +and incur the corresponding memory access penalty, performing the extra housekeeping should have comparitively little +overhead (and save the overhead of maintaining these data structures during IR modification). diff --git a/src/manual/documentation.md b/src/manual/documentation.md index 8118e39..bfb24a4 100644 --- a/src/manual/documentation.md +++ b/src/manual/documentation.md @@ -182,6 +182,11 @@ As in the example above, we recommend following some simple conventions when wri Docstrings are edited using the same tools as code. Therefore, the same conventions should apply. It it advised to add line breaks after 92 characters. +6. Provide information allowing custom types to implement the function in an + `# Implementation` section. These implementation details intended for developers + rather than users, explaining e.g. which functions should be overridden and which functions + automatically use appropriate fallbacks, are better kept separate from the main description of + the function's behavior. ## Accessing Documentation diff --git a/src/manual/parallel-computing.md b/src/manual/parallel-computing.md index 410122d..d70befa 100644 --- a/src/manual/parallel-computing.md +++ b/src/manual/parallel-computing.md @@ -1511,8 +1511,8 @@ For instance functions that have their [name ending with `!`](https://docs.julialang.org/en/latest/manual/style-guide/#Append-!-to-names-of-functions-that-modify-their-arguments-1) by convention modify their arguments and thus are not pure. However, there are functions that have side effects and their name does not end with `!`. For -instance [`findfirst(regex, str)`](@Ref) mutates its `regex` argument or -[`rand()`](@Ref) changes `Base.GLOBAL_RNG` : +instance [`findfirst(regex, str)`](@ref) mutates its `regex` argument or +[`rand()`](@ref) changes `Base.GLOBAL_RNG` : ```julia-repl julia> using Base.Threads @@ -1574,7 +1574,7 @@ creates separate instances of `Regex` object for each entry of `rx` vector. The case of `rand` is a bit more complex as we have to ensure that each thread uses non-overlapping pseudorandom number sequences. This can be simply ensured -by using [`randjump`](@Ref) function: +by using [`randjump`](@ref) function: ```julia-repl diff --git a/src/manual/strings.md b/src/manual/strings.md index 2f680f7..dcfd739 100644 --- a/src/manual/strings.md +++ b/src/manual/strings.md @@ -180,7 +180,7 @@ julia> str[end] Many Julia objects, including strings, can be indexed with integers. The index of the first element is returned by [`firstindex(str)`](@ref), and the index of the last element -with [`lastindex(str)`](@ref). The keyword`end` can be used inside an indexing +with [`lastindex(str)`](@ref). The keyword `end` can be used inside an indexing operation as shorthand for the last index along the given dimension. Most indexing in Julia is 1-based: the first element of many integer-indexed objects is found at index 1. (As we will see below, this does not necessarily mean that the last element is found diff --git a/src/manual/unicode-input.md b/src/manual/unicode-input.md index e0659c7..b156bde 100644 --- a/src/manual/unicode-input.md +++ b/src/manual/unicode-input.md @@ -62,7 +62,7 @@ function table_entries(completions, unicode_dict) for (chars, inputs) in sort!(collect(completions), by = first) code_points, unicode_names, characters = String[], String[], String[] for char in chars - push!(code_points, "U+$(uppercase(hex(char, 5)))") + push!(code_points, "U+$(uppercase(string(UInt32(char), base = 16, pad = 5)))") push!(unicode_names, get(unicode_dict, UInt32(char), "(No Unicode name)")) push!(characters, isempty(characters) ? fix_combining_chars(char) : "$char") end diff --git a/src/stdlib/Sockets.md b/src/stdlib/Sockets.md new file mode 100644 index 0000000..d457da9 --- /dev/null +++ b/src/stdlib/Sockets.md @@ -0,0 +1,25 @@ +## Sockets + +```@docs +Sockets.connect(::TCPSocket, ::Integer) +Sockets.connect(::AbstractString) +Sockets.listen(::Any) +Sockets.listen(::AbstractString) +Sockets.getaddrinfo +Sockets.getipaddr +Sockets.getalladdrinfo +Sockets.getnameinfo +Sockets.getsockname +Sockets.getpeername +Sockets.IPv4 +Sockets.IPv6 +Sockets.TCPSocket +Sockets.UDPSocket +Sockets.accept +Sockets.listenany +Sockets.bind +Sockets.send +Sockets.recv +Sockets.recvfrom +Sockets.setopt +``` From 91c95910bf6b4bd1cc9269858432ce25ec1feb46 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Sun, 4 Mar 2018 22:18:05 +0900 Subject: [PATCH 010/153] =?UTF-8?q?update=20Julia=20Commit=201a870b466d,?= =?UTF-8?q?=20make.jl=20PAGES=20=EC=B2=B4=ED=81=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- REQUIRE | 6 +-- codex/NEWS.md | 3 ++ codex/base/arrays.md | 4 +- codex/base/collections.md | 12 ++--- codex/base/io-network.md | 2 +- codex/devdocs/reflection.md | 34 ++++++------- codex/index.md | 4 +- codex/manual/arrays.md | 4 +- codex/manual/complex-and-rational-numbers.md | 2 +- codex/manual/constructors.md | 17 +++---- codex/manual/control-flow.md | 24 ++++++---- codex/manual/conversion-and-promotion.md | 3 +- codex/manual/embedding.md | 2 +- codex/manual/faq.md | 20 ++++---- codex/manual/functions.md | 9 ++-- codex/manual/index.md | 2 +- codex/manual/interfaces.md | 22 ++++++--- codex/manual/mathematical-operations.md | 20 +++----- codex/manual/metaprogramming.md | 2 +- codex/manual/missing.md | 4 -- codex/manual/parallel-computing.md | 8 ++-- codex/manual/performance-tips.md | 9 ++-- codex/manual/running-external-programs.md | 50 ++++++++------------ codex/manual/strings.md | 21 ++++---- codex/manual/types.md | 23 ++++----- codex/manual/variables-and-scoping.md | 14 +++--- codex/stdlib/Dates.md | 17 ++++--- codex/stdlib/IterativeEigensolvers.md | 37 ++++++--------- codex/stdlib/LinearAlgebra.md | 28 ++++++----- codex/stdlib/Sockets.md | 10 +++- codex/stdlib/SparseArrays.md | 2 +- codex/stdlib/UUIDs.md | 2 +- codex/stdlib/dates.md | 17 ++++--- codex/stdlib/iterativeeigensolvers.md | 37 ++++++--------- codex/stdlib/linearalgebra.md | 28 ++++++----- codex/stdlib/sparsearrays.md | 2 +- src/NEWS.md | 3 ++ src/base/arrays.md | 4 +- src/base/collections.md | 12 ++--- src/base/io-network.md | 2 +- src/devdocs/reflection.md | 34 ++++++------- src/index.md | 4 +- src/manual/arrays.md | 4 +- src/manual/complex-and-rational-numbers.md | 2 +- src/manual/constructors.md | 17 +++---- src/manual/control-flow.md | 24 ++++++---- src/manual/conversion-and-promotion.md | 3 +- src/manual/embedding.md | 2 +- src/manual/faq.md | 20 ++++---- src/manual/functions.md | 9 ++-- src/manual/index.md | 2 +- src/manual/interfaces.md | 22 ++++++--- src/manual/mathematical-operations.md | 20 +++----- src/manual/metaprogramming.md | 2 +- src/manual/missing.md | 4 -- src/manual/parallel-computing.md | 8 ++-- src/manual/performance-tips.md | 9 ++-- src/manual/running-external-programs.md | 50 ++++++++------------ src/manual/strings.md | 21 ++++---- src/manual/types.md | 23 ++++----- src/manual/variables-and-scoping.md | 14 +++--- src/stdlib/Dates.md | 17 ++++--- src/stdlib/IterativeEigensolvers.md | 37 ++++++--------- src/stdlib/LinearAlgebra.md | 28 ++++++----- src/stdlib/Sockets.md | 10 +++- src/stdlib/SparseArrays.md | 2 +- src/stdlib/UUIDs.md | 2 +- src/stdlib/dates.md | 17 ++++--- src/stdlib/iterativeeigensolvers.md | 37 ++++++--------- src/stdlib/linearalgebra.md | 28 ++++++----- src/stdlib/sparsearrays.md | 2 +- tools/check_codex.jl | 46 +++++++++++++++--- 72 files changed, 530 insertions(+), 512 deletions(-) diff --git a/REQUIRE b/REQUIRE index f712c56..8b6fd17 100644 --- a/REQUIRE +++ b/REQUIRE @@ -1,3 +1,3 @@ -Compat 0.39.0 0.39.0+ -DocStringExtensions 0.4.1 0.4.1+ -Documenter 0.12.4 0.12.4+ +Compat 0.56.0 0.56.0+ +DocStringExtensions 0.4.3 0.4.3+ +Documenter 0.14.0 0.14.0+ diff --git a/codex/NEWS.md b/codex/NEWS.md index 3e85604..546e4ef 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -587,6 +587,9 @@ Library improvements collection `A`. There are also two other methods with a different API, and a mutating variant, `replace!` ([#22324](https://github.com/JuliaLang/julia/issues/22324)). + * Adding integers to `CartesianIndex` objects is now deprecated. Instead of + `i::Int + x::CartesianIndex`, use `i*one(x) + x` ([#26284](https://github.com/JuliaLang/julia/issues/26284)). + * `CartesianRange` changes ([#24715](https://github.com/JuliaLang/julia/issues/24715)): - Inherits from `AbstractArray`, and linear indexing can be used to provide linear-to-cartesian conversion ([#24715](https://github.com/JuliaLang/julia/issues/24715)) diff --git a/codex/base/arrays.md b/codex/base/arrays.md index 402ebab..11b3c6d 100644 --- a/codex/base/arrays.md +++ b/codex/base/arrays.md @@ -138,7 +138,7 @@ Base.promote_shape ## Array functions ```@docs -Base.accumulate(::Any, ::Any, ::Integer) +Base.accumulate Base.accumulate! Base.cumprod Base.cumprod! @@ -149,8 +149,6 @@ Base.repeat Base.rot180 Base.rotl90 Base.rotr90 -Base.reducedim -Base.mapreducedim Base.mapslices ``` diff --git a/codex/base/collections.md b/codex/base/collections.md index 43ba36a..cdc77c2 100644 --- a/codex/base/collections.md +++ b/codex/base/collections.md @@ -88,20 +88,16 @@ Base.foldl(::Any, ::Any, ::Any) Base.foldl(::Any, ::Any) Base.foldr(::Any, ::Any, ::Any) Base.foldr(::Any, ::Any) -Base.maximum(::Any) -Base.maximum(::Any, ::Any) +Base.maximum Base.maximum! -Base.minimum(::Any) -Base.minimum(::Any, ::Any) +Base.minimum Base.minimum! Base.extrema(::Any) Base.extrema(::AbstractArray, ::Any) Base.argmax Base.argmin -Base.findmax(::Any) -Base.findmax(::AbstractArray, ::Any) -Base.findmin(::Any) -Base.findmin(::AbstractArray, ::Any) +Base.findmax +Base.findmin Base.findmax! Base.findmin! Base.sum diff --git a/codex/base/io-network.md b/codex/base/io-network.md index c99684c..9c0cf81 100644 --- a/codex/base/io-network.md +++ b/codex/base/io-network.md @@ -94,7 +94,7 @@ Base.Multimedia.redisplay Base.Multimedia.displayable Base.show(::Any, ::Any, ::Any) Base.Multimedia.showable -Base.repr(::Any, ::Any) +Base.repr(::MIME, ::Any) ``` As mentioned above, one can also define new display backends. For example, a module that can display diff --git a/codex/devdocs/reflection.md b/codex/devdocs/reflection.md index d664ef0..23ff13b 100644 --- a/codex/devdocs/reflection.md +++ b/codex/devdocs/reflection.md @@ -11,7 +11,7 @@ returns symbols for all bindings in `m`, regardless of export status. ## DataType fields The names of `DataType` fields may be interrogated using [`fieldnames`](@ref). For example, -given the following type, `fieldnames(Point)` returns an arrays of [`Symbol`](@ref) elements representing +given the following type, `fieldnames(Point)` returns a tuple of [`Symbol`](@ref)s representing the field names: ```jldoctest struct_point @@ -21,9 +21,7 @@ julia> struct Point end julia> fieldnames(Point) -2-element Array{Symbol,1}: - :x - :y +(:x, :y) ``` The type of each field in a `Point` object is stored in the `types` field of the `Point` variable @@ -52,9 +50,9 @@ of these fields is the `types` field observed in the example above. The *direct* subtypes of any `DataType` may be listed using [`subtypes`](@ref). For example, the abstract `DataType` [`AbstractFloat`](@ref) has four (concrete) subtypes: -```jldoctest +```jldoctest; setup = :(using InteractiveUtils) julia> subtypes(AbstractFloat) -4-element Array{Union{DataType, UnionAll},1}: +4-element Array{Any,1}: BigFloat Float16 Float32 @@ -83,9 +81,9 @@ the unquoted and interpolated expression (`Expr`) form for a given macro. To use `quote` the expression block itself (otherwise, the macro will be evaluated and the result will be passed instead!). For example: -```jldoctest +```jldoctest; setup = :(using InteractiveUtils) julia> macroexpand(@__MODULE__, :(@edit println("")) ) -:((Base.edit)(println, (Base.typesof)(""))) +:((InteractiveUtils.edit)(println, (Base.typesof)(""))) ``` The functions `Base.Meta.show_sexpr` and [`dump`](@ref) are used to display S-expr style views @@ -97,14 +95,18 @@ and variable assignments: ```jldoctest julia> Meta.lower(@__MODULE__, :(f() = 1) ) -:(begin - $(Expr(:method, :f)) - $(Expr(:method, :f, :((Core.svec)((Core.svec)((Core.Typeof)(f)), (Core.svec)())), CodeInfo(:(begin - #= none:1 =# - return 1 - end)), false)) - return f - end) +:($(Expr(:thunk, CodeInfo(:(begin + $(Expr(:method, :f)) + Core.SSAValue(0) = (Core.Typeof)(f) + Core.SSAValue(1) = (Core.svec)(Core.SSAValue(0)) + Core.SSAValue(2) = (Core.svec)() + Core.SSAValue(3) = (Core.svec)(Core.SSAValue(1), Core.SSAValue(2)) + $(Expr(:method, :f, Core.SSAValue(3), CodeInfo(:(begin + #= none:1 =# + return 1 + end)))) + return f + end))))) ``` ## Intermediate and compiled representations diff --git a/codex/index.md b/codex/index.md index f7e5765..dba35ba 100644 --- a/codex/index.md +++ b/codex/index.md @@ -79,7 +79,7 @@ Please read the [release notes](NEWS.md) to see what has changed since the last * [Base64](@ref) * [CRC32c](@ref) * [SHA](@ref) - * [Dates](@ref stdlib-dates) + * [Dates](@ref) * [Delimited Files](@ref) * [Distributed Computing](@ref) * [File Events](@ref lib-filewatching) @@ -114,7 +114,7 @@ Please read the [release notes](NEWS.md) to see what has changed since the last * [printf() and stdio in the Julia runtime](@ref) * [Bounds checking](@ref) * [Proper maintenance and care of multi-threading locks](@ref) - * [Arrays with custom indices](@ref) + * [Arrays with custom indices](@ref man-custom-indices) * [Module loading](@ref) * [Inference](@ref) * Developing/debugging Julia's C code diff --git a/codex/manual/arrays.md b/codex/manual/arrays.md index 09ca6a3..28f2c51 100644 --- a/codex/manual/arrays.md +++ b/codex/manual/arrays.md @@ -661,8 +661,8 @@ it also handles tuples and treats any argument that is not an array, tuple or [` ```jldoctest julia> convert.(Float32, [1, 2]) 2-element Array{Float32,1}: - 1.0f0 - 2.0f0 + 1.0 + 2.0 julia> ceil.((UInt8,), [1.2 3.4; 5.6 6.7]) 2×2 Array{UInt8,2}: diff --git a/codex/manual/complex-and-rational-numbers.md b/codex/manual/complex-and-rational-numbers.md index ebb7a06..9f49aa0 100644 --- a/codex/manual/complex-and-rational-numbers.md +++ b/codex/manual/complex-and-rational-numbers.md @@ -37,7 +37,7 @@ julia> (-1 + 2im)^2 -3 - 4im julia> (-1 + 2im)^2.5 -2.7296244647840084 - 6.960664459571898im +2.729624464784009 - 6.9606644595719im julia> (-1 + 2im)^(1 + 1im) -0.27910381075826657 + 0.08708053414102428im diff --git a/codex/manual/constructors.md b/codex/manual/constructors.md index 153d6e3..8ee79ea 100644 --- a/codex/manual/constructors.md +++ b/codex/manual/constructors.md @@ -97,14 +97,16 @@ julia> struct OrderedPair Now `OrderedPair` objects can only be constructed such that `x <= y`: -```jldoctest pairtype +```jldoctest pairtype; filter = r"Stacktrace:(\n \[[0-9]+\].*)*" julia> OrderedPair(1, 2) OrderedPair(1, 2) julia> OrderedPair(2,1) ERROR: out of order Stacktrace: - [1] OrderedPair(::Int64, ::Int64) at ./none:4 + [1] error at ./error.jl:33 [inlined] + [2] OrderedPair(::Int64, ::Int64) at ./none:4 + [3] top-level scope ``` If the type were declared `mutable`, you could reach in and directly change the field values to @@ -277,7 +279,7 @@ that, by default, instances of parametric composite types can be constructed eit given type parameters or with type parameters implied by the types of the arguments given to the constructor. Here are some examples: -```jldoctest parametric +```jldoctest parametric; filter = r"Closest candidates.*\n .*" julia> struct Point{T<:Real} x::T y::T @@ -292,16 +294,15 @@ Point{Float64}(1.0, 2.5) julia> Point(1,2.5) ## implicit T ## ERROR: MethodError: no method matching Point(::Int64, ::Float64) Closest candidates are: - Point(::T<:Real, !Matched::T<:Real) where T<:Real at none:2 + Point(::T<:Real, ::T<:Real) where T<:Real at none:2 julia> Point{Int64}(1, 2) ## explicit T ## Point{Int64}(1, 2) julia> Point{Int64}(1.0,2.5) ## explicit T ## -ERROR: InexactError: convert(Int64, 2.5) +ERROR: InexactError: Int64(Int64, 2.5) Stacktrace: - [1] convert at ./float.jl:703 [inlined] - [2] Point{Int64}(::Float64, ::Float64) at ./none:2 +[...] julia> Point{Float64}(1.0, 2.5) ## explicit T ## Point{Float64}(1.0, 2.5) @@ -502,7 +503,7 @@ julia> typeof(z) <: Complex{OurRational} false ``` -Thus, although the [`⊘`](@ref) operator usually returns an instance of `OurRational`, if either +Thus, although the `⊘` operator usually returns an instance of `OurRational`, if either of its arguments are complex integers, it will return an instance of `Complex{OurRational}` instead. The interested reader should consider perusing the rest of [`rational.jl`](https://github.com/JuliaLang/julia/blob/master/base/rational.jl): it is short, self-contained, and implements an entire basic Julia type. diff --git a/codex/manual/control-flow.md b/codex/manual/control-flow.md index 18dd982..5d38a7f 100644 --- a/codex/manual/control-flow.md +++ b/codex/manual/control-flow.md @@ -124,7 +124,7 @@ The variable `relation` is declared inside the `if` block, but used outside. How on this behavior, make sure all possible code paths define a value for the variable. The following change to the above function results in a runtime error -```jldoctest +```jldoctest; filter = r"Stacktrace:(\n \[[0-9]+\].*)*" julia> function test(x,y) if x < y relation = "less than" @@ -315,7 +315,7 @@ one can write ` || ` (which could be read as: *or else* For example, a recursive factorial routine could be defined like this: -```jldoctest +```jldoctest; filter = r"Stacktrace:(\n \[[0-9]+\].*)*" julia> function fact(n::Int) n >= 0 || error("n must be non-negative") n == 0 && return 1 @@ -332,7 +332,9 @@ julia> fact(0) julia> fact(-1) ERROR: n must be non-negative Stacktrace: - [1] fact(::Int64) at ./none:2 + [1] error at ./error.jl:33 [inlined] + [2] fact(::Int64) at ./none:2 + [3] top-level scope ``` Boolean operations *without* short-circuit evaluation can be done with the bitwise boolean operators @@ -589,7 +591,7 @@ Exceptions can be created explicitly with [`throw`](@ref). For example, a functi for nonnegative numbers could be written to [`throw`](@ref) a [`DomainError`](@ref) if the argument is negative: -```jldoctest +```jldoctest; filter = r"Stacktrace:(\n \[[0-9]+\].*)*" julia> f(x) = x>=0 ? exp(-x) : throw(DomainError(x, "argument must be nonnegative")) f (generic function with 1 method) @@ -652,7 +654,7 @@ Suppose we want to stop execution immediately if the square root of a negative n To do this, we can define a fussy version of the [`sqrt`](@ref) function that raises an error if its argument is negative: -```jldoctest fussy_sqrt +```jldoctest fussy_sqrt; filter = r"Stacktrace:(\n \[[0-9]+\].*)*" julia> fussy_sqrt(x) = x >= 0 ? sqrt(x) : error("negative x not allowed") fussy_sqrt (generic function with 1 method) @@ -662,14 +664,16 @@ julia> fussy_sqrt(2) julia> fussy_sqrt(-1) ERROR: negative x not allowed Stacktrace: - [1] fussy_sqrt(::Int64) at ./none:1 + [1] error at ./error.jl:33 [inlined] + [2] fussy_sqrt(::Int64) at ./none:1 + [3] top-level scope ``` If `fussy_sqrt` is called with a negative value from another function, instead of trying to continue execution of the calling function, it returns immediately, displaying the error message in the interactive session: -```jldoctest fussy_sqrt +```jldoctest fussy_sqrt; filter = r"Stacktrace:(\n \[[0-9]+\].*)*" julia> function verbose_fussy_sqrt(x) println("before fussy_sqrt") r = fussy_sqrt(x) @@ -687,8 +691,10 @@ julia> verbose_fussy_sqrt(-1) before fussy_sqrt ERROR: negative x not allowed Stacktrace: - [1] fussy_sqrt at ./none:1 [inlined] - [2] verbose_fussy_sqrt(::Int64) at ./none:3 + [1] error at ./error.jl:33 [inlined] + [2] fussy_sqrt at ./none:1 [inlined] + [3] verbose_fussy_sqrt(::Int64) at ./none:3 + [4] top-level scope ``` ### The `try/catch` statement diff --git a/codex/manual/conversion-and-promotion.md b/codex/manual/conversion-and-promotion.md index b824c97..7345334 100644 --- a/codex/manual/conversion-and-promotion.md +++ b/codex/manual/conversion-and-promotion.md @@ -88,7 +88,8 @@ doesn't know how to perform the requested conversion: ```jldoctest julia> convert(AbstractFloat, "foo") -ERROR: MethodError: Cannot `convert` an object of type String to an object of type AbstractFloat. +ERROR: MethodError: Cannot `convert` an object of type String to an object of type AbstractFloat +[...] ``` Some languages consider parsing strings as numbers or formatting numbers as strings to be conversions diff --git a/codex/manual/embedding.md b/codex/manual/embedding.md index 54cabeb..496d0f1 100644 --- a/codex/manual/embedding.md +++ b/codex/manual/embedding.md @@ -44,7 +44,7 @@ gcc -o test -fPIC -I$JULIA_DIR/include/julia -L$JULIA_DIR/lib test.c -ljulia $JU Then if the environment variable `JULIA_BINDIR` is set to `$JULIA_DIR/bin`, the output `test` program can be executed. -Alternatively, look at the `embedding.c` program in the Julia source tree in the `examples/` folder. +Alternatively, look at the `embedding.c` program in the Julia source tree in the `test/embedding/` folder. The file `ui/repl.c` program is another simple example of how to set `jl_options` options while linking against `libjulia`. diff --git a/codex/manual/faq.md b/codex/manual/faq.md index fe8ca94..da68118 100644 --- a/codex/manual/faq.md +++ b/codex/manual/faq.md @@ -147,18 +147,18 @@ argument is called slurping: ```jldoctest julia> function printargs(args...) - @printf("%s\n", typeof(args)) + println(typeof(args)) for (i, arg) in enumerate(args) - @printf("Arg %d = %s\n", i, arg) + println("Arg #$i = $arg") end end printargs (generic function with 1 method) julia> printargs(1, 2, 3) Tuple{Int64,Int64,Int64} -Arg 1 = 1 -Arg 2 = 2 -Arg 3 = 3 +Arg #1 = 1 +Arg #2 = 2 +Arg #3 = 3 ``` If Julia were a language that made more liberal use of ASCII characters, the slurping operator @@ -173,19 +173,19 @@ call. This use of `...` is called splatting: ```jldoctest julia> function threeargs(a, b, c) - @printf("a = %s::%s\n", a, typeof(a)) - @printf("b = %s::%s\n", b, typeof(b)) - @printf("c = %s::%s\n", c, typeof(c)) + println("a = $a::$(typeof(a))") + println("b = $b::$(typeof(b))") + println("c = $c::$(typeof(c))") end threeargs (generic function with 1 method) -julia> vec = [1, 2, 3] +julia> x = [1, 2, 3] 3-element Array{Int64,1}: 1 2 3 -julia> threeargs(vec...) +julia> threeargs(x...) a = 1::Int64 b = 2::Int64 c = 3::Int64 diff --git a/codex/manual/functions.md b/codex/manual/functions.md index db16602..5779954 100644 --- a/codex/manual/functions.md +++ b/codex/manual/functions.md @@ -129,9 +129,12 @@ A return type can also be specified in the function declaration using the `::` o the return value to the specified type. ```jldoctest -function g(x,y)::Int8 - return x * y -end +julia> function g(x, y)::Int8 + return x * y + end; + +julia> typeof(g(1, 2)) +Int8 ``` This function will always return an `Int8` regardless of the types of `x` and `y`. diff --git a/codex/manual/index.md b/codex/manual/index.md index 5d776d5..148d5e0 100644 --- a/codex/manual/index.md +++ b/codex/manual/index.md @@ -22,7 +22,7 @@ * [Missing Values](@ref missing) * [Networking and Streams](@ref) * [Parallel Computing](@ref) - * [Date and DateTime](@ref) + * [Dates](@ref) * [Running External Programs](@ref) * [Calling C and Fortran Code](@ref) * [Handling Operating System Variation](@ref) diff --git a/codex/manual/interfaces.md b/codex/manual/interfaces.md index 236641c..2349da9 100644 --- a/codex/manual/interfaces.md +++ b/codex/manual/interfaces.md @@ -39,7 +39,7 @@ tests if there are any elements remaining, and `next(iter, state)`, which return the current element and an updated `state`. The `state` object can be anything, and is generally considered to be an implementation detail private to the iterable object. -Any object defines these three methods is iterable and can be used in the [many functions that rely upon iteration](@ref lib-collections-iteration). +Any object that defines these three methods is iterable and can be used in the [many functions that rely upon iteration](@ref lib-collections-iteration). It can also be used directly in a `for` loop since the syntax: ```julia @@ -189,6 +189,7 @@ valid index. It is recommended to also define [`firstindex`](@ref) to specify th ```jldoctest squaretype julia> Base.firstindex(S::Squares) = 1 + julia> Base.lastindex(S::Squares) = length(S) julia> Squares(23)[end] @@ -400,7 +401,8 @@ julia> mean(A) 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`](@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). +perhaps range-types `Ind` of your own design. For more information, see +[Arrays with custom indices](@ref man-custom-indices). ## [Strided Arrays](@id man-interface-strided-arrays) @@ -505,7 +507,7 @@ However, if needed you can specialize on any or all of these arguments. For a complete example, let's say you have created a type, `ArrayAndChar`, that stores an array and a single character: -```jldoctest +```jldoctest ArrayAndChar struct ArrayAndChar{T,N} <: AbstractArray{T,N} data::Array{T,N} char::Char @@ -514,16 +516,20 @@ Base.size(A::ArrayAndChar) = size(A.data) Base.getindex(A::ArrayAndChar{T,N}, inds::Vararg{Int,N}) where {T,N} = A.data[inds...] Base.setindex!(A::ArrayAndChar{T,N}, val, inds::Vararg{Int,N}) where {T,N} = A.data[inds...] = val Base.showarg(io::IO, A::ArrayAndChar, toplevel) = print(io, typeof(A), " with char '", A.char, "'") +# output + ``` You might want broadcasting to preserve the `char` "metadata." First we define -```jldoctest +```jldoctest ArrayAndChar Base.BroadcastStyle(::Type{<:ArrayAndChar}) = Broadcast.ArrayStyle{ArrayAndChar}() +# output + ``` This forces us to also define a `broadcast_similar` method: -```jldoctest +```jldoctest ArrayAndChar; filter = r"(^find_aac \(generic function with 2 methods\)$|^$)" function Base.broadcast_similar(f, ::Broadcast.ArrayStyle{ArrayAndChar}, ::Type{ElType}, inds, As...) where ElType # Scan the inputs for the ArrayAndChar: A = find_aac(As...) @@ -533,11 +539,13 @@ end "`A = find_aac(As...)` returns the first ArrayAndChar among the arguments." find_aac(A::ArrayAndChar, B...) = A -find_aac(A, B...) = find_aac(B...) +find_aac(A, B...) = find_aac(B...); +# output + ``` From these definitions, one obtains the following behavior: -```jldoctest +```jldoctest ArrayAndChar julia> a = ArrayAndChar([1 2; 3 4], 'x') 2×2 ArrayAndChar{Int64,2} with char 'x': 1 2 diff --git a/codex/manual/mathematical-operations.md b/codex/manual/mathematical-operations.md index b539efb..f33449c 100644 --- a/codex/manual/mathematical-operations.md +++ b/codex/manual/mathematical-operations.md @@ -380,7 +380,7 @@ You can also find the numerical precedence for any given operator via the built- ```jldoctest julia> Base.operator_precedence(:+), Base.operator_precedence(:*), Base.operator_precedence(:.) -(9, 11, 15) +(11, 13, 17) julia> Base.operator_precedence(:sin), Base.operator_precedence(:+=), Base.operator_precedence(:(=)) # (Note the necessary parens on `:(=)`) (0, 1, 1) @@ -424,25 +424,20 @@ julia> Int8(127) julia> Int8(128) ERROR: InexactError: trunc(Int8, 128) Stacktrace: - [1] throw_inexacterror(::Symbol, ::Type{Int8}, ::Int64) at ./int.jl:34 - [2] checked_trunc_sint at ./int.jl:438 [inlined] - [3] convert at ./int.jl:458 [inlined] - [4] Int8(::Int64) at ./sysimg.jl:114 +[...] julia> Int8(127.0) 127 julia> Int8(3.14) -ERROR: InexactError: convert(Int8, 3.14) +ERROR: InexactError: Int8(Int8, 3.14) Stacktrace: - [1] convert at ./float.jl:682 [inlined] - [2] Int8(::Float64) at ./sysimg.jl:114 +[...] julia> Int8(128.0) -ERROR: InexactError: convert(Int8, 128.0) +ERROR: InexactError: Int8(Int8, 128.0) Stacktrace: - [1] convert at ./float.jl:682 [inlined] - [2] Int8(::Float64) at ./sysimg.jl:114 +[...] julia> 127 % Int8 127 @@ -456,8 +451,7 @@ julia> round(Int8,127.4) julia> round(Int8,127.6) ERROR: InexactError: trunc(Int8, 128.0) Stacktrace: - [1] trunc at ./float.jl:675 [inlined] - [2] round(::Type{Int8}, ::Float64) at ./float.jl:353 +[...] ``` See [Conversion and Promotion](@ref conversion-and-promotion) for how to define your own conversions and promotions. diff --git a/codex/manual/metaprogramming.md b/codex/manual/metaprogramming.md index 2ac0c0c..901076c 100644 --- a/codex/manual/metaprogramming.md +++ b/codex/manual/metaprogramming.md @@ -216,7 +216,7 @@ Interpolating into an unquoted expression is not supported and will cause a comp ```jldoctest interp1 julia> $a + b -ERROR: unsupported or misplaced expression $ +ERROR: syntax: "$" expression outside quote ``` In this example, the tuple `(1,2,3)` is interpolated as an expression into a conditional test: diff --git a/codex/manual/missing.md b/codex/manual/missing.md index 89ccb7f..4467f58 100644 --- a/codex/manual/missing.md +++ b/codex/manual/missing.md @@ -276,10 +276,6 @@ julia> y = Union{Missing, String}[missing, "b"] julia> convert(Array{String}, y) ERROR: MethodError: Cannot `convert` an object of type Missing to an object of type String -This may have arisen from a call to the constructor String(...), -since type constructors fall back to convert methods. -Stacktrace: -[... ``` ## Skipping Missing Values diff --git a/codex/manual/parallel-computing.md b/codex/manual/parallel-computing.md index d70befa..58bdaf9 100644 --- a/codex/manual/parallel-computing.md +++ b/codex/manual/parallel-computing.md @@ -727,7 +727,8 @@ Methods [`put!`](@ref), [`take!`](@ref), [`fetch`](@ref), [`isready`](@ref) and on a [`RemoteChannel`](@ref) are proxied onto the backing store on the remote process. [`RemoteChannel`](@ref) can thus be used to refer to user implemented `AbstractChannel` objects. -A simple example of this is provided in `examples/dictchannel.jl` which uses a dictionary as its +A simple example of this is provided in `dictchannel.jl` in the +[Examples repository](https://github.com/JuliaArchive/Examples), which uses a dictionary as its remote store. ## Channels and RemoteChannels @@ -1246,7 +1247,8 @@ transport and Julia's in-built parallel infrastructure. A `BufferStream` is an in-memory [`IOBuffer`](@ref) which behaves like an `IO`--it is a stream which can be handled asynchronously. -Folder `examples/clustermanager/0mq` contains an example of using ZeroMQ to connect Julia workers +The folder `clustermanager/0mq` in the [Examples repository](https://github.com/JuliaArchive/Examples) +contains an example of using ZeroMQ to connect Julia workers in a star topology with a 0MQ broker in the middle. Note: The Julia processes are still all *logically* connected to each other--any worker can message any other worker directly without any awareness of 0MQ being used as the transport layer. @@ -1268,7 +1270,7 @@ When using custom transports: the corresponding `IO` objects must be closed by the implementation to ensure proper cleanup. The default implementation simply executes an `exit()` call on the specified remote worker. -`examples/clustermanager/simple` is an example that shows a simple implementation using UNIX domain +The Examples folder `clustermanager/simple` is an example that shows a simple implementation using UNIX domain sockets for cluster setup. ## Network Requirements for LocalManager and SSHManager diff --git a/codex/manual/performance-tips.md b/codex/manual/performance-tips.md index a832506..84dd79c 100644 --- a/codex/manual/performance-tips.md +++ b/codex/manual/performance-tips.md @@ -453,10 +453,7 @@ MyBetterContainer{Float64,UnitRange{Float64}} julia> b = MyBetterContainer{Int64, UnitRange{Float64}}(UnitRange(1.3, 5.0)); ERROR: MethodError: Cannot `convert` an object of type UnitRange{Float64} to an object of type MyBetterContainer{Int64,UnitRange{Float64}} -This may have arisen from a call to the constructor MyBetterContainer{Int64,UnitRange{Float64}}(...), -since type constructors fall back to convert methods. -Stacktrace: - [1] MyBetterContainer{Int64,UnitRange{Float64}}(::UnitRange{Float64}) at ./sysimg.jl:114 +[...] ``` The inner constructor requires that the element type of `A` be `T`. @@ -621,7 +618,7 @@ end ```jldoctest julia> function strange_twos(n) - a = Vector{rand(Bool) ? Int64 : Float64}(n) + a = Vector{rand(Bool) ? Int64 : Float64}(uninitialized, n) for i = 1:n a[i] = 2 end @@ -640,7 +637,7 @@ This should be written as: ```jldoctest julia> function fill_twos!(a) - for i=eachindex(a) + for i = eachindex(a) a[i] = 2 end end diff --git a/codex/manual/running-external-programs.md b/codex/manual/running-external-programs.md index 88fc044..749d88b 100644 --- a/codex/manual/running-external-programs.md +++ b/codex/manual/running-external-programs.md @@ -29,7 +29,7 @@ julia> mycommand = `echo hello` julia> typeof(mycommand) Cmd -julia> run(mycommand) +julia> run(mycommand); hello ``` @@ -209,7 +209,7 @@ values. Let's try the above two examples in Julia: julia> A = `perl -le '$|=1; for (0..3) { print }'` `perl -le '$|=1; for (0..3) { print }'` -julia> run(A) +julia> run(A); 0 1 2 @@ -220,7 +220,7 @@ julia> first = "A"; second = "B"; julia> B = `perl -le 'print for @ARGV' "1: $first" "2: $second"` `perl -le 'print for @ARGV' '1: A' '2: B'` -julia> run(B) +julia> run(B); 1: A 2: B ``` @@ -236,10 +236,10 @@ easily and safely just examine its interpretation without doing any damage. Shell metacharacters, such as `|`, `&`, and `>`, need to be quoted (or escaped) inside of Julia's backticks: ```jldoctest -julia> run(`echo hello '|' sort`) +julia> run(`echo hello '|' sort`); hello | sort -julia> run(`echo hello \| sort`) +julia> run(`echo hello \| sort`); hello | sort ``` @@ -248,7 +248,7 @@ The result is that a single line is printed: `hello | sort`. How, then, does one pipeline? Instead of using `'|'` inside of backticks, one uses [`pipeline`](@ref): ```jldoctest -julia> run(pipeline(`echo hello`, `sort`)) +julia> run(pipeline(`echo hello`, `sort`)); hello ``` @@ -273,8 +273,8 @@ that shells cannot. Julia can run multiple commands in parallel: -```julia-repl -julia> run(`echo hello` & `echo world`) +```jldoctest; filter = r"(world\nhello|hello\nworld)" +julia> run(`echo hello` & `echo world`); world hello ``` @@ -285,7 +285,7 @@ share with each other and the `julia` parent process. Julia lets you pipe the ou of these processes to another program: ```jldoctest -julia> run(pipeline(`echo world` & `echo hello`, `sort`)) +julia> run(pipeline(`echo world` & `echo hello`, `sort`)); hello world ``` @@ -326,24 +326,20 @@ setup of pipes between processes is a powerful one. To give some sense of the co that can be created easily, here are some more sophisticated examples, with apologies for the excessive use of Perl one-liners: -```julia-repl +```jldoctest prefixer; filter = r"([A-B] [0-5])" julia> prefixer(prefix, sleep) = `perl -nle '$|=1; print "'$prefix' ", $_; sleep '$sleep';'`; -julia> run(pipeline(`perl -le '$|=1; for(0..9){ print; sleep 1 }'`, prefixer("A",2) & prefixer("B",2))) -A 0 -B 1 -A 2 -B 3 -A 4 -B 5 -A 6 -B 7 -A 8 -B 9 +julia> run(pipeline(`perl -le '$|=1; for(0..5){ print; sleep 1 }'`, prefixer("A",2) & prefixer("B",2))); +B 0 +A 1 +B 2 +A 3 +B 4 +A 5 ``` This is a classic example of a single producer feeding two concurrent consumers: one `perl` process -generates lines with the numbers 0 through 9 on them, while two parallel processes consume that +generates lines with the numbers 0 through 5 on them, while two parallel processes consume that output, one prefixing lines with the letter "A", the other with the letter "B". Which consumer gets the first line is non-deterministic, but once that race has been won, the lines are consumed alternately by one process and then the other. (Setting `$|=1` in Perl causes each print statement @@ -352,20 +348,16 @@ the output is buffered and printed to the pipe at once, to be read by just one c Here is an even more complex multi-stage producer-consumer example: -```julia-repl -julia> run(pipeline(`perl -le '$|=1; for(0..9){ print; sleep 1 }'`, +```jldoctest prefixer; filter = r"[A-B] [X-Z] [0-5]" +julia> run(pipeline(`perl -le '$|=1; for(0..5){ print; sleep 1 }'`, prefixer("X",3) & prefixer("Y",3) & prefixer("Z",3), - prefixer("A",2) & prefixer("B",2))) + prefixer("A",2) & prefixer("B",2))); A X 0 B Y 1 A Z 2 B X 3 A Y 4 B Z 5 -A X 6 -B Y 7 -A Z 8 -B X 9 ``` This example is similar to the previous one, except there are two stages of consumers, and the diff --git a/codex/manual/strings.md b/codex/manual/strings.md index dcfd739..5002016 100644 --- a/codex/manual/strings.md +++ b/codex/manual/strings.md @@ -78,7 +78,7 @@ is a valid code point, use the [`isvalid`](@ref) function: ```jldoctest julia> Char(0x110000) -'\U110000': Unicode U+110000 (category Cn: Other, not assigned) +'\U110000': Unicode U+110000 (category In: Invalid, too high) julia> isvalid(Char, 0x110000) false @@ -129,9 +129,6 @@ julia> Int('\x7f') julia> Int('\177') 127 - -julia> Int('\xff') -255 ``` You can do comparisons and a limited amount of arithmetic with `Char` values: @@ -275,11 +272,12 @@ julia> s[1] '∀': Unicode U+2200 (category Sm: Symbol, math) julia> s[2] -ERROR: UnicodeError: invalid character index +ERROR: StringIndexError("∀ x ∃ y", 2) [...] julia> s[3] -ERROR: UnicodeError: invalid character index +ERROR: StringIndexError("∀ x ∃ y", 3) +Stacktrace: [...] julia> s[4] @@ -297,7 +295,8 @@ julia> s[1:1] "∀" julia> s[1:2] -ERROR: UnicodeError: invalid character index +ERROR: StringIndexError("∀ x ∃ y", 2) +Stacktrace: [...] julia> s[1:4] @@ -312,7 +311,7 @@ since each character in a string must have its own index. The following is an in verbose way to iterate through the characters of `s`: ```jldoctest unicodestring -julia> for i = begindex(s):lastindex(s) +julia> for i = firstindex(s):lastindex(s) try println(s[i]) catch @@ -824,7 +823,7 @@ produce arrays of bytes. Here is an example using all three: ```jldoctest julia> b"DATA\xff\u2200" -8-element Array{UInt8,1}: +8-element Base.CodeUnits{UInt8,String}: 0x44 0x41 0x54 @@ -851,11 +850,11 @@ is encoded as two bytes in UTF-8: ```jldoctest julia> b"\xff" -1-element Array{UInt8,1}: +1-element Base.CodeUnits{UInt8,String}: 0xff julia> b"\uff" -2-element Array{UInt8,1}: +2-element Base.CodeUnits{UInt8,String}: 0xc3 0xbf ``` diff --git a/codex/manual/types.md b/codex/manual/types.md index c64215b..3260b39 100644 --- a/codex/manual/types.md +++ b/codex/manual/types.md @@ -16,10 +16,11 @@ of function arguments to be deeply integrated with the language. Method dispatch detail in [Methods](@ref), but is rooted in the type system presented here. The default behavior in Julia when types are omitted is to allow values to be of any type. Thus, -one can write many useful Julia programs without ever explicitly using types. When additional +one can write many useful Julia functions without ever explicitly using types. When additional expressiveness is needed, however, it is easy to gradually introduce explicit type annotations -into previously "untyped" code. Doing so will typically increase both the performance and robustness -of these systems, and perhaps somewhat counterintuitively, often significantly simplify them. +into previously "untyped" code. Adding annotations serves three primary purposes: to take advantage +of Julia's powerful multiple-dispatch mechanism, to improve human readability, and to catch +programmer errors. Describing Julia in the lingo of [type systems](https://en.wikipedia.org/wiki/Type_system), it is: dynamic, nominative and parametric. Generic types can be parameterized, and the hierarchical @@ -343,20 +344,16 @@ must be convertible to `Int`: ```jldoctest footype julia> Foo((), 23.5, 1) -ERROR: InexactError: convert(Int64, 23.5) +ERROR: InexactError: Int64(Int64, 23.5) Stacktrace: - [1] convert at ./float.jl:703 [inlined] - [2] Foo(::Tuple{}, ::Float64, ::Int64) at ./none:2 +[...] ``` You may find a list of field names using the `fieldnames` function. ```jldoctest footype julia> fieldnames(Foo) -3-element Array{Symbol,1}: - :bar - :baz - :qux +(:bar, :baz, :qux) ``` You can access the field values of a composite object using the traditional `foo.bar` notation: @@ -648,13 +645,11 @@ For the default constructor, exactly one argument must be supplied for each fiel ```jldoctest pointtype julia> Point{Float64}(1.0) ERROR: MethodError: Cannot `convert` an object of type Float64 to an object of type Point{Float64} -This may have arisen from a call to the constructor Point{Float64}(...), -since type constructors fall back to convert methods. -Stacktrace: - [1] Point{Float64}(::Float64) at ./sysimg.jl:114 +[...] julia> Point{Float64}(1.0,2.0,3.0) ERROR: MethodError: no method matching Point{Float64}(::Float64, ::Float64, ::Float64) +[...] ``` Only one default constructor is generated for parametric types, since overriding it is not possible. diff --git a/codex/manual/variables-and-scoping.md b/codex/manual/variables-and-scoping.md index 4fc5ba1..088aafd 100644 --- a/codex/manual/variables-and-scoping.md +++ b/codex/manual/variables-and-scoping.md @@ -251,15 +251,15 @@ which have a private state, for instance the ``state`` variable in the following example: ```jldoctest - julia> let state = 0 - global counter() = (state += 1) - end; +julia> let state = 0 + global counter() = (state += 1) + end; - julia> counter() - 1 +julia> counter() +1 - julia> counter() - 2 +julia> counter() +2 ``` See also the closures in the examples in the next two sections. diff --git a/codex/stdlib/Dates.md b/codex/stdlib/Dates.md index 2b3adef..3a434cc 100644 --- a/codex/stdlib/Dates.md +++ b/codex/stdlib/Dates.md @@ -144,14 +144,14 @@ julia> dt2 = Date(2000,2,1) julia> dump(dt) Date - instant: Dates.UTInstant{Dates.Day} - periods: Dates.Day + instant: Dates.UTInstant{Day} + periods: Day value: Int64 734562 julia> dump(dt2) Date - instant: Dates.UTInstant{Dates.Day} - periods: Dates.Day + instant: Dates.UTInstant{Day} + periods: Day value: Int64 730151 julia> dt > dt2 @@ -170,7 +170,6 @@ ERROR: MethodError: no method matching *(::Date, ::Date) julia> dt / dt2 ERROR: MethodError: no method matching /(::Date, ::Date) -[...] julia> dt - dt2 4411 days @@ -240,12 +239,12 @@ One may also access the underlying `UTInstant` or integer value: ```jldoctest tdate julia> dump(t) Date - instant: Dates.UTInstant{Dates.Day} - periods: Dates.Day + instant: Dates.UTInstant{Day} + periods: Day value: Int64 735264 julia> t.instant -Dates.UTInstant{Dates.Day}(735264 days) +Dates.UTInstant{Day}(735264 days) julia> Dates.value(t) 735264 @@ -559,7 +558,7 @@ julia> round(DateTime(2016, 8, 6, 20, 15), Dates.Day) Unlike the numeric [`round`](@ref) method, which breaks ties toward the even number by default, the [`TimeType`](@ref)[`round`](@ref) method uses the `RoundNearestTiesUp` rounding mode. (It's difficult to guess what breaking ties to nearest "even" [`TimeType`](@ref) would entail.) Further -details on the available `RoundingMode` s can be found in the [API reference](@ref stdlib-dates). +details on the available `RoundingMode` s can be found in the [API reference](@ref stdlib-dates-api). Rounding should generally behave as expected, but there are a few cases in which the expected behaviour is not obvious. diff --git a/codex/stdlib/IterativeEigensolvers.md b/codex/stdlib/IterativeEigensolvers.md index 62dadc7..185d2dc 100644 --- a/codex/stdlib/IterativeEigensolvers.md +++ b/codex/stdlib/IterativeEigensolvers.md @@ -1,7 +1,7 @@ # [Iterative Eigensolvers](@id lib-itereigen) ```@meta -DocTestSetup = :(using IterativeEigensolvers) +DocTestSetup = :(using IterativeEigensolvers, LinearAlgebra, SparseArrays) ``` Julia provides bindings to [ARPACK](http://www.caam.rice.edu/software/ARPACK/), which @@ -53,9 +53,7 @@ the following keyword arguments are supported: * `v0`: starting vector from which to start the iterations We can see the various keywords in action in the following examples: -```jldoctest -julia> using IterativeEigensolvers - +```jldoctest; filter = r"(1|2)-element Array{(Float64|Complex{Float64}),1}:\n (.|\s)*$" julia> A = Diagonal(1:4); julia> λ, ϕ = eigs(A, nev = 2, which=:SM); @@ -65,42 +63,37 @@ julia> λ 1.0000000000000002 2.0 -julia> B = Diagonal([1., 2., -3im, 4im]) -4×4 Diagonal{Complex{Float64},Array{Complex{Float64},1}}: - 1.0+0.0im ⋅ ⋅ ⋅ - ⋅ 2.0+0.0im ⋅ ⋅ - ⋅ ⋅ 0.0-3.0im ⋅ - ⋅ ⋅ ⋅ 0.0+4.0im +julia> B = Diagonal([1., 2., -3im, 4im]); julia> λ, ϕ = eigs(B, nev=1, which=:LI); julia> λ 1-element Array{Complex{Float64},1}: - -4.440892098500626e-16 + 3.999999999999998im + 1.3322676295501878e-15 + 4.0im julia> λ, ϕ = eigs(B, nev=1, which=:SI); julia> λ 1-element Array{Complex{Float64},1}: - 1.3877787807814457e-16 - 2.999999999999999im + -2.498001805406602e-16 - 3.0000000000000018im julia> λ, ϕ = eigs(B, nev=1, which=:LR); julia> λ 1-element Array{Complex{Float64},1}: - 2.0 + 4.242754940683747e-17im + 2.0000000000000004 + 4.0615212488780827e-17im julia> λ, ϕ = eigs(B, nev=1, which=:SR); julia> λ 1-element Array{Complex{Float64},1}: - 4.440892098500626e-16 + 4.0000000000000036im + -8.881784197001252e-16 + 3.999999999999997im julia> λ, ϕ = eigs(B, nev=1, sigma=1.5); julia> λ 1-element Array{Complex{Float64},1}: - 1.9999999999999996 + 2.4290457684137336e-17im + 1.0000000000000004 + 4.0417078924070745e-18im ``` !!! note @@ -168,31 +161,29 @@ iterations `niter` and the number of matrix vector multiplications `nmult`, as w final residual vector `resid`. We can see the various keywords in action in the following examples: -```jldoctest -julia> using IterativeEigensolvers - +```jldoctest; filter = r"(1|2)-element Array{(Float64|Complex{Float64}),1}:\n (.|\s)*$" julia> A = sparse(1.0I, 4, 4); B = Diagonal(1:4); julia> λ, ϕ = eigs(A, B, nev = 2); julia> λ 2-element Array{Float64,1}: - 1.0 - 0.4999999999999999 + 1.0000000000000002 + 0.5 -julia> A = sparse(1.0I, 4, 4); B = Diagonal([1, -2im, 3, 4im]); +julia> A = Diagonal([1, -2im, 3, 4im]); B = sparse(1.0I, 4, 4); julia> λ, ϕ = eigs(A, B, nev=1, which=:SI); julia> λ 1-element Array{Complex{Float64},1}: - 0.03291282838780993 - 2.0627621271174514im + -1.5720931501039814e-16 - 1.9999999999999984im julia> λ, ϕ = eigs(A, B, nev=1, which=:LI); julia> λ 1-element Array{Complex{Float64},1}: - -0.6428551411711136 + 2.1820633510068994im + 0.0 + 4.000000000000002im ``` !!! note diff --git a/codex/stdlib/LinearAlgebra.md b/codex/stdlib/LinearAlgebra.md index d931b8c..e46e75e 100644 --- a/codex/stdlib/LinearAlgebra.md +++ b/codex/stdlib/LinearAlgebra.md @@ -60,9 +60,17 @@ julia> A = [1.5 2 -4; 3 -1 -6; -10 2.3 4] -10.0 2.3 4.0 julia> factorize(A) -LinearAlgebra.LU{Float64,Array{Float64,2}} with factors L and U: -[1.0 0.0 0.0; -0.15 1.0 0.0; -0.3 -0.132196 1.0] -[-10.0 2.3 4.0; 0.0 2.345 -3.4; 0.0 0.0 -5.24947] +LU{Float64,Array{Float64,2}} +L factor: +3×3 Array{Float64,2}: + 1.0 0.0 0.0 + -0.15 1.0 0.0 + -0.3 -0.132196 1.0 +U factor: +3×3 Array{Float64,2}: + -10.0 2.3 4.0 + 0.0 2.345 -3.4 + 0.0 0.0 -5.24947 ``` Since `A` is not Hermitian, symmetric, triangular, tridiagonal, or bidiagonal, an LU factorization may be the @@ -76,17 +84,17 @@ julia> B = [1.5 2 -4; 2 -1 -3; -4 -3 5] -4.0 -3.0 5.0 julia> factorize(B) -LinearAlgebra.BunchKaufman{Float64,Array{Float64,2}} +BunchKaufman{Float64,Array{Float64,2}} D factor: 3×3 Tridiagonal{Float64,Array{Float64,1}}: -1.64286 0.0 ⋅ 0.0 -2.8 0.0 ⋅ 0.0 5.0 U factor: -3×3 LinearAlgebra.UnitUpperTriangular{Float64,Array{Float64,2}}: +3×3 UnitUpperTriangular{Float64,Array{Float64,2}}: 1.0 0.142857 -0.8 - 0.0 1.0 -0.6 - 0.0 0.0 1.0 + ⋅ 1.0 -0.6 + ⋅ ⋅ 1.0 permutation: 3-element Array{Int64,1}: 1 @@ -252,9 +260,7 @@ julia> b = [1 2 3; 4 5 6] julia> b - U ERROR: DimensionMismatch("matrix is not square: dimensions are (2, 3)") Stacktrace: - [1] checksquare at ./linalg/linalg.jl:220 [inlined] - [2] -(::Array{Int64,2}, ::UniformScaling{Int64}) at ./linalg/uniformscaling.jl:156 - [3] top-level scope +[...] ``` ## [Matrix factorizations](@id man-linalg-factorizations) @@ -416,7 +422,7 @@ Base.transpose LinearAlgebra.transpose! Base.adjoint LinearAlgebra.adjoint! -LinearAlgebra.peakflops +Base.copy(::Union{Transpose,Adjoint}) LinearAlgebra.stride1 LinearAlgebra.checksquare ``` diff --git a/codex/stdlib/Sockets.md b/codex/stdlib/Sockets.md index d457da9..7f4d72b 100644 --- a/codex/stdlib/Sockets.md +++ b/codex/stdlib/Sockets.md @@ -1,4 +1,8 @@ -## Sockets +# Sockets + +```@meta +DocTestSetup = :(using Sockets) +``` ```@docs Sockets.connect(::TCPSocket, ::Integer) @@ -23,3 +27,7 @@ Sockets.recv Sockets.recvfrom Sockets.setopt ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/codex/stdlib/SparseArrays.md b/codex/stdlib/SparseArrays.md index 34dd58c..afde15c 100644 --- a/codex/stdlib/SparseArrays.md +++ b/codex/stdlib/SparseArrays.md @@ -1,7 +1,7 @@ # Sparse Arrays ```@meta -DocTestSetup = :(using SparseArrays) +DocTestSetup = :(using SparseArrays, LinearAlgebra) ``` Julia has support for sparse vectors and [sparse matrices](https://en.wikipedia.org/wiki/Sparse_matrix) diff --git a/codex/stdlib/UUIDs.md b/codex/stdlib/UUIDs.md index ddc490f..3b936e7 100644 --- a/codex/stdlib/UUIDs.md +++ b/codex/stdlib/UUIDs.md @@ -1,7 +1,7 @@ # UUIDs ```@meta -DocTestSetup = :(using UUIDs) +DocTestSetup = :(using UUIDs, Random) ``` ```@docs diff --git a/codex/stdlib/dates.md b/codex/stdlib/dates.md index 2b3adef..3a434cc 100644 --- a/codex/stdlib/dates.md +++ b/codex/stdlib/dates.md @@ -144,14 +144,14 @@ julia> dt2 = Date(2000,2,1) julia> dump(dt) Date - instant: Dates.UTInstant{Dates.Day} - periods: Dates.Day + instant: Dates.UTInstant{Day} + periods: Day value: Int64 734562 julia> dump(dt2) Date - instant: Dates.UTInstant{Dates.Day} - periods: Dates.Day + instant: Dates.UTInstant{Day} + periods: Day value: Int64 730151 julia> dt > dt2 @@ -170,7 +170,6 @@ ERROR: MethodError: no method matching *(::Date, ::Date) julia> dt / dt2 ERROR: MethodError: no method matching /(::Date, ::Date) -[...] julia> dt - dt2 4411 days @@ -240,12 +239,12 @@ One may also access the underlying `UTInstant` or integer value: ```jldoctest tdate julia> dump(t) Date - instant: Dates.UTInstant{Dates.Day} - periods: Dates.Day + instant: Dates.UTInstant{Day} + periods: Day value: Int64 735264 julia> t.instant -Dates.UTInstant{Dates.Day}(735264 days) +Dates.UTInstant{Day}(735264 days) julia> Dates.value(t) 735264 @@ -559,7 +558,7 @@ julia> round(DateTime(2016, 8, 6, 20, 15), Dates.Day) Unlike the numeric [`round`](@ref) method, which breaks ties toward the even number by default, the [`TimeType`](@ref)[`round`](@ref) method uses the `RoundNearestTiesUp` rounding mode. (It's difficult to guess what breaking ties to nearest "even" [`TimeType`](@ref) would entail.) Further -details on the available `RoundingMode` s can be found in the [API reference](@ref stdlib-dates). +details on the available `RoundingMode` s can be found in the [API reference](@ref stdlib-dates-api). Rounding should generally behave as expected, but there are a few cases in which the expected behaviour is not obvious. diff --git a/codex/stdlib/iterativeeigensolvers.md b/codex/stdlib/iterativeeigensolvers.md index 62dadc7..185d2dc 100644 --- a/codex/stdlib/iterativeeigensolvers.md +++ b/codex/stdlib/iterativeeigensolvers.md @@ -1,7 +1,7 @@ # [Iterative Eigensolvers](@id lib-itereigen) ```@meta -DocTestSetup = :(using IterativeEigensolvers) +DocTestSetup = :(using IterativeEigensolvers, LinearAlgebra, SparseArrays) ``` Julia provides bindings to [ARPACK](http://www.caam.rice.edu/software/ARPACK/), which @@ -53,9 +53,7 @@ the following keyword arguments are supported: * `v0`: starting vector from which to start the iterations We can see the various keywords in action in the following examples: -```jldoctest -julia> using IterativeEigensolvers - +```jldoctest; filter = r"(1|2)-element Array{(Float64|Complex{Float64}),1}:\n (.|\s)*$" julia> A = Diagonal(1:4); julia> λ, ϕ = eigs(A, nev = 2, which=:SM); @@ -65,42 +63,37 @@ julia> λ 1.0000000000000002 2.0 -julia> B = Diagonal([1., 2., -3im, 4im]) -4×4 Diagonal{Complex{Float64},Array{Complex{Float64},1}}: - 1.0+0.0im ⋅ ⋅ ⋅ - ⋅ 2.0+0.0im ⋅ ⋅ - ⋅ ⋅ 0.0-3.0im ⋅ - ⋅ ⋅ ⋅ 0.0+4.0im +julia> B = Diagonal([1., 2., -3im, 4im]); julia> λ, ϕ = eigs(B, nev=1, which=:LI); julia> λ 1-element Array{Complex{Float64},1}: - -4.440892098500626e-16 + 3.999999999999998im + 1.3322676295501878e-15 + 4.0im julia> λ, ϕ = eigs(B, nev=1, which=:SI); julia> λ 1-element Array{Complex{Float64},1}: - 1.3877787807814457e-16 - 2.999999999999999im + -2.498001805406602e-16 - 3.0000000000000018im julia> λ, ϕ = eigs(B, nev=1, which=:LR); julia> λ 1-element Array{Complex{Float64},1}: - 2.0 + 4.242754940683747e-17im + 2.0000000000000004 + 4.0615212488780827e-17im julia> λ, ϕ = eigs(B, nev=1, which=:SR); julia> λ 1-element Array{Complex{Float64},1}: - 4.440892098500626e-16 + 4.0000000000000036im + -8.881784197001252e-16 + 3.999999999999997im julia> λ, ϕ = eigs(B, nev=1, sigma=1.5); julia> λ 1-element Array{Complex{Float64},1}: - 1.9999999999999996 + 2.4290457684137336e-17im + 1.0000000000000004 + 4.0417078924070745e-18im ``` !!! note @@ -168,31 +161,29 @@ iterations `niter` and the number of matrix vector multiplications `nmult`, as w final residual vector `resid`. We can see the various keywords in action in the following examples: -```jldoctest -julia> using IterativeEigensolvers - +```jldoctest; filter = r"(1|2)-element Array{(Float64|Complex{Float64}),1}:\n (.|\s)*$" julia> A = sparse(1.0I, 4, 4); B = Diagonal(1:4); julia> λ, ϕ = eigs(A, B, nev = 2); julia> λ 2-element Array{Float64,1}: - 1.0 - 0.4999999999999999 + 1.0000000000000002 + 0.5 -julia> A = sparse(1.0I, 4, 4); B = Diagonal([1, -2im, 3, 4im]); +julia> A = Diagonal([1, -2im, 3, 4im]); B = sparse(1.0I, 4, 4); julia> λ, ϕ = eigs(A, B, nev=1, which=:SI); julia> λ 1-element Array{Complex{Float64},1}: - 0.03291282838780993 - 2.0627621271174514im + -1.5720931501039814e-16 - 1.9999999999999984im julia> λ, ϕ = eigs(A, B, nev=1, which=:LI); julia> λ 1-element Array{Complex{Float64},1}: - -0.6428551411711136 + 2.1820633510068994im + 0.0 + 4.000000000000002im ``` !!! note diff --git a/codex/stdlib/linearalgebra.md b/codex/stdlib/linearalgebra.md index d931b8c..e46e75e 100644 --- a/codex/stdlib/linearalgebra.md +++ b/codex/stdlib/linearalgebra.md @@ -60,9 +60,17 @@ julia> A = [1.5 2 -4; 3 -1 -6; -10 2.3 4] -10.0 2.3 4.0 julia> factorize(A) -LinearAlgebra.LU{Float64,Array{Float64,2}} with factors L and U: -[1.0 0.0 0.0; -0.15 1.0 0.0; -0.3 -0.132196 1.0] -[-10.0 2.3 4.0; 0.0 2.345 -3.4; 0.0 0.0 -5.24947] +LU{Float64,Array{Float64,2}} +L factor: +3×3 Array{Float64,2}: + 1.0 0.0 0.0 + -0.15 1.0 0.0 + -0.3 -0.132196 1.0 +U factor: +3×3 Array{Float64,2}: + -10.0 2.3 4.0 + 0.0 2.345 -3.4 + 0.0 0.0 -5.24947 ``` Since `A` is not Hermitian, symmetric, triangular, tridiagonal, or bidiagonal, an LU factorization may be the @@ -76,17 +84,17 @@ julia> B = [1.5 2 -4; 2 -1 -3; -4 -3 5] -4.0 -3.0 5.0 julia> factorize(B) -LinearAlgebra.BunchKaufman{Float64,Array{Float64,2}} +BunchKaufman{Float64,Array{Float64,2}} D factor: 3×3 Tridiagonal{Float64,Array{Float64,1}}: -1.64286 0.0 ⋅ 0.0 -2.8 0.0 ⋅ 0.0 5.0 U factor: -3×3 LinearAlgebra.UnitUpperTriangular{Float64,Array{Float64,2}}: +3×3 UnitUpperTriangular{Float64,Array{Float64,2}}: 1.0 0.142857 -0.8 - 0.0 1.0 -0.6 - 0.0 0.0 1.0 + ⋅ 1.0 -0.6 + ⋅ ⋅ 1.0 permutation: 3-element Array{Int64,1}: 1 @@ -252,9 +260,7 @@ julia> b = [1 2 3; 4 5 6] julia> b - U ERROR: DimensionMismatch("matrix is not square: dimensions are (2, 3)") Stacktrace: - [1] checksquare at ./linalg/linalg.jl:220 [inlined] - [2] -(::Array{Int64,2}, ::UniformScaling{Int64}) at ./linalg/uniformscaling.jl:156 - [3] top-level scope +[...] ``` ## [Matrix factorizations](@id man-linalg-factorizations) @@ -416,7 +422,7 @@ Base.transpose LinearAlgebra.transpose! Base.adjoint LinearAlgebra.adjoint! -LinearAlgebra.peakflops +Base.copy(::Union{Transpose,Adjoint}) LinearAlgebra.stride1 LinearAlgebra.checksquare ``` diff --git a/codex/stdlib/sparsearrays.md b/codex/stdlib/sparsearrays.md index 34dd58c..afde15c 100644 --- a/codex/stdlib/sparsearrays.md +++ b/codex/stdlib/sparsearrays.md @@ -1,7 +1,7 @@ # Sparse Arrays ```@meta -DocTestSetup = :(using SparseArrays) +DocTestSetup = :(using SparseArrays, LinearAlgebra) ``` Julia has support for sparse vectors and [sparse matrices](https://en.wikipedia.org/wiki/Sparse_matrix) diff --git a/src/NEWS.md b/src/NEWS.md index 1dd861e..80e9552 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -575,6 +575,9 @@ Library improvements collection `A`. There are also two other methods with a different API, and a mutating variant, `replace!` ([#22324](https://github.com/JuliaLang/julia/issues/22324)). + * Adding integers to `CartesianIndex` objects is now deprecated. Instead of + `i::Int + x::CartesianIndex`, use `i*one(x) + x` ([#26284](https://github.com/JuliaLang/julia/issues/26284)). + * `CartesianRange` changes ([#24715](https://github.com/JuliaLang/julia/issues/24715)): - Inherits from `AbstractArray`, and linear indexing can be used to provide linear-to-cartesian conversion ([#24715](https://github.com/JuliaLang/julia/issues/24715)) diff --git a/src/base/arrays.md b/src/base/arrays.md index 402ebab..11b3c6d 100644 --- a/src/base/arrays.md +++ b/src/base/arrays.md @@ -138,7 +138,7 @@ Base.promote_shape ## Array functions ```@docs -Base.accumulate(::Any, ::Any, ::Integer) +Base.accumulate Base.accumulate! Base.cumprod Base.cumprod! @@ -149,8 +149,6 @@ Base.repeat Base.rot180 Base.rotl90 Base.rotr90 -Base.reducedim -Base.mapreducedim Base.mapslices ``` diff --git a/src/base/collections.md b/src/base/collections.md index 43ba36a..cdc77c2 100644 --- a/src/base/collections.md +++ b/src/base/collections.md @@ -88,20 +88,16 @@ Base.foldl(::Any, ::Any, ::Any) Base.foldl(::Any, ::Any) Base.foldr(::Any, ::Any, ::Any) Base.foldr(::Any, ::Any) -Base.maximum(::Any) -Base.maximum(::Any, ::Any) +Base.maximum Base.maximum! -Base.minimum(::Any) -Base.minimum(::Any, ::Any) +Base.minimum Base.minimum! Base.extrema(::Any) Base.extrema(::AbstractArray, ::Any) Base.argmax Base.argmin -Base.findmax(::Any) -Base.findmax(::AbstractArray, ::Any) -Base.findmin(::Any) -Base.findmin(::AbstractArray, ::Any) +Base.findmax +Base.findmin Base.findmax! Base.findmin! Base.sum diff --git a/src/base/io-network.md b/src/base/io-network.md index c99684c..9c0cf81 100644 --- a/src/base/io-network.md +++ b/src/base/io-network.md @@ -94,7 +94,7 @@ Base.Multimedia.redisplay Base.Multimedia.displayable Base.show(::Any, ::Any, ::Any) Base.Multimedia.showable -Base.repr(::Any, ::Any) +Base.repr(::MIME, ::Any) ``` As mentioned above, one can also define new display backends. For example, a module that can display diff --git a/src/devdocs/reflection.md b/src/devdocs/reflection.md index d664ef0..23ff13b 100644 --- a/src/devdocs/reflection.md +++ b/src/devdocs/reflection.md @@ -11,7 +11,7 @@ returns symbols for all bindings in `m`, regardless of export status. ## DataType fields The names of `DataType` fields may be interrogated using [`fieldnames`](@ref). For example, -given the following type, `fieldnames(Point)` returns an arrays of [`Symbol`](@ref) elements representing +given the following type, `fieldnames(Point)` returns a tuple of [`Symbol`](@ref)s representing the field names: ```jldoctest struct_point @@ -21,9 +21,7 @@ julia> struct Point end julia> fieldnames(Point) -2-element Array{Symbol,1}: - :x - :y +(:x, :y) ``` The type of each field in a `Point` object is stored in the `types` field of the `Point` variable @@ -52,9 +50,9 @@ of these fields is the `types` field observed in the example above. The *direct* subtypes of any `DataType` may be listed using [`subtypes`](@ref). For example, the abstract `DataType` [`AbstractFloat`](@ref) has four (concrete) subtypes: -```jldoctest +```jldoctest; setup = :(using InteractiveUtils) julia> subtypes(AbstractFloat) -4-element Array{Union{DataType, UnionAll},1}: +4-element Array{Any,1}: BigFloat Float16 Float32 @@ -83,9 +81,9 @@ the unquoted and interpolated expression (`Expr`) form for a given macro. To use `quote` the expression block itself (otherwise, the macro will be evaluated and the result will be passed instead!). For example: -```jldoctest +```jldoctest; setup = :(using InteractiveUtils) julia> macroexpand(@__MODULE__, :(@edit println("")) ) -:((Base.edit)(println, (Base.typesof)(""))) +:((InteractiveUtils.edit)(println, (Base.typesof)(""))) ``` The functions `Base.Meta.show_sexpr` and [`dump`](@ref) are used to display S-expr style views @@ -97,14 +95,18 @@ and variable assignments: ```jldoctest julia> Meta.lower(@__MODULE__, :(f() = 1) ) -:(begin - $(Expr(:method, :f)) - $(Expr(:method, :f, :((Core.svec)((Core.svec)((Core.Typeof)(f)), (Core.svec)())), CodeInfo(:(begin - #= none:1 =# - return 1 - end)), false)) - return f - end) +:($(Expr(:thunk, CodeInfo(:(begin + $(Expr(:method, :f)) + Core.SSAValue(0) = (Core.Typeof)(f) + Core.SSAValue(1) = (Core.svec)(Core.SSAValue(0)) + Core.SSAValue(2) = (Core.svec)() + Core.SSAValue(3) = (Core.svec)(Core.SSAValue(1), Core.SSAValue(2)) + $(Expr(:method, :f, Core.SSAValue(3), CodeInfo(:(begin + #= none:1 =# + return 1 + end)))) + return f + end))))) ``` ## Intermediate and compiled representations diff --git a/src/index.md b/src/index.md index ab3aa22..f08c212 100644 --- a/src/index.md +++ b/src/index.md @@ -81,7 +81,7 @@ * [Base64](@ref) * [CRC32c](@ref) * [SHA](@ref) - * [Dates](@ref stdlib-dates) + * [Dates](@ref) * [Delimited Files](@ref) * [Distributed Computing](@ref) * [File Events](@ref lib-filewatching) @@ -116,7 +116,7 @@ * [printf() and stdio in the Julia runtime](@ref) * [Bounds checking](@ref) * [Proper maintenance and care of multi-threading locks](@ref) - * [Arrays with custom indices](@ref) + * [Arrays with custom indices](@ref man-custom-indices) * [Module loading](@ref) * [Inference](@ref) * Developing/debugging Julia's C code diff --git a/src/manual/arrays.md b/src/manual/arrays.md index cdd961d..b1e968a 100644 --- a/src/manual/arrays.md +++ b/src/manual/arrays.md @@ -609,8 +609,8 @@ julia> broadcast(+, a, b) ```jldoctest julia> convert.(Float32, [1, 2]) 2-element Array{Float32,1}: - 1.0f0 - 2.0f0 + 1.0 + 2.0 julia> ceil.((UInt8,), [1.2 3.4; 5.6 6.7]) 2×2 Array{UInt8,2}: diff --git a/src/manual/complex-and-rational-numbers.md b/src/manual/complex-and-rational-numbers.md index ebb7a06..9f49aa0 100644 --- a/src/manual/complex-and-rational-numbers.md +++ b/src/manual/complex-and-rational-numbers.md @@ -37,7 +37,7 @@ julia> (-1 + 2im)^2 -3 - 4im julia> (-1 + 2im)^2.5 -2.7296244647840084 - 6.960664459571898im +2.729624464784009 - 6.9606644595719im julia> (-1 + 2im)^(1 + 1im) -0.27910381075826657 + 0.08708053414102428im diff --git a/src/manual/constructors.md b/src/manual/constructors.md index 153d6e3..8ee79ea 100644 --- a/src/manual/constructors.md +++ b/src/manual/constructors.md @@ -97,14 +97,16 @@ julia> struct OrderedPair Now `OrderedPair` objects can only be constructed such that `x <= y`: -```jldoctest pairtype +```jldoctest pairtype; filter = r"Stacktrace:(\n \[[0-9]+\].*)*" julia> OrderedPair(1, 2) OrderedPair(1, 2) julia> OrderedPair(2,1) ERROR: out of order Stacktrace: - [1] OrderedPair(::Int64, ::Int64) at ./none:4 + [1] error at ./error.jl:33 [inlined] + [2] OrderedPair(::Int64, ::Int64) at ./none:4 + [3] top-level scope ``` If the type were declared `mutable`, you could reach in and directly change the field values to @@ -277,7 +279,7 @@ that, by default, instances of parametric composite types can be constructed eit given type parameters or with type parameters implied by the types of the arguments given to the constructor. Here are some examples: -```jldoctest parametric +```jldoctest parametric; filter = r"Closest candidates.*\n .*" julia> struct Point{T<:Real} x::T y::T @@ -292,16 +294,15 @@ Point{Float64}(1.0, 2.5) julia> Point(1,2.5) ## implicit T ## ERROR: MethodError: no method matching Point(::Int64, ::Float64) Closest candidates are: - Point(::T<:Real, !Matched::T<:Real) where T<:Real at none:2 + Point(::T<:Real, ::T<:Real) where T<:Real at none:2 julia> Point{Int64}(1, 2) ## explicit T ## Point{Int64}(1, 2) julia> Point{Int64}(1.0,2.5) ## explicit T ## -ERROR: InexactError: convert(Int64, 2.5) +ERROR: InexactError: Int64(Int64, 2.5) Stacktrace: - [1] convert at ./float.jl:703 [inlined] - [2] Point{Int64}(::Float64, ::Float64) at ./none:2 +[...] julia> Point{Float64}(1.0, 2.5) ## explicit T ## Point{Float64}(1.0, 2.5) @@ -502,7 +503,7 @@ julia> typeof(z) <: Complex{OurRational} false ``` -Thus, although the [`⊘`](@ref) operator usually returns an instance of `OurRational`, if either +Thus, although the `⊘` operator usually returns an instance of `OurRational`, if either of its arguments are complex integers, it will return an instance of `Complex{OurRational}` instead. The interested reader should consider perusing the rest of [`rational.jl`](https://github.com/JuliaLang/julia/blob/master/base/rational.jl): it is short, self-contained, and implements an entire basic Julia type. diff --git a/src/manual/control-flow.md b/src/manual/control-flow.md index e7c929d..c80cc6c 100644 --- a/src/manual/control-flow.md +++ b/src/manual/control-flow.md @@ -85,7 +85,7 @@ x is equal to y `if` 블록은 지역 범위를 만들지 않기 때문에 한 마디로 "구멍이 났다"고 할 수 있습니다. 이는 `if` 절 안에서 정의된 새로운 변수가 `if` 블록 다음에도 사용될 수 있음을 의미합니다. 따라서, 위에서 정의한 `test` 함수를 다음과 같이 정의할 수도 있습니다. -```jldoctest +```jldoctest; filter = r"Stacktrace:(\n \[[0-9]+\].*)*" julia> function test(x,y) if x < y relation = "less than" @@ -266,7 +266,7 @@ false 예제로 재귀적 팩토리얼 함수를 다음과 같이 선언할 수 있습니다. -```jldoctest +```jldoctest; filter = r"Stacktrace:(\n \[[0-9]+\].*)*" julia> function fact(n::Int) n >= 0 || error("n must be non-negative") n == 0 && return 1 @@ -283,7 +283,9 @@ julia> fact(0) julia> fact(-1) ERROR: n must be non-negative Stacktrace: - [1] fact(::Int64) at ./none:2 + [1] error at ./error.jl:33 [inlined] + [2] fact(::Int64) at ./none:2 + [3] top-level scope ``` Mathematical Operations and Elementary Functions: `&` 및 `|`에서 소개한 비트 논리 연산자로 단락 평가가 없는 논리 연산을 할 수 있습니다. 그것들은 이항연산자 구문을 지원하지만, 항상 인수를 평가하는 일반적인 함수라고 할 수 있습니다. @@ -506,7 +508,7 @@ julia> struct MyCustomException <: Exception end 예외는 `throw`를 사용하여 명시적으로 만들 수 있습니다. 예를 들어, 인수가 음수이면 인수가 음수가 아닌 숫자로만 정의된 함수를 작성하여 `DomainError`를 `throw`할 수 있습니다. -```jldoctest +```jldoctest; filter = r"Stacktrace:(\n \[[0-9]+\].*)*" julia> f(x) = x>=0 ? exp(-x) : throw(DomainError(x, "argument must be nonnegative")) f (generic function with 1 method) @@ -563,7 +565,7 @@ julia> Base.showerror(io::IO, e::MyUndefVarError) = print(io, e.var, " not defin 음수의 제곱근을 취하면 즉시 실행을 멈추고 싶다고 합시다. 이것을 하기 위해 인수가 음수이면 오류가 발생하는 `sqrt` 함수의 까다로운 버전을 정의할 수 있습니다. -```jldoctest fussy_sqrt +```jldoctest fussy_sqrt; filter = r"Stacktrace:(\n \[[0-9]+\].*)*" julia> fussy_sqrt(x) = x >= 0 ? sqrt(x) : error("negative x not allowed") fussy_sqrt (generic function with 1 method) @@ -573,12 +575,14 @@ julia> fussy_sqrt(2) julia> fussy_sqrt(-1) ERROR: negative x not allowed Stacktrace: - [1] fussy_sqrt(::Int64) at ./none:1 + [1] error at ./error.jl:33 [inlined] + [2] fussy_sqrt(::Int64) at ./none:1 + [3] top-level scope ``` `fussy_sqrt`가 호출 함수의 실행을 계속하려 하는 것이 아니라 다른 함수에서 음수 값으로 호출되면, 즉시 반환되어 대화식 세션에 오류 메시지를 표시합니다. -```jldoctest fussy_sqrt +```jldoctest fussy_sqrt; filter = r"Stacktrace:(\n \[[0-9]+\].*)*" julia> function verbose_fussy_sqrt(x) println("before fussy_sqrt") r = fussy_sqrt(x) @@ -596,8 +600,10 @@ julia> verbose_fussy_sqrt(-1) before fussy_sqrt ERROR: negative x not allowed Stacktrace: - [1] fussy_sqrt at ./none:1 [inlined] - [2] verbose_fussy_sqrt(::Int64) at ./none:3 + [1] error at ./error.jl:33 [inlined] + [2] fussy_sqrt at ./none:1 [inlined] + [3] verbose_fussy_sqrt(::Int64) at ./none:3 + [4] top-level scope ``` ### `try/catch`문 diff --git a/src/manual/conversion-and-promotion.md b/src/manual/conversion-and-promotion.md index b824c97..7345334 100644 --- a/src/manual/conversion-and-promotion.md +++ b/src/manual/conversion-and-promotion.md @@ -88,7 +88,8 @@ doesn't know how to perform the requested conversion: ```jldoctest julia> convert(AbstractFloat, "foo") -ERROR: MethodError: Cannot `convert` an object of type String to an object of type AbstractFloat. +ERROR: MethodError: Cannot `convert` an object of type String to an object of type AbstractFloat +[...] ``` Some languages consider parsing strings as numbers or formatting numbers as strings to be conversions diff --git a/src/manual/embedding.md b/src/manual/embedding.md index 54cabeb..496d0f1 100644 --- a/src/manual/embedding.md +++ b/src/manual/embedding.md @@ -44,7 +44,7 @@ gcc -o test -fPIC -I$JULIA_DIR/include/julia -L$JULIA_DIR/lib test.c -ljulia $JU Then if the environment variable `JULIA_BINDIR` is set to `$JULIA_DIR/bin`, the output `test` program can be executed. -Alternatively, look at the `embedding.c` program in the Julia source tree in the `examples/` folder. +Alternatively, look at the `embedding.c` program in the Julia source tree in the `test/embedding/` folder. The file `ui/repl.c` program is another simple example of how to set `jl_options` options while linking against `libjulia`. diff --git a/src/manual/faq.md b/src/manual/faq.md index fe8ca94..da68118 100644 --- a/src/manual/faq.md +++ b/src/manual/faq.md @@ -147,18 +147,18 @@ argument is called slurping: ```jldoctest julia> function printargs(args...) - @printf("%s\n", typeof(args)) + println(typeof(args)) for (i, arg) in enumerate(args) - @printf("Arg %d = %s\n", i, arg) + println("Arg #$i = $arg") end end printargs (generic function with 1 method) julia> printargs(1, 2, 3) Tuple{Int64,Int64,Int64} -Arg 1 = 1 -Arg 2 = 2 -Arg 3 = 3 +Arg #1 = 1 +Arg #2 = 2 +Arg #3 = 3 ``` If Julia were a language that made more liberal use of ASCII characters, the slurping operator @@ -173,19 +173,19 @@ call. This use of `...` is called splatting: ```jldoctest julia> function threeargs(a, b, c) - @printf("a = %s::%s\n", a, typeof(a)) - @printf("b = %s::%s\n", b, typeof(b)) - @printf("c = %s::%s\n", c, typeof(c)) + println("a = $a::$(typeof(a))") + println("b = $b::$(typeof(b))") + println("c = $c::$(typeof(c))") end threeargs (generic function with 1 method) -julia> vec = [1, 2, 3] +julia> x = [1, 2, 3] 3-element Array{Int64,1}: 1 2 3 -julia> threeargs(vec...) +julia> threeargs(x...) a = 1::Int64 b = 2::Int64 c = 3::Int64 diff --git a/src/manual/functions.md b/src/manual/functions.md index db16602..5779954 100644 --- a/src/manual/functions.md +++ b/src/manual/functions.md @@ -129,9 +129,12 @@ A return type can also be specified in the function declaration using the `::` o the return value to the specified type. ```jldoctest -function g(x,y)::Int8 - return x * y -end +julia> function g(x, y)::Int8 + return x * y + end; + +julia> typeof(g(1, 2)) +Int8 ``` This function will always return an `Int8` regardless of the types of `x` and `y`. diff --git a/src/manual/index.md b/src/manual/index.md index 5d776d5..148d5e0 100644 --- a/src/manual/index.md +++ b/src/manual/index.md @@ -22,7 +22,7 @@ * [Missing Values](@ref missing) * [Networking and Streams](@ref) * [Parallel Computing](@ref) - * [Date and DateTime](@ref) + * [Dates](@ref) * [Running External Programs](@ref) * [Calling C and Fortran Code](@ref) * [Handling Operating System Variation](@ref) diff --git a/src/manual/interfaces.md b/src/manual/interfaces.md index 236641c..2349da9 100644 --- a/src/manual/interfaces.md +++ b/src/manual/interfaces.md @@ -39,7 +39,7 @@ tests if there are any elements remaining, and `next(iter, state)`, which return the current element and an updated `state`. The `state` object can be anything, and is generally considered to be an implementation detail private to the iterable object. -Any object defines these three methods is iterable and can be used in the [many functions that rely upon iteration](@ref lib-collections-iteration). +Any object that defines these three methods is iterable and can be used in the [many functions that rely upon iteration](@ref lib-collections-iteration). It can also be used directly in a `for` loop since the syntax: ```julia @@ -189,6 +189,7 @@ valid index. It is recommended to also define [`firstindex`](@ref) to specify th ```jldoctest squaretype julia> Base.firstindex(S::Squares) = 1 + julia> Base.lastindex(S::Squares) = length(S) julia> Squares(23)[end] @@ -400,7 +401,8 @@ julia> mean(A) 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`](@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). +perhaps range-types `Ind` of your own design. For more information, see +[Arrays with custom indices](@ref man-custom-indices). ## [Strided Arrays](@id man-interface-strided-arrays) @@ -505,7 +507,7 @@ However, if needed you can specialize on any or all of these arguments. For a complete example, let's say you have created a type, `ArrayAndChar`, that stores an array and a single character: -```jldoctest +```jldoctest ArrayAndChar struct ArrayAndChar{T,N} <: AbstractArray{T,N} data::Array{T,N} char::Char @@ -514,16 +516,20 @@ Base.size(A::ArrayAndChar) = size(A.data) Base.getindex(A::ArrayAndChar{T,N}, inds::Vararg{Int,N}) where {T,N} = A.data[inds...] Base.setindex!(A::ArrayAndChar{T,N}, val, inds::Vararg{Int,N}) where {T,N} = A.data[inds...] = val Base.showarg(io::IO, A::ArrayAndChar, toplevel) = print(io, typeof(A), " with char '", A.char, "'") +# output + ``` You might want broadcasting to preserve the `char` "metadata." First we define -```jldoctest +```jldoctest ArrayAndChar Base.BroadcastStyle(::Type{<:ArrayAndChar}) = Broadcast.ArrayStyle{ArrayAndChar}() +# output + ``` This forces us to also define a `broadcast_similar` method: -```jldoctest +```jldoctest ArrayAndChar; filter = r"(^find_aac \(generic function with 2 methods\)$|^$)" function Base.broadcast_similar(f, ::Broadcast.ArrayStyle{ArrayAndChar}, ::Type{ElType}, inds, As...) where ElType # Scan the inputs for the ArrayAndChar: A = find_aac(As...) @@ -533,11 +539,13 @@ end "`A = find_aac(As...)` returns the first ArrayAndChar among the arguments." find_aac(A::ArrayAndChar, B...) = A -find_aac(A, B...) = find_aac(B...) +find_aac(A, B...) = find_aac(B...); +# output + ``` From these definitions, one obtains the following behavior: -```jldoctest +```jldoctest ArrayAndChar julia> a = ArrayAndChar([1 2; 3 4], 'x') 2×2 ArrayAndChar{Int64,2} with char 'x': 1 2 diff --git a/src/manual/mathematical-operations.md b/src/manual/mathematical-operations.md index b539efb..f33449c 100644 --- a/src/manual/mathematical-operations.md +++ b/src/manual/mathematical-operations.md @@ -380,7 +380,7 @@ You can also find the numerical precedence for any given operator via the built- ```jldoctest julia> Base.operator_precedence(:+), Base.operator_precedence(:*), Base.operator_precedence(:.) -(9, 11, 15) +(11, 13, 17) julia> Base.operator_precedence(:sin), Base.operator_precedence(:+=), Base.operator_precedence(:(=)) # (Note the necessary parens on `:(=)`) (0, 1, 1) @@ -424,25 +424,20 @@ julia> Int8(127) julia> Int8(128) ERROR: InexactError: trunc(Int8, 128) Stacktrace: - [1] throw_inexacterror(::Symbol, ::Type{Int8}, ::Int64) at ./int.jl:34 - [2] checked_trunc_sint at ./int.jl:438 [inlined] - [3] convert at ./int.jl:458 [inlined] - [4] Int8(::Int64) at ./sysimg.jl:114 +[...] julia> Int8(127.0) 127 julia> Int8(3.14) -ERROR: InexactError: convert(Int8, 3.14) +ERROR: InexactError: Int8(Int8, 3.14) Stacktrace: - [1] convert at ./float.jl:682 [inlined] - [2] Int8(::Float64) at ./sysimg.jl:114 +[...] julia> Int8(128.0) -ERROR: InexactError: convert(Int8, 128.0) +ERROR: InexactError: Int8(Int8, 128.0) Stacktrace: - [1] convert at ./float.jl:682 [inlined] - [2] Int8(::Float64) at ./sysimg.jl:114 +[...] julia> 127 % Int8 127 @@ -456,8 +451,7 @@ julia> round(Int8,127.4) julia> round(Int8,127.6) ERROR: InexactError: trunc(Int8, 128.0) Stacktrace: - [1] trunc at ./float.jl:675 [inlined] - [2] round(::Type{Int8}, ::Float64) at ./float.jl:353 +[...] ``` See [Conversion and Promotion](@ref conversion-and-promotion) for how to define your own conversions and promotions. diff --git a/src/manual/metaprogramming.md b/src/manual/metaprogramming.md index 2ac0c0c..901076c 100644 --- a/src/manual/metaprogramming.md +++ b/src/manual/metaprogramming.md @@ -216,7 +216,7 @@ Interpolating into an unquoted expression is not supported and will cause a comp ```jldoctest interp1 julia> $a + b -ERROR: unsupported or misplaced expression $ +ERROR: syntax: "$" expression outside quote ``` In this example, the tuple `(1,2,3)` is interpolated as an expression into a conditional test: diff --git a/src/manual/missing.md b/src/manual/missing.md index 89ccb7f..4467f58 100644 --- a/src/manual/missing.md +++ b/src/manual/missing.md @@ -276,10 +276,6 @@ julia> y = Union{Missing, String}[missing, "b"] julia> convert(Array{String}, y) ERROR: MethodError: Cannot `convert` an object of type Missing to an object of type String -This may have arisen from a call to the constructor String(...), -since type constructors fall back to convert methods. -Stacktrace: -[... ``` ## Skipping Missing Values diff --git a/src/manual/parallel-computing.md b/src/manual/parallel-computing.md index d70befa..58bdaf9 100644 --- a/src/manual/parallel-computing.md +++ b/src/manual/parallel-computing.md @@ -727,7 +727,8 @@ Methods [`put!`](@ref), [`take!`](@ref), [`fetch`](@ref), [`isready`](@ref) and on a [`RemoteChannel`](@ref) are proxied onto the backing store on the remote process. [`RemoteChannel`](@ref) can thus be used to refer to user implemented `AbstractChannel` objects. -A simple example of this is provided in `examples/dictchannel.jl` which uses a dictionary as its +A simple example of this is provided in `dictchannel.jl` in the +[Examples repository](https://github.com/JuliaArchive/Examples), which uses a dictionary as its remote store. ## Channels and RemoteChannels @@ -1246,7 +1247,8 @@ transport and Julia's in-built parallel infrastructure. A `BufferStream` is an in-memory [`IOBuffer`](@ref) which behaves like an `IO`--it is a stream which can be handled asynchronously. -Folder `examples/clustermanager/0mq` contains an example of using ZeroMQ to connect Julia workers +The folder `clustermanager/0mq` in the [Examples repository](https://github.com/JuliaArchive/Examples) +contains an example of using ZeroMQ to connect Julia workers in a star topology with a 0MQ broker in the middle. Note: The Julia processes are still all *logically* connected to each other--any worker can message any other worker directly without any awareness of 0MQ being used as the transport layer. @@ -1268,7 +1270,7 @@ When using custom transports: the corresponding `IO` objects must be closed by the implementation to ensure proper cleanup. The default implementation simply executes an `exit()` call on the specified remote worker. -`examples/clustermanager/simple` is an example that shows a simple implementation using UNIX domain +The Examples folder `clustermanager/simple` is an example that shows a simple implementation using UNIX domain sockets for cluster setup. ## Network Requirements for LocalManager and SSHManager diff --git a/src/manual/performance-tips.md b/src/manual/performance-tips.md index a832506..84dd79c 100644 --- a/src/manual/performance-tips.md +++ b/src/manual/performance-tips.md @@ -453,10 +453,7 @@ MyBetterContainer{Float64,UnitRange{Float64}} julia> b = MyBetterContainer{Int64, UnitRange{Float64}}(UnitRange(1.3, 5.0)); ERROR: MethodError: Cannot `convert` an object of type UnitRange{Float64} to an object of type MyBetterContainer{Int64,UnitRange{Float64}} -This may have arisen from a call to the constructor MyBetterContainer{Int64,UnitRange{Float64}}(...), -since type constructors fall back to convert methods. -Stacktrace: - [1] MyBetterContainer{Int64,UnitRange{Float64}}(::UnitRange{Float64}) at ./sysimg.jl:114 +[...] ``` The inner constructor requires that the element type of `A` be `T`. @@ -621,7 +618,7 @@ end ```jldoctest julia> function strange_twos(n) - a = Vector{rand(Bool) ? Int64 : Float64}(n) + a = Vector{rand(Bool) ? Int64 : Float64}(uninitialized, n) for i = 1:n a[i] = 2 end @@ -640,7 +637,7 @@ This should be written as: ```jldoctest julia> function fill_twos!(a) - for i=eachindex(a) + for i = eachindex(a) a[i] = 2 end end diff --git a/src/manual/running-external-programs.md b/src/manual/running-external-programs.md index 88fc044..749d88b 100644 --- a/src/manual/running-external-programs.md +++ b/src/manual/running-external-programs.md @@ -29,7 +29,7 @@ julia> mycommand = `echo hello` julia> typeof(mycommand) Cmd -julia> run(mycommand) +julia> run(mycommand); hello ``` @@ -209,7 +209,7 @@ values. Let's try the above two examples in Julia: julia> A = `perl -le '$|=1; for (0..3) { print }'` `perl -le '$|=1; for (0..3) { print }'` -julia> run(A) +julia> run(A); 0 1 2 @@ -220,7 +220,7 @@ julia> first = "A"; second = "B"; julia> B = `perl -le 'print for @ARGV' "1: $first" "2: $second"` `perl -le 'print for @ARGV' '1: A' '2: B'` -julia> run(B) +julia> run(B); 1: A 2: B ``` @@ -236,10 +236,10 @@ easily and safely just examine its interpretation without doing any damage. Shell metacharacters, such as `|`, `&`, and `>`, need to be quoted (or escaped) inside of Julia's backticks: ```jldoctest -julia> run(`echo hello '|' sort`) +julia> run(`echo hello '|' sort`); hello | sort -julia> run(`echo hello \| sort`) +julia> run(`echo hello \| sort`); hello | sort ``` @@ -248,7 +248,7 @@ The result is that a single line is printed: `hello | sort`. How, then, does one pipeline? Instead of using `'|'` inside of backticks, one uses [`pipeline`](@ref): ```jldoctest -julia> run(pipeline(`echo hello`, `sort`)) +julia> run(pipeline(`echo hello`, `sort`)); hello ``` @@ -273,8 +273,8 @@ that shells cannot. Julia can run multiple commands in parallel: -```julia-repl -julia> run(`echo hello` & `echo world`) +```jldoctest; filter = r"(world\nhello|hello\nworld)" +julia> run(`echo hello` & `echo world`); world hello ``` @@ -285,7 +285,7 @@ share with each other and the `julia` parent process. Julia lets you pipe the ou of these processes to another program: ```jldoctest -julia> run(pipeline(`echo world` & `echo hello`, `sort`)) +julia> run(pipeline(`echo world` & `echo hello`, `sort`)); hello world ``` @@ -326,24 +326,20 @@ setup of pipes between processes is a powerful one. To give some sense of the co that can be created easily, here are some more sophisticated examples, with apologies for the excessive use of Perl one-liners: -```julia-repl +```jldoctest prefixer; filter = r"([A-B] [0-5])" julia> prefixer(prefix, sleep) = `perl -nle '$|=1; print "'$prefix' ", $_; sleep '$sleep';'`; -julia> run(pipeline(`perl -le '$|=1; for(0..9){ print; sleep 1 }'`, prefixer("A",2) & prefixer("B",2))) -A 0 -B 1 -A 2 -B 3 -A 4 -B 5 -A 6 -B 7 -A 8 -B 9 +julia> run(pipeline(`perl -le '$|=1; for(0..5){ print; sleep 1 }'`, prefixer("A",2) & prefixer("B",2))); +B 0 +A 1 +B 2 +A 3 +B 4 +A 5 ``` This is a classic example of a single producer feeding two concurrent consumers: one `perl` process -generates lines with the numbers 0 through 9 on them, while two parallel processes consume that +generates lines with the numbers 0 through 5 on them, while two parallel processes consume that output, one prefixing lines with the letter "A", the other with the letter "B". Which consumer gets the first line is non-deterministic, but once that race has been won, the lines are consumed alternately by one process and then the other. (Setting `$|=1` in Perl causes each print statement @@ -352,20 +348,16 @@ the output is buffered and printed to the pipe at once, to be read by just one c Here is an even more complex multi-stage producer-consumer example: -```julia-repl -julia> run(pipeline(`perl -le '$|=1; for(0..9){ print; sleep 1 }'`, +```jldoctest prefixer; filter = r"[A-B] [X-Z] [0-5]" +julia> run(pipeline(`perl -le '$|=1; for(0..5){ print; sleep 1 }'`, prefixer("X",3) & prefixer("Y",3) & prefixer("Z",3), - prefixer("A",2) & prefixer("B",2))) + prefixer("A",2) & prefixer("B",2))); A X 0 B Y 1 A Z 2 B X 3 A Y 4 B Z 5 -A X 6 -B Y 7 -A Z 8 -B X 9 ``` This example is similar to the previous one, except there are two stages of consumers, and the diff --git a/src/manual/strings.md b/src/manual/strings.md index dcfd739..5002016 100644 --- a/src/manual/strings.md +++ b/src/manual/strings.md @@ -78,7 +78,7 @@ is a valid code point, use the [`isvalid`](@ref) function: ```jldoctest julia> Char(0x110000) -'\U110000': Unicode U+110000 (category Cn: Other, not assigned) +'\U110000': Unicode U+110000 (category In: Invalid, too high) julia> isvalid(Char, 0x110000) false @@ -129,9 +129,6 @@ julia> Int('\x7f') julia> Int('\177') 127 - -julia> Int('\xff') -255 ``` You can do comparisons and a limited amount of arithmetic with `Char` values: @@ -275,11 +272,12 @@ julia> s[1] '∀': Unicode U+2200 (category Sm: Symbol, math) julia> s[2] -ERROR: UnicodeError: invalid character index +ERROR: StringIndexError("∀ x ∃ y", 2) [...] julia> s[3] -ERROR: UnicodeError: invalid character index +ERROR: StringIndexError("∀ x ∃ y", 3) +Stacktrace: [...] julia> s[4] @@ -297,7 +295,8 @@ julia> s[1:1] "∀" julia> s[1:2] -ERROR: UnicodeError: invalid character index +ERROR: StringIndexError("∀ x ∃ y", 2) +Stacktrace: [...] julia> s[1:4] @@ -312,7 +311,7 @@ since each character in a string must have its own index. The following is an in verbose way to iterate through the characters of `s`: ```jldoctest unicodestring -julia> for i = begindex(s):lastindex(s) +julia> for i = firstindex(s):lastindex(s) try println(s[i]) catch @@ -824,7 +823,7 @@ produce arrays of bytes. Here is an example using all three: ```jldoctest julia> b"DATA\xff\u2200" -8-element Array{UInt8,1}: +8-element Base.CodeUnits{UInt8,String}: 0x44 0x41 0x54 @@ -851,11 +850,11 @@ is encoded as two bytes in UTF-8: ```jldoctest julia> b"\xff" -1-element Array{UInt8,1}: +1-element Base.CodeUnits{UInt8,String}: 0xff julia> b"\uff" -2-element Array{UInt8,1}: +2-element Base.CodeUnits{UInt8,String}: 0xc3 0xbf ``` diff --git a/src/manual/types.md b/src/manual/types.md index c64215b..3260b39 100644 --- a/src/manual/types.md +++ b/src/manual/types.md @@ -16,10 +16,11 @@ of function arguments to be deeply integrated with the language. Method dispatch detail in [Methods](@ref), but is rooted in the type system presented here. The default behavior in Julia when types are omitted is to allow values to be of any type. Thus, -one can write many useful Julia programs without ever explicitly using types. When additional +one can write many useful Julia functions without ever explicitly using types. When additional expressiveness is needed, however, it is easy to gradually introduce explicit type annotations -into previously "untyped" code. Doing so will typically increase both the performance and robustness -of these systems, and perhaps somewhat counterintuitively, often significantly simplify them. +into previously "untyped" code. Adding annotations serves three primary purposes: to take advantage +of Julia's powerful multiple-dispatch mechanism, to improve human readability, and to catch +programmer errors. Describing Julia in the lingo of [type systems](https://en.wikipedia.org/wiki/Type_system), it is: dynamic, nominative and parametric. Generic types can be parameterized, and the hierarchical @@ -343,20 +344,16 @@ must be convertible to `Int`: ```jldoctest footype julia> Foo((), 23.5, 1) -ERROR: InexactError: convert(Int64, 23.5) +ERROR: InexactError: Int64(Int64, 23.5) Stacktrace: - [1] convert at ./float.jl:703 [inlined] - [2] Foo(::Tuple{}, ::Float64, ::Int64) at ./none:2 +[...] ``` You may find a list of field names using the `fieldnames` function. ```jldoctest footype julia> fieldnames(Foo) -3-element Array{Symbol,1}: - :bar - :baz - :qux +(:bar, :baz, :qux) ``` You can access the field values of a composite object using the traditional `foo.bar` notation: @@ -648,13 +645,11 @@ For the default constructor, exactly one argument must be supplied for each fiel ```jldoctest pointtype julia> Point{Float64}(1.0) ERROR: MethodError: Cannot `convert` an object of type Float64 to an object of type Point{Float64} -This may have arisen from a call to the constructor Point{Float64}(...), -since type constructors fall back to convert methods. -Stacktrace: - [1] Point{Float64}(::Float64) at ./sysimg.jl:114 +[...] julia> Point{Float64}(1.0,2.0,3.0) ERROR: MethodError: no method matching Point{Float64}(::Float64, ::Float64, ::Float64) +[...] ``` Only one default constructor is generated for parametric types, since overriding it is not possible. diff --git a/src/manual/variables-and-scoping.md b/src/manual/variables-and-scoping.md index 4fc5ba1..088aafd 100644 --- a/src/manual/variables-and-scoping.md +++ b/src/manual/variables-and-scoping.md @@ -251,15 +251,15 @@ which have a private state, for instance the ``state`` variable in the following example: ```jldoctest - julia> let state = 0 - global counter() = (state += 1) - end; +julia> let state = 0 + global counter() = (state += 1) + end; - julia> counter() - 1 +julia> counter() +1 - julia> counter() - 2 +julia> counter() +2 ``` See also the closures in the examples in the next two sections. diff --git a/src/stdlib/Dates.md b/src/stdlib/Dates.md index 2b3adef..3a434cc 100644 --- a/src/stdlib/Dates.md +++ b/src/stdlib/Dates.md @@ -144,14 +144,14 @@ julia> dt2 = Date(2000,2,1) julia> dump(dt) Date - instant: Dates.UTInstant{Dates.Day} - periods: Dates.Day + instant: Dates.UTInstant{Day} + periods: Day value: Int64 734562 julia> dump(dt2) Date - instant: Dates.UTInstant{Dates.Day} - periods: Dates.Day + instant: Dates.UTInstant{Day} + periods: Day value: Int64 730151 julia> dt > dt2 @@ -170,7 +170,6 @@ ERROR: MethodError: no method matching *(::Date, ::Date) julia> dt / dt2 ERROR: MethodError: no method matching /(::Date, ::Date) -[...] julia> dt - dt2 4411 days @@ -240,12 +239,12 @@ One may also access the underlying `UTInstant` or integer value: ```jldoctest tdate julia> dump(t) Date - instant: Dates.UTInstant{Dates.Day} - periods: Dates.Day + instant: Dates.UTInstant{Day} + periods: Day value: Int64 735264 julia> t.instant -Dates.UTInstant{Dates.Day}(735264 days) +Dates.UTInstant{Day}(735264 days) julia> Dates.value(t) 735264 @@ -559,7 +558,7 @@ julia> round(DateTime(2016, 8, 6, 20, 15), Dates.Day) Unlike the numeric [`round`](@ref) method, which breaks ties toward the even number by default, the [`TimeType`](@ref)[`round`](@ref) method uses the `RoundNearestTiesUp` rounding mode. (It's difficult to guess what breaking ties to nearest "even" [`TimeType`](@ref) would entail.) Further -details on the available `RoundingMode` s can be found in the [API reference](@ref stdlib-dates). +details on the available `RoundingMode` s can be found in the [API reference](@ref stdlib-dates-api). Rounding should generally behave as expected, but there are a few cases in which the expected behaviour is not obvious. diff --git a/src/stdlib/IterativeEigensolvers.md b/src/stdlib/IterativeEigensolvers.md index 62dadc7..185d2dc 100644 --- a/src/stdlib/IterativeEigensolvers.md +++ b/src/stdlib/IterativeEigensolvers.md @@ -1,7 +1,7 @@ # [Iterative Eigensolvers](@id lib-itereigen) ```@meta -DocTestSetup = :(using IterativeEigensolvers) +DocTestSetup = :(using IterativeEigensolvers, LinearAlgebra, SparseArrays) ``` Julia provides bindings to [ARPACK](http://www.caam.rice.edu/software/ARPACK/), which @@ -53,9 +53,7 @@ the following keyword arguments are supported: * `v0`: starting vector from which to start the iterations We can see the various keywords in action in the following examples: -```jldoctest -julia> using IterativeEigensolvers - +```jldoctest; filter = r"(1|2)-element Array{(Float64|Complex{Float64}),1}:\n (.|\s)*$" julia> A = Diagonal(1:4); julia> λ, ϕ = eigs(A, nev = 2, which=:SM); @@ -65,42 +63,37 @@ julia> λ 1.0000000000000002 2.0 -julia> B = Diagonal([1., 2., -3im, 4im]) -4×4 Diagonal{Complex{Float64},Array{Complex{Float64},1}}: - 1.0+0.0im ⋅ ⋅ ⋅ - ⋅ 2.0+0.0im ⋅ ⋅ - ⋅ ⋅ 0.0-3.0im ⋅ - ⋅ ⋅ ⋅ 0.0+4.0im +julia> B = Diagonal([1., 2., -3im, 4im]); julia> λ, ϕ = eigs(B, nev=1, which=:LI); julia> λ 1-element Array{Complex{Float64},1}: - -4.440892098500626e-16 + 3.999999999999998im + 1.3322676295501878e-15 + 4.0im julia> λ, ϕ = eigs(B, nev=1, which=:SI); julia> λ 1-element Array{Complex{Float64},1}: - 1.3877787807814457e-16 - 2.999999999999999im + -2.498001805406602e-16 - 3.0000000000000018im julia> λ, ϕ = eigs(B, nev=1, which=:LR); julia> λ 1-element Array{Complex{Float64},1}: - 2.0 + 4.242754940683747e-17im + 2.0000000000000004 + 4.0615212488780827e-17im julia> λ, ϕ = eigs(B, nev=1, which=:SR); julia> λ 1-element Array{Complex{Float64},1}: - 4.440892098500626e-16 + 4.0000000000000036im + -8.881784197001252e-16 + 3.999999999999997im julia> λ, ϕ = eigs(B, nev=1, sigma=1.5); julia> λ 1-element Array{Complex{Float64},1}: - 1.9999999999999996 + 2.4290457684137336e-17im + 1.0000000000000004 + 4.0417078924070745e-18im ``` !!! note @@ -168,31 +161,29 @@ iterations `niter` and the number of matrix vector multiplications `nmult`, as w final residual vector `resid`. We can see the various keywords in action in the following examples: -```jldoctest -julia> using IterativeEigensolvers - +```jldoctest; filter = r"(1|2)-element Array{(Float64|Complex{Float64}),1}:\n (.|\s)*$" julia> A = sparse(1.0I, 4, 4); B = Diagonal(1:4); julia> λ, ϕ = eigs(A, B, nev = 2); julia> λ 2-element Array{Float64,1}: - 1.0 - 0.4999999999999999 + 1.0000000000000002 + 0.5 -julia> A = sparse(1.0I, 4, 4); B = Diagonal([1, -2im, 3, 4im]); +julia> A = Diagonal([1, -2im, 3, 4im]); B = sparse(1.0I, 4, 4); julia> λ, ϕ = eigs(A, B, nev=1, which=:SI); julia> λ 1-element Array{Complex{Float64},1}: - 0.03291282838780993 - 2.0627621271174514im + -1.5720931501039814e-16 - 1.9999999999999984im julia> λ, ϕ = eigs(A, B, nev=1, which=:LI); julia> λ 1-element Array{Complex{Float64},1}: - -0.6428551411711136 + 2.1820633510068994im + 0.0 + 4.000000000000002im ``` !!! note diff --git a/src/stdlib/LinearAlgebra.md b/src/stdlib/LinearAlgebra.md index d931b8c..e46e75e 100644 --- a/src/stdlib/LinearAlgebra.md +++ b/src/stdlib/LinearAlgebra.md @@ -60,9 +60,17 @@ julia> A = [1.5 2 -4; 3 -1 -6; -10 2.3 4] -10.0 2.3 4.0 julia> factorize(A) -LinearAlgebra.LU{Float64,Array{Float64,2}} with factors L and U: -[1.0 0.0 0.0; -0.15 1.0 0.0; -0.3 -0.132196 1.0] -[-10.0 2.3 4.0; 0.0 2.345 -3.4; 0.0 0.0 -5.24947] +LU{Float64,Array{Float64,2}} +L factor: +3×3 Array{Float64,2}: + 1.0 0.0 0.0 + -0.15 1.0 0.0 + -0.3 -0.132196 1.0 +U factor: +3×3 Array{Float64,2}: + -10.0 2.3 4.0 + 0.0 2.345 -3.4 + 0.0 0.0 -5.24947 ``` Since `A` is not Hermitian, symmetric, triangular, tridiagonal, or bidiagonal, an LU factorization may be the @@ -76,17 +84,17 @@ julia> B = [1.5 2 -4; 2 -1 -3; -4 -3 5] -4.0 -3.0 5.0 julia> factorize(B) -LinearAlgebra.BunchKaufman{Float64,Array{Float64,2}} +BunchKaufman{Float64,Array{Float64,2}} D factor: 3×3 Tridiagonal{Float64,Array{Float64,1}}: -1.64286 0.0 ⋅ 0.0 -2.8 0.0 ⋅ 0.0 5.0 U factor: -3×3 LinearAlgebra.UnitUpperTriangular{Float64,Array{Float64,2}}: +3×3 UnitUpperTriangular{Float64,Array{Float64,2}}: 1.0 0.142857 -0.8 - 0.0 1.0 -0.6 - 0.0 0.0 1.0 + ⋅ 1.0 -0.6 + ⋅ ⋅ 1.0 permutation: 3-element Array{Int64,1}: 1 @@ -252,9 +260,7 @@ julia> b = [1 2 3; 4 5 6] julia> b - U ERROR: DimensionMismatch("matrix is not square: dimensions are (2, 3)") Stacktrace: - [1] checksquare at ./linalg/linalg.jl:220 [inlined] - [2] -(::Array{Int64,2}, ::UniformScaling{Int64}) at ./linalg/uniformscaling.jl:156 - [3] top-level scope +[...] ``` ## [Matrix factorizations](@id man-linalg-factorizations) @@ -416,7 +422,7 @@ Base.transpose LinearAlgebra.transpose! Base.adjoint LinearAlgebra.adjoint! -LinearAlgebra.peakflops +Base.copy(::Union{Transpose,Adjoint}) LinearAlgebra.stride1 LinearAlgebra.checksquare ``` diff --git a/src/stdlib/Sockets.md b/src/stdlib/Sockets.md index d457da9..7f4d72b 100644 --- a/src/stdlib/Sockets.md +++ b/src/stdlib/Sockets.md @@ -1,4 +1,8 @@ -## Sockets +# Sockets + +```@meta +DocTestSetup = :(using Sockets) +``` ```@docs Sockets.connect(::TCPSocket, ::Integer) @@ -23,3 +27,7 @@ Sockets.recv Sockets.recvfrom Sockets.setopt ``` + +```@meta +DocTestSetup = nothing +``` diff --git a/src/stdlib/SparseArrays.md b/src/stdlib/SparseArrays.md index 34dd58c..afde15c 100644 --- a/src/stdlib/SparseArrays.md +++ b/src/stdlib/SparseArrays.md @@ -1,7 +1,7 @@ # Sparse Arrays ```@meta -DocTestSetup = :(using SparseArrays) +DocTestSetup = :(using SparseArrays, LinearAlgebra) ``` Julia has support for sparse vectors and [sparse matrices](https://en.wikipedia.org/wiki/Sparse_matrix) diff --git a/src/stdlib/UUIDs.md b/src/stdlib/UUIDs.md index ddc490f..3b936e7 100644 --- a/src/stdlib/UUIDs.md +++ b/src/stdlib/UUIDs.md @@ -1,7 +1,7 @@ # UUIDs ```@meta -DocTestSetup = :(using UUIDs) +DocTestSetup = :(using UUIDs, Random) ``` ```@docs diff --git a/src/stdlib/dates.md b/src/stdlib/dates.md index 2b3adef..3a434cc 100644 --- a/src/stdlib/dates.md +++ b/src/stdlib/dates.md @@ -144,14 +144,14 @@ julia> dt2 = Date(2000,2,1) julia> dump(dt) Date - instant: Dates.UTInstant{Dates.Day} - periods: Dates.Day + instant: Dates.UTInstant{Day} + periods: Day value: Int64 734562 julia> dump(dt2) Date - instant: Dates.UTInstant{Dates.Day} - periods: Dates.Day + instant: Dates.UTInstant{Day} + periods: Day value: Int64 730151 julia> dt > dt2 @@ -170,7 +170,6 @@ ERROR: MethodError: no method matching *(::Date, ::Date) julia> dt / dt2 ERROR: MethodError: no method matching /(::Date, ::Date) -[...] julia> dt - dt2 4411 days @@ -240,12 +239,12 @@ One may also access the underlying `UTInstant` or integer value: ```jldoctest tdate julia> dump(t) Date - instant: Dates.UTInstant{Dates.Day} - periods: Dates.Day + instant: Dates.UTInstant{Day} + periods: Day value: Int64 735264 julia> t.instant -Dates.UTInstant{Dates.Day}(735264 days) +Dates.UTInstant{Day}(735264 days) julia> Dates.value(t) 735264 @@ -559,7 +558,7 @@ julia> round(DateTime(2016, 8, 6, 20, 15), Dates.Day) Unlike the numeric [`round`](@ref) method, which breaks ties toward the even number by default, the [`TimeType`](@ref)[`round`](@ref) method uses the `RoundNearestTiesUp` rounding mode. (It's difficult to guess what breaking ties to nearest "even" [`TimeType`](@ref) would entail.) Further -details on the available `RoundingMode` s can be found in the [API reference](@ref stdlib-dates). +details on the available `RoundingMode` s can be found in the [API reference](@ref stdlib-dates-api). Rounding should generally behave as expected, but there are a few cases in which the expected behaviour is not obvious. diff --git a/src/stdlib/iterativeeigensolvers.md b/src/stdlib/iterativeeigensolvers.md index 62dadc7..185d2dc 100644 --- a/src/stdlib/iterativeeigensolvers.md +++ b/src/stdlib/iterativeeigensolvers.md @@ -1,7 +1,7 @@ # [Iterative Eigensolvers](@id lib-itereigen) ```@meta -DocTestSetup = :(using IterativeEigensolvers) +DocTestSetup = :(using IterativeEigensolvers, LinearAlgebra, SparseArrays) ``` Julia provides bindings to [ARPACK](http://www.caam.rice.edu/software/ARPACK/), which @@ -53,9 +53,7 @@ the following keyword arguments are supported: * `v0`: starting vector from which to start the iterations We can see the various keywords in action in the following examples: -```jldoctest -julia> using IterativeEigensolvers - +```jldoctest; filter = r"(1|2)-element Array{(Float64|Complex{Float64}),1}:\n (.|\s)*$" julia> A = Diagonal(1:4); julia> λ, ϕ = eigs(A, nev = 2, which=:SM); @@ -65,42 +63,37 @@ julia> λ 1.0000000000000002 2.0 -julia> B = Diagonal([1., 2., -3im, 4im]) -4×4 Diagonal{Complex{Float64},Array{Complex{Float64},1}}: - 1.0+0.0im ⋅ ⋅ ⋅ - ⋅ 2.0+0.0im ⋅ ⋅ - ⋅ ⋅ 0.0-3.0im ⋅ - ⋅ ⋅ ⋅ 0.0+4.0im +julia> B = Diagonal([1., 2., -3im, 4im]); julia> λ, ϕ = eigs(B, nev=1, which=:LI); julia> λ 1-element Array{Complex{Float64},1}: - -4.440892098500626e-16 + 3.999999999999998im + 1.3322676295501878e-15 + 4.0im julia> λ, ϕ = eigs(B, nev=1, which=:SI); julia> λ 1-element Array{Complex{Float64},1}: - 1.3877787807814457e-16 - 2.999999999999999im + -2.498001805406602e-16 - 3.0000000000000018im julia> λ, ϕ = eigs(B, nev=1, which=:LR); julia> λ 1-element Array{Complex{Float64},1}: - 2.0 + 4.242754940683747e-17im + 2.0000000000000004 + 4.0615212488780827e-17im julia> λ, ϕ = eigs(B, nev=1, which=:SR); julia> λ 1-element Array{Complex{Float64},1}: - 4.440892098500626e-16 + 4.0000000000000036im + -8.881784197001252e-16 + 3.999999999999997im julia> λ, ϕ = eigs(B, nev=1, sigma=1.5); julia> λ 1-element Array{Complex{Float64},1}: - 1.9999999999999996 + 2.4290457684137336e-17im + 1.0000000000000004 + 4.0417078924070745e-18im ``` !!! note @@ -168,31 +161,29 @@ iterations `niter` and the number of matrix vector multiplications `nmult`, as w final residual vector `resid`. We can see the various keywords in action in the following examples: -```jldoctest -julia> using IterativeEigensolvers - +```jldoctest; filter = r"(1|2)-element Array{(Float64|Complex{Float64}),1}:\n (.|\s)*$" julia> A = sparse(1.0I, 4, 4); B = Diagonal(1:4); julia> λ, ϕ = eigs(A, B, nev = 2); julia> λ 2-element Array{Float64,1}: - 1.0 - 0.4999999999999999 + 1.0000000000000002 + 0.5 -julia> A = sparse(1.0I, 4, 4); B = Diagonal([1, -2im, 3, 4im]); +julia> A = Diagonal([1, -2im, 3, 4im]); B = sparse(1.0I, 4, 4); julia> λ, ϕ = eigs(A, B, nev=1, which=:SI); julia> λ 1-element Array{Complex{Float64},1}: - 0.03291282838780993 - 2.0627621271174514im + -1.5720931501039814e-16 - 1.9999999999999984im julia> λ, ϕ = eigs(A, B, nev=1, which=:LI); julia> λ 1-element Array{Complex{Float64},1}: - -0.6428551411711136 + 2.1820633510068994im + 0.0 + 4.000000000000002im ``` !!! note diff --git a/src/stdlib/linearalgebra.md b/src/stdlib/linearalgebra.md index d931b8c..e46e75e 100644 --- a/src/stdlib/linearalgebra.md +++ b/src/stdlib/linearalgebra.md @@ -60,9 +60,17 @@ julia> A = [1.5 2 -4; 3 -1 -6; -10 2.3 4] -10.0 2.3 4.0 julia> factorize(A) -LinearAlgebra.LU{Float64,Array{Float64,2}} with factors L and U: -[1.0 0.0 0.0; -0.15 1.0 0.0; -0.3 -0.132196 1.0] -[-10.0 2.3 4.0; 0.0 2.345 -3.4; 0.0 0.0 -5.24947] +LU{Float64,Array{Float64,2}} +L factor: +3×3 Array{Float64,2}: + 1.0 0.0 0.0 + -0.15 1.0 0.0 + -0.3 -0.132196 1.0 +U factor: +3×3 Array{Float64,2}: + -10.0 2.3 4.0 + 0.0 2.345 -3.4 + 0.0 0.0 -5.24947 ``` Since `A` is not Hermitian, symmetric, triangular, tridiagonal, or bidiagonal, an LU factorization may be the @@ -76,17 +84,17 @@ julia> B = [1.5 2 -4; 2 -1 -3; -4 -3 5] -4.0 -3.0 5.0 julia> factorize(B) -LinearAlgebra.BunchKaufman{Float64,Array{Float64,2}} +BunchKaufman{Float64,Array{Float64,2}} D factor: 3×3 Tridiagonal{Float64,Array{Float64,1}}: -1.64286 0.0 ⋅ 0.0 -2.8 0.0 ⋅ 0.0 5.0 U factor: -3×3 LinearAlgebra.UnitUpperTriangular{Float64,Array{Float64,2}}: +3×3 UnitUpperTriangular{Float64,Array{Float64,2}}: 1.0 0.142857 -0.8 - 0.0 1.0 -0.6 - 0.0 0.0 1.0 + ⋅ 1.0 -0.6 + ⋅ ⋅ 1.0 permutation: 3-element Array{Int64,1}: 1 @@ -252,9 +260,7 @@ julia> b = [1 2 3; 4 5 6] julia> b - U ERROR: DimensionMismatch("matrix is not square: dimensions are (2, 3)") Stacktrace: - [1] checksquare at ./linalg/linalg.jl:220 [inlined] - [2] -(::Array{Int64,2}, ::UniformScaling{Int64}) at ./linalg/uniformscaling.jl:156 - [3] top-level scope +[...] ``` ## [Matrix factorizations](@id man-linalg-factorizations) @@ -416,7 +422,7 @@ Base.transpose LinearAlgebra.transpose! Base.adjoint LinearAlgebra.adjoint! -LinearAlgebra.peakflops +Base.copy(::Union{Transpose,Adjoint}) LinearAlgebra.stride1 LinearAlgebra.checksquare ``` diff --git a/src/stdlib/sparsearrays.md b/src/stdlib/sparsearrays.md index 34dd58c..afde15c 100644 --- a/src/stdlib/sparsearrays.md +++ b/src/stdlib/sparsearrays.md @@ -1,7 +1,7 @@ # Sparse Arrays ```@meta -DocTestSetup = :(using SparseArrays) +DocTestSetup = :(using SparseArrays, LinearAlgebra) ``` Julia has support for sparse vectors and [sparse matrices](https://en.wikipedia.org/wiki/Sparse_matrix) diff --git a/tools/check_codex.jl b/tools/check_codex.jl index 0e9ecc5..d1438c8 100644 --- a/tools/check_codex.jl +++ b/tools/check_codex.jl @@ -4,6 +4,10 @@ const TOP_PATH = abspath(dirname(@__FILE__), "..") const JULIA_PATH = abspath(TOP_PATH, "..", "julia") +if !(VERSION >= v"0.7.0-DEV") + println("Julia ", v"0.7.0-DEV", " 버젼으로 실행하세요") +end + if !isdir(JULIA_PATH) println("줄리아 리파지토리 경로를 지정해 주세요 $JULIA_PATH") end @@ -14,7 +18,7 @@ const julia_doc_src_path = abspath(JULIA_PATH, "doc", "src") translated_files = [] function check_src_and_codex(path1, path2) - const ignore_assets = ["custom.css"] + ignore_assets = ["custom.css"] src_codex_diff = `diff -qr $path1 $path2` lines = readlines(ignorestatus(src_codex_diff)) for line in lines @@ -27,7 +31,7 @@ function check_src_and_codex(path1, path2) push!(translated_files, nub) elseif kind == "Only" (_,_,dircolon,filename) = chunk - dir = replace(dircolon, ":", "/") + dir = replace(dircolon, ":" => "/") # src에만 있으면 src에 있는 파일 지우기 if contains(dir, src_path) if endswith(filename, ".swp") @@ -47,7 +51,7 @@ end function copy_julia_doc_src_to_codex_and_src(julia_doc_src_dir, filename) for d in (codex_path, src_path) - dir = replace(julia_doc_src_dir, julia_doc_src_path, d) + dir = replace(julia_doc_src_dir, julia_doc_src_path => d) #print_with_color(:cyan, "cp ") #print_with_color(:white, julia_doc_src_dir) #print_with_color(:yellow, filename, " ") @@ -59,7 +63,7 @@ function copy_julia_doc_src_to_codex_and_src(julia_doc_src_dir, filename) end function manual_julia_doc_src_to_codex(julia_doc_src_dir, filename) - dir = replace(julia_doc_src_dir, julia_doc_src_path, codex_path) + dir = replace(julia_doc_src_dir, julia_doc_src_path => codex_path) #print_with_color(:blue, "# diff ") #print_with_color(:white, dir) #print_with_color(:yellow, filename, " ") @@ -67,7 +71,7 @@ function manual_julia_doc_src_to_codex(julia_doc_src_dir, filename) #print_with_color(:yellow, filename) print("# diff -u ", dir, filename, " ", julia_doc_src_dir, filename) println() - edit_dir = replace(julia_doc_src_dir, julia_doc_src_path, src_path) + edit_dir = replace(julia_doc_src_dir, julia_doc_src_path => src_path) #print_with_color(:blue, "# edit ") #print_with_color(:white, edit_dir) #print_with_color(:yellow, filename) @@ -102,10 +106,10 @@ function check_julia_doc_src_and_codex(path1, path2) if endswith(filename, ".swp") continue end - dir = replace(dircolon, ":", "/") + dir = replace(dircolon, ":" => "/") # codex에만 있으면 codex, src에 있는 파일 지우기 if contains(dir, codex_path) - for d in (dir, replace(dir, codex_path, src_path)) + for d in (dir, replace(dir, codex_path => src_path)) #print_with_color(:red, "rm ") #print_with_color(:white, d) #print_with_color(:yellow, filename) @@ -121,9 +125,37 @@ function check_julia_doc_src_and_codex(path1, path2) end end +function get_pages(f, path) + s = read(path, String) + r = Regex("const (PAGES = .*^\\])", "ms") + m = match(r, s) + s = string("hide(s) = nothing; STDLIB_DOCS = []; ", m[1]) + eval(Meta.parse(f(s))) +end + +function check_pages() + makejl_path = abspath(TOP_PATH, "make.jl") + julia_doc_makejl_path = abspath(JULIA_PATH, "doc", "make.jl") + pages1 = get_pages(julia_doc_makejl_path) do s; s end + pages2 = get_pages(makejl_path) do s + for (a,b) in [("홈", "Home"), + ("매뉴얼", "Manual"), + ("\"devdocs/ssair.md\", # Julia SSA-form IR", ""), # 임시 + ] + s = replace(s, a => b) + end + s + end + if pages1 == pages2 + else + @info "pages" setdiff(pages1, pages2) + end +end + const src_stdlib_path = abspath(src_path, "stdlib") const codex_stdlib_path = abspath(codex_path, "stdlib") const julia_doc_src_stdlib_path = abspath(JULIA_PATH, "doc", "src", "stdlib") +check_pages() check_src_and_codex(src_path, codex_path) check_julia_doc_src_and_codex(julia_doc_src_path, codex_path) From 4f84c3286b7b7c770b23c008e4efaac7fe7fc355 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Sat, 10 Mar 2018 12:22:57 +0900 Subject: [PATCH 011/153] update Julia Commit 56d2af7b68 --- codex/NEWS.md | 13 +++++++--- codex/base/io-network.md | 1 - codex/base/strings.md | 7 ++++-- codex/manual/metaprogramming.md | 4 +-- codex/manual/networking-and-streams.md | 10 +++++--- codex/manual/strings.md | 17 +++++++------ codex/manual/types.md | 35 ++++++++++++++++++++++++-- codex/stdlib/DelimitedFiles.md | 8 +++--- codex/stdlib/SparseArrays.md | 2 +- codex/stdlib/delimitedfiles.md | 8 +++--- codex/stdlib/sparsearrays.md | 2 +- src/NEWS.md | 13 +++++++--- src/base/io-network.md | 1 - src/base/strings.md | 7 ++++-- src/manual/metaprogramming.md | 4 +-- src/manual/networking-and-streams.md | 10 +++++--- src/manual/strings.md | 17 +++++++------ src/manual/types.md | 35 ++++++++++++++++++++++++-- src/stdlib/DelimitedFiles.md | 8 +++--- src/stdlib/SparseArrays.md | 2 +- src/stdlib/delimitedfiles.md | 8 +++--- src/stdlib/sparsearrays.md | 2 +- 22 files changed, 154 insertions(+), 60 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index 546e4ef..a2b5a81 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -421,9 +421,9 @@ This section lists changes that do not have deprecation warnings. and higher-dimensional arrays instead of linear indices as was previously the case. Use `LinearIndices(a)[findall(f, a)]` and similar constructs to compute linear indices. - * The `find*` functions which return scalars, i.e. `findnext`, `findprev`, `findfirst`, + * The `find*` functions, i.e. `findnext`, `findprev`, `findfirst`, and `findlast`, as well as `indexin`, now return `nothing` when no match is found rather - than 0 ([#25472](https://github.com/JuliaLang/julia/issues/25472), [#25662](https://github.com/JuliaLang/julia/issues/25662)). + than `0` or `0:-1` ([#25472](https://github.com/JuliaLang/julia/issues/25472), [#25662](https://github.com/JuliaLang/julia/issues/25662), [#26149](https://github.com/JuliaLang/julia/issues/26149)) * The `Base.HasShape` iterator trait has gained a type parameter `N` indicating the number of dimensions, which must correspond to the length of the tuple returned by @@ -458,6 +458,9 @@ Library improvements * The function `thisind(s::AbstractString, i::Integer)` returns the largest valid index less or equal than `i` in the string `s` or `0` if no such index exists ([#24414](https://github.com/JuliaLang/julia/issues/24414)). + * `Char` is now a subtype of `AbstractChar`, and most of the functions that + take character arguments now accept any `AbstractChar` ([#26286](https://github.com/JuliaLang/julia/issues/26286)). + * `Irrational` is now a subtype of `AbstractIrrational` ([#24245](https://github.com/JuliaLang/julia/issues/24245)). * Introduced the `empty` function, the functional pair to `empty!` which returns a new, @@ -1090,7 +1093,11 @@ Deprecated or removed * `DevNull`, `STDIN`, `STDOUT`, and `STDERR` have been renamed to `devnull`, `stdin`, `stdout`, and `stderr`, respectively ([#25786](https://github.com/JuliaLang/julia/issues/25786)). - * `wait` and `fetch` on `Task` now resemble the interface of `Future` + * `wait` and `fetch` on `Task` now resemble the interface of `Future`. + + * `showcompact(io, x...)` has been deprecated in favor of + `show(IOContext(io, :compact => true), x...)` ([#26080](https://github.com/JuliaLang/julia/issues/26080)). + Use `sprint(show, x..., context=:compact => true)` instead of `sprint(showcompact, x...)`. Command-line option changes --------------------------- diff --git a/codex/base/io-network.md b/codex/base/io-network.md index 9c0cf81..377ee41 100644 --- a/codex/base/io-network.md +++ b/codex/base/io-network.md @@ -55,7 +55,6 @@ Base.IOContext(::IO, ::IOContext) ```@docs Base.show(::Any) -Base.showcompact Base.summary Base.print Base.println diff --git a/codex/base/strings.md b/codex/base/strings.md index d71e7ef..816f607 100644 --- a/codex/base/strings.md +++ b/codex/base/strings.md @@ -1,13 +1,16 @@ # [Strings](@id lib-strings) ```@docs +Core.AbstractChar +Core.Char +Base.codepoint Base.length(::AbstractString) Base.sizeof(::AbstractString) -Base.:*(::Union{Char, AbstractString}, ::Union{Char, AbstractString}...) +Base.:*(::Union{AbstractChar, AbstractString}, ::Union{AbstractChar, AbstractString}...) Base.:^(::AbstractString, ::Integer) Base.string Base.repeat(::AbstractString, ::Integer) -Base.repeat(::Char, ::Integer) +Base.repeat(::AbstractChar, ::Integer) Base.repr(::Any) Core.String(::AbstractString) Base.SubString diff --git a/codex/manual/metaprogramming.md b/codex/manual/metaprogramming.md index 901076c..14fa9c5 100644 --- a/codex/manual/metaprogramming.md +++ b/codex/manual/metaprogramming.md @@ -407,10 +407,10 @@ julia> eval(ex) The value of `a` is used to construct the expression `ex` which applies the `+` function to the value 1 and the variable `b`. Note the important distinction between the way `a` and `b` are used: - * The value of the *variable*`a` at expression construction time is used as an immediate value in + * The value of the *variable* `a` at expression construction time is used as an immediate value in the expression. Thus, the value of `a` when the expression is evaluated no longer matters: the value in the expression is already `1`, independent of whatever the value of `a` might be. - * On the other hand, the *symbol*`:b` is used in the expression construction, so the value of the + * On the other hand, the *symbol* `:b` is used in the expression construction, so the value of the variable `b` at that time is irrelevant -- `:b` is just a symbol and the variable `b` need not even be defined. At expression evaluation time, however, the value of the symbol `:b` is resolved by looking up the value of the variable `b`. diff --git a/codex/manual/networking-and-streams.md b/codex/manual/networking-and-streams.md index 4d75c59..51b6912 100644 --- a/codex/manual/networking-and-streams.md +++ b/codex/manual/networking-and-streams.md @@ -100,19 +100,23 @@ Note that `a` is written to [`stdout`](@ref) by the [`write`](@ref) function and value is `1` (since `0x61` is one byte). For text I/O, use the [`print`](@ref) or [`show`](@ref) methods, depending on your needs (see -the Julia Base reference for a detailed discussion of the difference between the two): +the documentation for these two methods for a detailed discussion of the difference between them): ```jldoctest julia> print(stdout, 0x61) 97 ``` +See [Custom pretty-printing](@ref man-custom-pretty-printing) for more information on how to +implement display methods for custom types. + ## IO Output Contextual Properties Sometimes IO output can benefit from the ability to pass contextual information into show methods. The [`IOContext`](@ref) object provides this framework for associating arbitrary metadata with an IO object. -For example, [`showcompact`](@ref) adds a hinting parameter to the IO object that the invoked show method -should print a shorter output (if applicable). +For example, `:compact => true` adds a hinting parameter to the IO object that the invoked show method +should print a shorter output (if applicable). See the [`IOContext`](@ref) documentation for a list +of common properties. ## Working with Files diff --git a/codex/manual/strings.md b/codex/manual/strings.md index 5002016..68c2ccf 100644 --- a/codex/manual/strings.md +++ b/codex/manual/strings.md @@ -28,9 +28,10 @@ There are a few noteworthy high-level features about Julia's strings: additional `AbstractString` subtypes (e.g. for other encodings). If you define a function expecting a string argument, you should declare the type as `AbstractString` in order to accept any string type. - * Like C and Java, but unlike most dynamic languages, Julia has a first-class type representing - a single character, called `Char`. This is just a special kind of 32-bit primitive type whose numeric - value represents a Unicode code point. + * Like C and Java, but unlike most dynamic languages, Julia has a first-class type for representing + a single character, called `AbstractChar`. The built-in `Char` subtype of `AbstractChar` + is a 32-bit primitive type that can represent any Unicode character (and which is based + on the UTF-8 encoding). * As in Java, strings are immutable: the value of an `AbstractString` object cannot be changed. To construct a different string value, you construct a new string from parts of other strings. * Conceptually, a string is a *partial function* from indices to characters: for some index values, @@ -41,9 +42,11 @@ There are a few noteworthy high-level features about Julia's strings: ## [Characters](@id man-characters) -A `Char` value represents a single character: it is just a 32-bit primitive type with a special literal -representation and appropriate arithmetic behaviors, whose numeric value is interpreted as a -[Unicode code point](https://en.wikipedia.org/wiki/Code_point). Here is how `Char` values are +An `Char` value represents a single character: it is just a 32-bit primitive type with a special literal +representation and appropriate arithmetic behaviors, and which can be converted +to a numeric value representing a +[Unicode code point](https://en.wikipedia.org/wiki/Code_point). (Julia packages may define + other subtypes of `AbstractChar`, e.g. to optimize operations for other [text encodings](https://en.wikipedia.org/wiki/Character_encoding).) Here is how `Char` values are input and shown: ```jldoctest @@ -428,7 +431,7 @@ julia> "v: $v" "v: [1, 2, 3]" ``` -[`string`](@ref) is the identity for `AbstractString` and `Char` values, so these are interpolated +[`string`](@ref) is the identity for `AbstractString` and `AbstractChar` values, so these are interpolated into strings as themselves, unquoted and unescaped: ```jldoctest diff --git a/codex/manual/types.md b/codex/manual/types.md index 3260b39..20c40c3 100644 --- a/codex/manual/types.md +++ b/codex/manual/types.md @@ -247,7 +247,7 @@ primitive type Float32 <: AbstractFloat 32 end primitive type Float64 <: AbstractFloat 64 end primitive type Bool <: Integer 8 end -primitive type Char 32 end +primitive type Char <: AbstractChar 32 end primitive type Int8 <: Signed 8 end primitive type UInt8 <: Unsigned 8 end @@ -1187,7 +1187,7 @@ Closest candidates are: supertype(!Matched::UnionAll) at operators.jl:47 ``` -## Custom pretty-printing +## [Custom pretty-printing](@id man-custom-pretty-printing) Often, one wants to customize how instances of a type are displayed. This is accomplished by overloading the [`show`](@ref) function. For example, suppose we define a type to represent @@ -1321,6 +1321,37 @@ julia> :($a == 2) :(3.0 * exp(4.0im) == 2) ``` +In some cases, it is useful to adjust the behavior of `show` methods depending +on the context. This can be achieved via the [`IOContext`](@ref) type, which allows +passing contextual properties together with a wrapped IO stream. +For example, we can build a shorter representation in our `show` method +when the `:compact` property is set to `true`, falling back to the long +representation if the property is `false` or absent: +```jldoctest polartype +julia> function Base.show(io::IO, z::Polar) + if get(io, :compact, false) + print(io, z.r, "ℯ", z.Θ, "im") + else + print(io, z.r, " * exp(", z.Θ, "im)") + end + end +``` + +This new compact representation will be used when the passed IO stream is an `IOContext` +object with the `:compact` property set. In particular, this is the case when printing +arrays with multiple columns (where horizontal space is limited): +```jldoctest polartype +julia> show(IOContext(stdout, :compact=>true), Polar(3, 4.0)) +3.0ℯ4.0im + +julia> [Polar(3, 4.0) Polar(4.0,5.3)] +1×2 Array{Polar{Float64},2}: + 3.0ℯ4.0im 4.0ℯ5.3im +``` + +See the [`IOContext`](@ref) documentation for a list of common properties which can be used +to adjust printing. + ## "Value types" In Julia, you can't dispatch on a *value* such as `true` or `false`. However, you can dispatch diff --git a/codex/stdlib/DelimitedFiles.md b/codex/stdlib/DelimitedFiles.md index 2a343d5..839bdb8 100644 --- a/codex/stdlib/DelimitedFiles.md +++ b/codex/stdlib/DelimitedFiles.md @@ -5,10 +5,10 @@ DocTestSetup = :(using DelimitedFiles) ``` ```@docs -DelimitedFiles.readdlm(::Any, ::Char, ::Type, ::Char) -DelimitedFiles.readdlm(::Any, ::Char, ::Char) -DelimitedFiles.readdlm(::Any, ::Char, ::Type) -DelimitedFiles.readdlm(::Any, ::Char) +DelimitedFiles.readdlm(::Any, ::AbstractChar, ::Type, ::AbstractChar) +DelimitedFiles.readdlm(::Any, ::AbstractChar, ::AbstractChar) +DelimitedFiles.readdlm(::Any, ::AbstractChar, ::Type) +DelimitedFiles.readdlm(::Any, ::AbstractChar) DelimitedFiles.readdlm(::Any, ::Type) DelimitedFiles.readdlm(::Any) DelimitedFiles.writedlm diff --git a/codex/stdlib/SparseArrays.md b/codex/stdlib/SparseArrays.md index afde15c..af1be79 100644 --- a/codex/stdlib/SparseArrays.md +++ b/codex/stdlib/SparseArrays.md @@ -211,7 +211,7 @@ SparseArrays.nnz SparseArrays.findnz SparseArrays.spzeros SparseArrays.spdiagm -SparseArrays.blkdiag +SparseArrays.blockdiag SparseArrays.sprand SparseArrays.sprandn SparseArrays.nonzeros diff --git a/codex/stdlib/delimitedfiles.md b/codex/stdlib/delimitedfiles.md index 2a343d5..839bdb8 100644 --- a/codex/stdlib/delimitedfiles.md +++ b/codex/stdlib/delimitedfiles.md @@ -5,10 +5,10 @@ DocTestSetup = :(using DelimitedFiles) ``` ```@docs -DelimitedFiles.readdlm(::Any, ::Char, ::Type, ::Char) -DelimitedFiles.readdlm(::Any, ::Char, ::Char) -DelimitedFiles.readdlm(::Any, ::Char, ::Type) -DelimitedFiles.readdlm(::Any, ::Char) +DelimitedFiles.readdlm(::Any, ::AbstractChar, ::Type, ::AbstractChar) +DelimitedFiles.readdlm(::Any, ::AbstractChar, ::AbstractChar) +DelimitedFiles.readdlm(::Any, ::AbstractChar, ::Type) +DelimitedFiles.readdlm(::Any, ::AbstractChar) DelimitedFiles.readdlm(::Any, ::Type) DelimitedFiles.readdlm(::Any) DelimitedFiles.writedlm diff --git a/codex/stdlib/sparsearrays.md b/codex/stdlib/sparsearrays.md index afde15c..af1be79 100644 --- a/codex/stdlib/sparsearrays.md +++ b/codex/stdlib/sparsearrays.md @@ -211,7 +211,7 @@ SparseArrays.nnz SparseArrays.findnz SparseArrays.spzeros SparseArrays.spdiagm -SparseArrays.blkdiag +SparseArrays.blockdiag SparseArrays.sprand SparseArrays.sprandn SparseArrays.nonzeros diff --git a/src/NEWS.md b/src/NEWS.md index 80e9552..02511bd 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -409,9 +409,9 @@ This section lists changes that do not have deprecation warnings. and higher-dimensional arrays instead of linear indices as was previously the case. Use `LinearIndices(a)[findall(f, a)]` and similar constructs to compute linear indices. - * The `find*` functions which return scalars, i.e. `findnext`, `findprev`, `findfirst`, + * The `find*` functions, i.e. `findnext`, `findprev`, `findfirst`, and `findlast`, as well as `indexin`, now return `nothing` when no match is found rather - than 0 ([#25472](https://github.com/JuliaLang/julia/issues/25472), [#25662](https://github.com/JuliaLang/julia/issues/25662)). + than `0` or `0:-1` ([#25472](https://github.com/JuliaLang/julia/issues/25472), [#25662](https://github.com/JuliaLang/julia/issues/25662), [#26149](https://github.com/JuliaLang/julia/issues/26149)) * The `Base.HasShape` iterator trait has gained a type parameter `N` indicating the number of dimensions, which must correspond to the length of the tuple returned by @@ -446,6 +446,9 @@ Library improvements * The function `thisind(s::AbstractString, i::Integer)` returns the largest valid index less or equal than `i` in the string `s` or `0` if no such index exists ([#24414](https://github.com/JuliaLang/julia/issues/24414)). + * `Char` is now a subtype of `AbstractChar`, and most of the functions that + take character arguments now accept any `AbstractChar` ([#26286](https://github.com/JuliaLang/julia/issues/26286)). + * `Irrational` is now a subtype of `AbstractIrrational` ([#24245](https://github.com/JuliaLang/julia/issues/24245)). * Introduced the `empty` function, the functional pair to `empty!` which returns a new, @@ -1078,7 +1081,11 @@ Deprecated or removed * `DevNull`, `STDIN`, `STDOUT`, and `STDERR` have been renamed to `devnull`, `stdin`, `stdout`, and `stderr`, respectively ([#25786](https://github.com/JuliaLang/julia/issues/25786)). - * `wait` and `fetch` on `Task` now resemble the interface of `Future` + * `wait` and `fetch` on `Task` now resemble the interface of `Future`. + + * `showcompact(io, x...)` has been deprecated in favor of + `show(IOContext(io, :compact => true), x...)` ([#26080](https://github.com/JuliaLang/julia/issues/26080)). + Use `sprint(show, x..., context=:compact => true)` instead of `sprint(showcompact, x...)`. Command-line option changes --------------------------- diff --git a/src/base/io-network.md b/src/base/io-network.md index 9c0cf81..377ee41 100644 --- a/src/base/io-network.md +++ b/src/base/io-network.md @@ -55,7 +55,6 @@ Base.IOContext(::IO, ::IOContext) ```@docs Base.show(::Any) -Base.showcompact Base.summary Base.print Base.println diff --git a/src/base/strings.md b/src/base/strings.md index d71e7ef..816f607 100644 --- a/src/base/strings.md +++ b/src/base/strings.md @@ -1,13 +1,16 @@ # [Strings](@id lib-strings) ```@docs +Core.AbstractChar +Core.Char +Base.codepoint Base.length(::AbstractString) Base.sizeof(::AbstractString) -Base.:*(::Union{Char, AbstractString}, ::Union{Char, AbstractString}...) +Base.:*(::Union{AbstractChar, AbstractString}, ::Union{AbstractChar, AbstractString}...) Base.:^(::AbstractString, ::Integer) Base.string Base.repeat(::AbstractString, ::Integer) -Base.repeat(::Char, ::Integer) +Base.repeat(::AbstractChar, ::Integer) Base.repr(::Any) Core.String(::AbstractString) Base.SubString diff --git a/src/manual/metaprogramming.md b/src/manual/metaprogramming.md index 901076c..14fa9c5 100644 --- a/src/manual/metaprogramming.md +++ b/src/manual/metaprogramming.md @@ -407,10 +407,10 @@ julia> eval(ex) The value of `a` is used to construct the expression `ex` which applies the `+` function to the value 1 and the variable `b`. Note the important distinction between the way `a` and `b` are used: - * The value of the *variable*`a` at expression construction time is used as an immediate value in + * The value of the *variable* `a` at expression construction time is used as an immediate value in the expression. Thus, the value of `a` when the expression is evaluated no longer matters: the value in the expression is already `1`, independent of whatever the value of `a` might be. - * On the other hand, the *symbol*`:b` is used in the expression construction, so the value of the + * On the other hand, the *symbol* `:b` is used in the expression construction, so the value of the variable `b` at that time is irrelevant -- `:b` is just a symbol and the variable `b` need not even be defined. At expression evaluation time, however, the value of the symbol `:b` is resolved by looking up the value of the variable `b`. diff --git a/src/manual/networking-and-streams.md b/src/manual/networking-and-streams.md index 4d75c59..51b6912 100644 --- a/src/manual/networking-and-streams.md +++ b/src/manual/networking-and-streams.md @@ -100,19 +100,23 @@ Note that `a` is written to [`stdout`](@ref) by the [`write`](@ref) function and value is `1` (since `0x61` is one byte). For text I/O, use the [`print`](@ref) or [`show`](@ref) methods, depending on your needs (see -the Julia Base reference for a detailed discussion of the difference between the two): +the documentation for these two methods for a detailed discussion of the difference between them): ```jldoctest julia> print(stdout, 0x61) 97 ``` +See [Custom pretty-printing](@ref man-custom-pretty-printing) for more information on how to +implement display methods for custom types. + ## IO Output Contextual Properties Sometimes IO output can benefit from the ability to pass contextual information into show methods. The [`IOContext`](@ref) object provides this framework for associating arbitrary metadata with an IO object. -For example, [`showcompact`](@ref) adds a hinting parameter to the IO object that the invoked show method -should print a shorter output (if applicable). +For example, `:compact => true` adds a hinting parameter to the IO object that the invoked show method +should print a shorter output (if applicable). See the [`IOContext`](@ref) documentation for a list +of common properties. ## Working with Files diff --git a/src/manual/strings.md b/src/manual/strings.md index 5002016..68c2ccf 100644 --- a/src/manual/strings.md +++ b/src/manual/strings.md @@ -28,9 +28,10 @@ There are a few noteworthy high-level features about Julia's strings: additional `AbstractString` subtypes (e.g. for other encodings). If you define a function expecting a string argument, you should declare the type as `AbstractString` in order to accept any string type. - * Like C and Java, but unlike most dynamic languages, Julia has a first-class type representing - a single character, called `Char`. This is just a special kind of 32-bit primitive type whose numeric - value represents a Unicode code point. + * Like C and Java, but unlike most dynamic languages, Julia has a first-class type for representing + a single character, called `AbstractChar`. The built-in `Char` subtype of `AbstractChar` + is a 32-bit primitive type that can represent any Unicode character (and which is based + on the UTF-8 encoding). * As in Java, strings are immutable: the value of an `AbstractString` object cannot be changed. To construct a different string value, you construct a new string from parts of other strings. * Conceptually, a string is a *partial function* from indices to characters: for some index values, @@ -41,9 +42,11 @@ There are a few noteworthy high-level features about Julia's strings: ## [Characters](@id man-characters) -A `Char` value represents a single character: it is just a 32-bit primitive type with a special literal -representation and appropriate arithmetic behaviors, whose numeric value is interpreted as a -[Unicode code point](https://en.wikipedia.org/wiki/Code_point). Here is how `Char` values are +An `Char` value represents a single character: it is just a 32-bit primitive type with a special literal +representation and appropriate arithmetic behaviors, and which can be converted +to a numeric value representing a +[Unicode code point](https://en.wikipedia.org/wiki/Code_point). (Julia packages may define + other subtypes of `AbstractChar`, e.g. to optimize operations for other [text encodings](https://en.wikipedia.org/wiki/Character_encoding).) Here is how `Char` values are input and shown: ```jldoctest @@ -428,7 +431,7 @@ julia> "v: $v" "v: [1, 2, 3]" ``` -[`string`](@ref) is the identity for `AbstractString` and `Char` values, so these are interpolated +[`string`](@ref) is the identity for `AbstractString` and `AbstractChar` values, so these are interpolated into strings as themselves, unquoted and unescaped: ```jldoctest diff --git a/src/manual/types.md b/src/manual/types.md index 3260b39..20c40c3 100644 --- a/src/manual/types.md +++ b/src/manual/types.md @@ -247,7 +247,7 @@ primitive type Float32 <: AbstractFloat 32 end primitive type Float64 <: AbstractFloat 64 end primitive type Bool <: Integer 8 end -primitive type Char 32 end +primitive type Char <: AbstractChar 32 end primitive type Int8 <: Signed 8 end primitive type UInt8 <: Unsigned 8 end @@ -1187,7 +1187,7 @@ Closest candidates are: supertype(!Matched::UnionAll) at operators.jl:47 ``` -## Custom pretty-printing +## [Custom pretty-printing](@id man-custom-pretty-printing) Often, one wants to customize how instances of a type are displayed. This is accomplished by overloading the [`show`](@ref) function. For example, suppose we define a type to represent @@ -1321,6 +1321,37 @@ julia> :($a == 2) :(3.0 * exp(4.0im) == 2) ``` +In some cases, it is useful to adjust the behavior of `show` methods depending +on the context. This can be achieved via the [`IOContext`](@ref) type, which allows +passing contextual properties together with a wrapped IO stream. +For example, we can build a shorter representation in our `show` method +when the `:compact` property is set to `true`, falling back to the long +representation if the property is `false` or absent: +```jldoctest polartype +julia> function Base.show(io::IO, z::Polar) + if get(io, :compact, false) + print(io, z.r, "ℯ", z.Θ, "im") + else + print(io, z.r, " * exp(", z.Θ, "im)") + end + end +``` + +This new compact representation will be used when the passed IO stream is an `IOContext` +object with the `:compact` property set. In particular, this is the case when printing +arrays with multiple columns (where horizontal space is limited): +```jldoctest polartype +julia> show(IOContext(stdout, :compact=>true), Polar(3, 4.0)) +3.0ℯ4.0im + +julia> [Polar(3, 4.0) Polar(4.0,5.3)] +1×2 Array{Polar{Float64},2}: + 3.0ℯ4.0im 4.0ℯ5.3im +``` + +See the [`IOContext`](@ref) documentation for a list of common properties which can be used +to adjust printing. + ## "Value types" In Julia, you can't dispatch on a *value* such as `true` or `false`. However, you can dispatch diff --git a/src/stdlib/DelimitedFiles.md b/src/stdlib/DelimitedFiles.md index 2a343d5..839bdb8 100644 --- a/src/stdlib/DelimitedFiles.md +++ b/src/stdlib/DelimitedFiles.md @@ -5,10 +5,10 @@ DocTestSetup = :(using DelimitedFiles) ``` ```@docs -DelimitedFiles.readdlm(::Any, ::Char, ::Type, ::Char) -DelimitedFiles.readdlm(::Any, ::Char, ::Char) -DelimitedFiles.readdlm(::Any, ::Char, ::Type) -DelimitedFiles.readdlm(::Any, ::Char) +DelimitedFiles.readdlm(::Any, ::AbstractChar, ::Type, ::AbstractChar) +DelimitedFiles.readdlm(::Any, ::AbstractChar, ::AbstractChar) +DelimitedFiles.readdlm(::Any, ::AbstractChar, ::Type) +DelimitedFiles.readdlm(::Any, ::AbstractChar) DelimitedFiles.readdlm(::Any, ::Type) DelimitedFiles.readdlm(::Any) DelimitedFiles.writedlm diff --git a/src/stdlib/SparseArrays.md b/src/stdlib/SparseArrays.md index afde15c..af1be79 100644 --- a/src/stdlib/SparseArrays.md +++ b/src/stdlib/SparseArrays.md @@ -211,7 +211,7 @@ SparseArrays.nnz SparseArrays.findnz SparseArrays.spzeros SparseArrays.spdiagm -SparseArrays.blkdiag +SparseArrays.blockdiag SparseArrays.sprand SparseArrays.sprandn SparseArrays.nonzeros diff --git a/src/stdlib/delimitedfiles.md b/src/stdlib/delimitedfiles.md index 2a343d5..839bdb8 100644 --- a/src/stdlib/delimitedfiles.md +++ b/src/stdlib/delimitedfiles.md @@ -5,10 +5,10 @@ DocTestSetup = :(using DelimitedFiles) ``` ```@docs -DelimitedFiles.readdlm(::Any, ::Char, ::Type, ::Char) -DelimitedFiles.readdlm(::Any, ::Char, ::Char) -DelimitedFiles.readdlm(::Any, ::Char, ::Type) -DelimitedFiles.readdlm(::Any, ::Char) +DelimitedFiles.readdlm(::Any, ::AbstractChar, ::Type, ::AbstractChar) +DelimitedFiles.readdlm(::Any, ::AbstractChar, ::AbstractChar) +DelimitedFiles.readdlm(::Any, ::AbstractChar, ::Type) +DelimitedFiles.readdlm(::Any, ::AbstractChar) DelimitedFiles.readdlm(::Any, ::Type) DelimitedFiles.readdlm(::Any) DelimitedFiles.writedlm diff --git a/src/stdlib/sparsearrays.md b/src/stdlib/sparsearrays.md index afde15c..af1be79 100644 --- a/src/stdlib/sparsearrays.md +++ b/src/stdlib/sparsearrays.md @@ -211,7 +211,7 @@ SparseArrays.nnz SparseArrays.findnz SparseArrays.spzeros SparseArrays.spdiagm -SparseArrays.blkdiag +SparseArrays.blockdiag SparseArrays.sprand SparseArrays.sprandn SparseArrays.nonzeros From db47b104360464b60cd7b39d53dc7fcdd95fcf25 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Thu, 15 Mar 2018 09:46:33 +0900 Subject: [PATCH 012/153] update Julia Commit 4be51b7bb9 --- .gitignore | 1 + codex/NEWS.md | 39 ++-- codex/base/arrays.md | 13 +- codex/base/base.md | 3 +- codex/base/collections.md | 4 +- codex/devdocs/offset-arrays.md | 4 +- codex/devdocs/reflection.md | 14 +- codex/index.md | 2 +- codex/manual/arrays.md | 32 +-- codex/manual/calling-c-and-fortran-code.md | 39 ++-- codex/manual/control-flow.md | 2 +- codex/manual/environment-variables.md | 6 +- codex/manual/getting-started.md | 2 +- codex/manual/index.md | 2 +- codex/manual/interfaces.md | 2 +- codex/manual/noteworthy-differences.md | 10 +- codex/manual/performance-tips.md | 8 +- codex/manual/style-guide.md | 10 +- codex/manual/types.md | 32 +-- codex/manual/unicode-input.md | 2 +- codex/manual/variables-and-scoping.md | 6 +- codex/stdlib/Pkg3.md | 224 +++++++++++++++++++++ make.jl | 2 +- src/NEWS.md | 45 +++-- src/base/arrays.md | 13 +- src/base/base.md | 3 +- src/base/collections.md | 4 +- src/devdocs/offset-arrays.md | 4 +- src/devdocs/reflection.md | 14 +- src/index.md | 2 +- src/manual/arrays.md | 32 ++- src/manual/calling-c-and-fortran-code.md | 39 ++-- src/manual/control-flow.md | 2 +- src/manual/environment-variables.md | 6 +- src/manual/getting-started.md | 2 +- src/manual/index.md | 2 +- src/manual/interfaces.md | 2 +- src/manual/noteworthy-differences.md | 10 +- src/manual/performance-tips.md | 8 +- src/manual/style-guide.md | 10 +- src/manual/types.md | 32 +-- src/manual/unicode-input.md | 2 +- src/manual/variables-and-scoping.md | 6 +- src/stdlib/Pkg3.md | 224 +++++++++++++++++++++ 44 files changed, 710 insertions(+), 211 deletions(-) create mode 100644 codex/stdlib/Pkg3.md create mode 100644 src/stdlib/Pkg3.md diff --git a/.gitignore b/.gitignore index 496827a..48021a8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ _build +_build_local deps .DS_Store diff --git a/codex/NEWS.md b/codex/NEWS.md index a2b5a81..43b4ba9 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -120,12 +120,12 @@ Language changes * `global const` declarations may no longer appear inside functions ([#12010](https://github.com/JuliaLang/julia/issues/12010)). * Uninitialized `BitArray` constructors of the form `BitArray[{N}](shape...)` have been - deprecated in favor of equivalents accepting `uninitialized` (an alias for - `Uninitialized()`) as their first argument, as in - `BitArray[{N}](uninitialized, shape...)`. For example, `BitVector(3)` is now - `BitVector(uninitialized, 3)`, `BitMatrix((2, 4))` is now - `BitMatrix(uninitialized, (2, 4))`, and `BitArray{3}(11, 13, 17)` is now - `BitArray{3}(uninitialized, 11, 14, 17)` ([#24785](https://github.com/JuliaLang/julia/issues/24785)). + deprecated in favor of equivalents accepting `undef` (an alias for + `UndefInitializer()`) as their first argument, as in + `BitArray[{N}](undef, shape...)`. For example, `BitVector(3)` is now + `BitVector(undef, 3)`, `BitMatrix((2, 4))` is now + `BitMatrix(undef, (2, 4))`, and `BitArray{3}(11, 13, 17)` is now + `BitArray{3}(undef, 11, 14, 17)` ([#24785](https://github.com/JuliaLang/julia/issues/24785)). * Dispatch rules have been simplified: method matching is now determined exclusively by subtyping; @@ -461,6 +461,11 @@ Library improvements * `Char` is now a subtype of `AbstractChar`, and most of the functions that take character arguments now accept any `AbstractChar` ([#26286](https://github.com/JuliaLang/julia/issues/26286)). + * `String(array)` now accepts an arbitrary `AbstractVector{UInt8}`. For `Vector` + inputs, it "steals" the memory buffer, leaving them with an empty buffer which + is guaranteed not to be shared with the `String` object. For other types of vectors + (in particular immutable vectors), a copy is made and the input is not truncated ([#26093](https://github.com/JuliaLang/julia/issues/26093)). + * `Irrational` is now a subtype of `AbstractIrrational` ([#24245](https://github.com/JuliaLang/julia/issues/24245)). * Introduced the `empty` function, the functional pair to `empty!` which returns a new, @@ -662,11 +667,11 @@ Deprecated or removed * Uninitialized `Array` constructors of the form `Array[{T,N}](shape...)` have been deprecated in favor of equivalents - accepting `uninitialized` (an alias for `Uninitialized()`) as their first argument, - as in `Array[{T,N}](uninitialized, shape...)`. For example, - `Vector(3)` is now `Vector(uninitialized, 3)`, `Matrix{Int}((2, 4))` is now, - `Matrix{Int}(uninitialized, (2, 4))`, and `Array{Float32,3}(11, 13, 17)` is now - `Array{Float32,3}(uninitialized, 11, 13, 17)` ([#24781](https://github.com/JuliaLang/julia/issues/24781)). + accepting `undef` (an alias for `UndefInitializer()`) as their first argument, + as in `Array[{T,N}](undef, shape...)`. For example, + `Vector(3)` is now `Vector(undef, 3)`, `Matrix{Int}((2, 4))` is now, + `Matrix{Int}(undef, (2, 4))`, and `Array{Float32,3}(11, 13, 17)` is now + `Array{Float32,3}(undef, 11, 13, 17)` ([#24781](https://github.com/JuliaLang/julia/issues/24781)). * `LinAlg.fillslots!` has been renamed `LinAlg.fillstored!` ([#25030](https://github.com/JuliaLang/julia/issues/25030)). @@ -692,11 +697,11 @@ Deprecated or removed output ([#12131](https://github.com/JuliaLang/julia/issues/12131)). * Uninitialized `RowVector` constructors of the form `RowVector{T}(shape...)` have been - deprecated in favor of equivalents accepting `uninitialized` (an alias for - `Uninitialized()`) as their first argument, as in - `RowVector{T}(uninitialized, shape...)`. For example, `RowVector{Int}(3)` is now - `RowVector{Int}(uninitialized, 3)`, and `RowVector{Float32}((1, 4))` is now - `RowVector{Float32}(uninitialized, (1, 4))` ([#24786](https://github.com/JuliaLang/julia/issues/24786)). + deprecated in favor of equivalents accepting `undef` (an alias for + `UndefInitializer()`) as their first argument, as in + `RowVector{T}(undef, shape...)`. For example, `RowVector{Int}(3)` is now + `RowVector{Int}(undef, 3)`, and `RowVector{Float32}((1, 4))` is now + `RowVector{Float32}(undef, (1, 4))` ([#24786](https://github.com/JuliaLang/julia/issues/24786)). * `writecsv(io, a; opts...)` has been deprecated in favor of `writedlm(io, a, ','; opts...)` ([#23529](https://github.com/JuliaLang/julia/issues/23529)). @@ -759,7 +764,7 @@ Deprecated or removed in favor of `replace(s::AbstractString, pat => r; [count])` ([#25165](https://github.com/JuliaLang/julia/issues/25165)). Moreover, `count` cannot be negative anymore (use `typemax(Int)` instead ([#22325](https://github.com/JuliaLang/julia/issues/22325)). - * `read(io, type, dims)` is deprecated to `read!(io, Array{type}(uninitialized, dims))` ([#21450](https://github.com/JuliaLang/julia/issues/21450)). + * `read(io, type, dims)` is deprecated to `read!(io, Array{type}(undef, dims))` ([#21450](https://github.com/JuliaLang/julia/issues/21450)). * `read(::IO, ::Ref)` is now a method of `read!`, since it mutates its `Ref` argument ([#21592](https://github.com/JuliaLang/julia/issues/21592)). diff --git a/codex/base/arrays.md b/codex/base/arrays.md index 11b3c6d..4c011a1 100644 --- a/codex/base/arrays.md +++ b/codex/base/arrays.md @@ -7,24 +7,24 @@ Core.AbstractArray Base.AbstractVector Base.AbstractMatrix Core.Array -Core.Array(::Uninitialized, ::Any) +Core.Array(::UndefInitializer, ::Any) Core.Array(::Nothing, ::Any) Core.Array(::Missing, ::Any) -Core.Uninitialized -Core.uninitialized +Core.UndefInitializer +Core.undef Base.Vector -Base.Vector(::Uninitialized, ::Any) +Base.Vector(::UndefInitializer, ::Any) Base.Vector(::Nothing, ::Any) Base.Vector(::Missing, ::Any) Base.Matrix -Base.Matrix(::Uninitialized, ::Any, ::Any) +Base.Matrix(::UndefInitializer, ::Any, ::Any) Base.Matrix(::Nothing, ::Any, ::Any) Base.Matrix(::Missing, ::Any, ::Any) Base.getindex(::Type, ::Any...) Base.zeros Base.ones Base.BitArray -Base.BitArray(::Uninitialized, ::Integer...) +Base.BitArray(::UndefInitializer, ::Integer...) Base.BitArray(::Any) Base.trues Base.falses @@ -115,7 +115,6 @@ Base.vcat Base.hcat Base.hvcat Base.vect -Base.flipdim Base.circshift Base.circshift! Base.circcopy! diff --git a/codex/base/base.md b/codex/base/base.md index 2c1db70..e62e4c0 100644 --- a/codex/base/base.md +++ b/codex/base/base.md @@ -245,7 +245,6 @@ Base.withenv Base.pipeline(::Any, ::Any, ::Any, ::Any...) Base.pipeline(::Base.AbstractCmd) Base.Libc.gethostname -Base.getipaddr Base.Libc.getpid Base.Libc.time() Base.time_ns @@ -291,7 +290,6 @@ Base.MissingException Core.OutOfMemoryError Core.ReadOnlyMemoryError Core.OverflowError -Base.ParseError Core.StackOverflowError Base.SystemError Core.TypeError @@ -336,6 +334,7 @@ Meta.lower Meta.@lower Meta.parse(::AbstractString, ::Int) Meta.parse(::AbstractString) +Meta.ParseError Base.macroexpand Base.@macroexpand Base.@macroexpand1 diff --git a/codex/base/collections.md b/codex/base/collections.md index cdc77c2..0e2c58a 100644 --- a/codex/base/collections.md +++ b/codex/base/collections.md @@ -203,8 +203,8 @@ Base.keys Base.values Base.pairs Base.merge -Base.merge!(::Associative, ::Associative...) -Base.merge!(::Function, ::Associative, ::Associative...) +Base.merge!(::AbstractDict, ::AbstractDict...) +Base.merge!(::Function, ::AbstractDict, ::AbstractDict...) Base.sizehint! Base.keytype Base.valtype diff --git a/codex/devdocs/offset-arrays.md b/codex/devdocs/offset-arrays.md index 5288f30..b5a1552 100644 --- a/codex/devdocs/offset-arrays.md +++ b/codex/devdocs/offset-arrays.md @@ -97,7 +97,7 @@ end ### Allocating storage using generalizations of `similar` -Storage is often allocated with `Array{Int}(uninitialized, dims)` or `similar(A, args...)`. When the result needs +Storage is often allocated with `Array{Int}(undef, dims)` or `similar(A, args...)`. When the result needs to match the indices of some other array, this may not always suffice. The generic replacement for such patterns is to use `similar(storagetype, shape)`. `storagetype` indicates the kind of underlying "conventional" behavior you'd like, e.g., `Array{Int}` or `BitArray` or even `dims->zeros(Float32, dims)` @@ -109,7 +109,7 @@ Let's walk through a couple of explicit examples. First, if `A` has conventional `similar(Array{Int}, axes(A))` would end up calling `Array{Int}(size(A))`, and thus return an array. If `A` is an `AbstractArray` type with unconventional indexing, then `similar(Array{Int}, axes(A))` should return something that "behaves like" an `Array{Int}` but with a shape (including indices) -that matches `A`. (The most obvious implementation is to allocate an `Array{Int}(uninitialized, size(A))` and +that matches `A`. (The most obvious implementation is to allocate an `Array{Int}(undef, size(A))` and then "wrap" it in a type that shifts the indices.) Note also that `similar(Array{Int}, (axes(A, 2),))` would allocate an `AbstractVector{Int}` diff --git a/codex/devdocs/reflection.md b/codex/devdocs/reflection.md index 23ff13b..f8af9b6 100644 --- a/codex/devdocs/reflection.md +++ b/codex/devdocs/reflection.md @@ -113,14 +113,13 @@ julia> Meta.lower(@__MODULE__, :(f() = 1) ) Inspecting the lowered form for functions requires selection of the specific method to display, because generic functions may have many methods with different type signatures. For this purpose, -method-specific code-lowering is available using [`code_lowered(f::Function, (Argtypes...))`](@ref), -and the type-inferred form is available using [`code_typed(f::Function, (Argtypes...))`](@ref). -[`code_warntype(f::Function, (Argtypes...))`](@ref) adds highlighting to the output of [`code_typed`](@ref) -(see [`@code_warntype`](@ref)). +method-specific code-lowering is available using [`code_lowered`](@ref), +and the type-inferred form is available using [`code_typed`](@ref). +[`code_warntype`](@ref) adds highlighting to the output of [`code_typed`](@ref). Closer to the machine, the LLVM intermediate representation of a function may be printed using -by [`code_llvm(f::Function, (Argtypes...))`](@ref), and finally the compiled machine code is available -using [`code_native(f::Function, (Argtypes...))`](@ref) (this will trigger JIT compilation/code +by [`code_llvm`](@ref), and finally the compiled machine code is available +using [`code_native`](@ref) (this will trigger JIT compilation/code generation for any function which has not previously been called). For convenience, there are macro versions of the above functions which take standard function @@ -137,4 +136,5 @@ top: } ``` -(likewise `@code_typed`, `@code_warntype`, `@code_lowered`, and `@code_native`) +See [`@code_lowered`](@ref), [`@code_typed`](@ref), [`@code_warntype`](@ref), +[`@code_llvm`](@ref), and [`@code_native`](@ref). diff --git a/codex/index.md b/codex/index.md index dba35ba..6ebcfec 100644 --- a/codex/index.md +++ b/codex/index.md @@ -12,7 +12,7 @@ Please read the [release notes](NEWS.md) to see what has changed since the last ## Manual * [Introduction](@ref man-introduction) - * [Getting Started](@ref) + * [Getting Started](@ref man-getting-started) * [Variables](@ref) * [Integers and Floating-Point Numbers](@ref) * [Mathematical Operations and Elementary Functions](@ref) diff --git a/codex/manual/arrays.md b/codex/manual/arrays.md index 28f2c51..2492125 100644 --- a/codex/manual/arrays.md +++ b/codex/manual/arrays.md @@ -17,11 +17,17 @@ be written in a vectorized style for performance. Julia's compiler uses type inf optimized code for scalar array indexing, allowing programs to be written in a style that is convenient and readable, without sacrificing performance, and using less memory at times. -In Julia, all arguments to functions are passed by reference. Some technical computing languages -pass arrays by value, and this is convenient in many cases. In Julia, modifications made to input -arrays within a function will be visible in the parent function. The entire Julia array library -ensures that inputs are not modified by library functions. User code, if it needs to exhibit similar -behavior, should take care to create a copy of inputs that it may modify. +In Julia, all arguments to functions are [passed by +sharing](https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing) +(i.e. by pointers). Some technical computing languages pass arrays by value, and +while this prevents accidental modification by callees of a value in the caller, +it makes avoiding unwanted copying of arrays difficult. By convention, a +function name ending with a `!` indicates that it will mutate or destroy the +value of one or more of its arguments. Callees must make explicit copies to +ensure that they don't modify inputs that they don't intend to change. Many non- +mutating functions are implemented by calling a function of the same name with +an added `!` at the end on an explicit copy of the input, and returning that +copy. ## Arrays @@ -50,7 +56,7 @@ omitted it will default to [`Float64`](@ref). | Function | Description | |:---------------------------------- |:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [`Array{T}(uninitialized, dims...)`](@ref) | an uninitialized dense [`Array`](@ref) | +| [`Array{T}(undef, dims...)`](@ref) | an uninitialized dense [`Array`](@ref) | | [`zeros(T, dims...)`](@ref) | an `Array` of all zeros | | [`ones(T, dims...)`](@ref) | an `Array` of all ones | | [`trues(dims...)`](@ref) | a [`BitArray`](@ref) with all values `true` | @@ -705,12 +711,14 @@ Very few operations are implemented specifically for `Array` beyond those that a for all `AbstractArrays`s; much of the array library is implemented in a generic manner that allows all custom arrays to behave similarly. -`SubArray` is a specialization of `AbstractArray` that performs indexing by reference rather than -by copying. A `SubArray` is created with the [`view`](@ref) function, which is called the same -way as [`getindex`](@ref) (with an array and a series of index arguments). The result of [`view`](@ref) -looks the same as the result of [`getindex`](@ref), except the data is left in place. [`view`](@ref) -stores the input index vectors in a `SubArray` object, which can later be used to index the original -array indirectly. By putting the [`@views`](@ref) macro in front of an expression or +`SubArray` is a specialization of `AbstractArray` that performs indexing by +sharing memory with the original array rather than by copying it. A `SubArray` +is created with the [`view`](@ref) function, which is called the same way as +[`getindex`](@ref) (with an array and a series of index arguments). The result +of [`view`](@ref) looks the same as the result of [`getindex`](@ref), except the +data is left in place. [`view`](@ref) stores the input index vectors in a +`SubArray` object, which can later be used to index the original array +indirectly. By putting the [`@views`](@ref) macro in front of an expression or block of code, any `array[...]` slice in that expression will be converted to create a `SubArray` view instead. diff --git a/codex/manual/calling-c-and-fortran-code.md b/codex/manual/calling-c-and-fortran-code.md index a717d71..07d7f2f 100644 --- a/codex/manual/calling-c-and-fortran-code.md +++ b/codex/manual/calling-c-and-fortran-code.md @@ -26,11 +26,16 @@ A function name may be used alone in place of the tuple (just `:function` or `"f this case the name is resolved within the current process. This form can be used to call C library functions, functions in the Julia runtime, or functions in an application linked to Julia. -By default, Fortran compilers [generate mangled names](https://en.wikipedia.org/wiki/Name_mangling#Fortran) -(for example, converting function names to lowercase or uppercase, often appending an underscore), -and so to call a Fortran function via [`ccall`](@ref) you must pass the mangled identifier corresponding -to the rule followed by your Fortran compiler. Also, when calling a Fortran function, all inputs -must be passed by reference. +By default, Fortran compilers [generate mangled +names](https://en.wikipedia.org/wiki/Name_mangling#Fortran) (for example, +converting function names to lowercase or uppercase, often appending an +underscore), and so to call a Fortran function via [`ccall`](@ref) you must pass +the mangled identifier corresponding to the rule followed by your Fortran +compiler. Also, when calling a Fortran function, all inputs must be passed as +pointers to allocated values on the heap or stack. This applies not only to +arrays and other mutable objects which are normally heap-allocated, but also to +scalar values such as integers and floats which are normally stack-allocated and +commonly passed in registers when using C or Julia calling conventions. Finally, you can use [`ccall`](@ref) to actually generate a call to the library function. Arguments to [`ccall`](@ref) are as follows: @@ -385,8 +390,9 @@ checks and is only meant to improve readability of the call. | `wchar_t` | `Cwchar_t` | `Int32` (UNIX), `UInt16` (Windows) | !!! note - When calling a Fortran function, all inputs must be passed by reference, so all type correspondences - above should contain an additional `Ptr{..}` or `Ref{..}` wrapper around their type specification. + When calling Fortran, all inputs must be passed by pointers to heap- or stack-allocated + values, so all type correspondences above should contain an additional `Ptr{..}` or + `Ref{..}` wrapper around their type specification. !!! warning For string arguments (`char*`) the Julia type should be `Cstring` (if NUL- terminated data is @@ -590,9 +596,10 @@ of pointers to memory managed by either Julia or C through the implicit call to structs should be represented as fields of type `Ptr{T}` within the corresponding Julia struct types designed to mimic the internal structure of corresponding C structs. -In Julia code wrapping calls to external Fortran routines, all input arguments should be declared -as of type `Ref{T}`, as Fortran passes all variables by reference. The return type should either -be `Cvoid` for Fortran subroutines, or a `T` for Fortran functions returning the type `T`. +In Julia code wrapping calls to external Fortran routines, all input arguments +should be declared as of type `Ref{T}`, as Fortran passes all variables by +pointers to memory locations. The return type should either be `Cvoid` for +Fortran subroutines, or a `T` for Fortran functions returning the type `T`. ## Mapping C Functions to Julia @@ -763,11 +770,13 @@ that has no internal fields and whose sole purpose is to be placed in the type p `Ptr` type. The return type of the [`ccall`](@ref) is declared as `Ptr{gsl_permutation}`, since the memory allocated and pointed to by `output_ptr` is controlled by C (and not Julia). -The input `n` is passed by value, and so the function's input signature is simply declared as -`(Csize_t,)` without any `Ref` or `Ptr` necessary. (If the wrapper was calling a Fortran function -instead, the corresponding function input signature should instead be `(Ref{Csize_t},)`, since -Fortran variables are passed by reference.) Furthermore, `n` can be any type that is convertable -to a `Csize_t` integer; the [`ccall`](@ref) implicitly calls [`Base.cconvert(Csize_t, n)`](@ref). +The input `n` is passed by value, and so the function's input signature is +simply declared as `(Csize_t,)` without any `Ref` or `Ptr` necessary. (If the +wrapper was calling a Fortran function instead, the corresponding function input +signature should instead be `(Ref{Csize_t},)`, since Fortran variables are +passed by pointers.) Furthermore, `n` can be any type that is convertable to a +`Csize_t` integer; the [`ccall`](@ref) implicitly calls [`Base.cconvert(Csize_t, +n)`](@ref). Here is a second example wrapping the corresponding destructor: diff --git a/codex/manual/control-flow.md b/codex/manual/control-flow.md index 5d38a7f..458789a 100644 --- a/codex/manual/control-flow.md +++ b/codex/manual/control-flow.md @@ -561,7 +561,7 @@ below all interrupt the normal flow of control. | [`RemoteException`](@ref) | | [`MethodError`](@ref) | | [`OverflowError`](@ref) | -| [`ParseError`](@ref) | +| [`Meta.ParseError`](@ref) | | [`SystemError`](@ref) | | [`TypeError`](@ref) | | [`UndefRefError`](@ref) | diff --git a/codex/manual/environment-variables.md b/codex/manual/environment-variables.md index 28dbf15..513b75c 100644 --- a/codex/manual/environment-variables.md +++ b/codex/manual/environment-variables.md @@ -97,7 +97,7 @@ respect to the working directory. If `$JULIA_PKGDIR` is not set, then $HOME/.julia ``` -Then the repository location [`Pkg.dir`](@ref) for a given Julia version is +Then the repository location `Pkg.dir` for a given Julia version is ``` $JULIA_PKGDIR/v$(VERSION.major).$(VERSION.minor) @@ -128,7 +128,7 @@ $HOME/.julia_history ### `JULIA_PKGRESOLVE_ACCURACY` A positive `Int` that determines how much time the max-sum subroutine -`MaxSum.maxsum()` of the package dependency resolver [`Base.Pkg.resolve`](@ref) +`MaxSum.maxsum()` of the package dependency resolver `Pkg.resolve` will devote to attempting satisfying constraints before giving up: this value is by default `1`, and larger values correspond to larger amounts of time. @@ -164,7 +164,7 @@ exists, or `emacs` otherwise. !!! note `$JULIA_EDITOR` is *not* used in the determination of the editor for - [`Base.Pkg.edit`](@ref): this function checks `$VISUAL` and `$EDITOR` alone. + `Pkg.edit`: this function checks `$VISUAL` and `$EDITOR` alone. ## Parallelization diff --git a/codex/manual/getting-started.md b/codex/manual/getting-started.md index 6de2c96..e995f84 100644 --- a/codex/manual/getting-started.md +++ b/codex/manual/getting-started.md @@ -1,4 +1,4 @@ -# Getting Started +# [Getting Started](@id man-getting-started) Julia installation is straightforward, whether using precompiled binaries or compiling from source. Download and install Julia by following the instructions at [https://julialang.org/downloads/](https://julialang.org/downloads/). diff --git a/codex/manual/index.md b/codex/manual/index.md index 148d5e0..5f79a98 100644 --- a/codex/manual/index.md +++ b/codex/manual/index.md @@ -1,7 +1,7 @@ # The Julia Manual * [Introduction](@ref man-introduction) - * [Getting Started](@ref) + * [Getting Started](@ref man-getting-started) * [Variables](@ref) * [Integers and Floating-Point Numbers](@ref) * [Mathematical Operations and Elementary Functions](@ref) diff --git a/codex/manual/interfaces.md b/codex/manual/interfaces.md index 2349da9..9a6b064 100644 --- a/codex/manual/interfaces.md +++ b/codex/manual/interfaces.md @@ -235,7 +235,7 @@ ourselves, we can officially define it as a subtype of an [`AbstractArray`](@ref | `similar(A)` | `similar(A, eltype(A), size(A))` | Return a mutable array with the same shape and element type | | `similar(A, ::Type{S})` | `similar(A, S, size(A))` | Return a mutable array with the same shape and the specified element type | | `similar(A, dims::NTuple{Int})` | `similar(A, eltype(A), dims)` | Return a mutable array with the same element type and size *dims* | -| `similar(A, ::Type{S}, dims::NTuple{Int})` | `Array{S}(uninitialized, dims)` | Return a mutable array with the specified element type and size | +| `similar(A, ::Type{S}, dims::NTuple{Int})` | `Array{S}(undef, dims)` | Return a mutable array with the specified element type and size | | **Non-traditional indices** | **Default definition** | **Brief description** | | `axes(A)` | `map(OneTo, size(A))` | Return the `AbstractUnitRange` of valid indices | | `Base.similar(A, ::Type{S}, inds::NTuple{Ind})` | `similar(A, S, Base.to_shape(inds))` | Return a mutable array with the specified indices `inds` (see below) | diff --git a/codex/manual/noteworthy-differences.md b/codex/manual/noteworthy-differences.md index dd0a8c1..c87b30c 100644 --- a/codex/manual/noteworthy-differences.md +++ b/codex/manual/noteworthy-differences.md @@ -7,9 +7,9 @@ major syntactic and functional differences. The following are some noteworthy di may trip up Julia users accustomed to MATLAB: * Julia arrays are indexed with square brackets, `A[i,j]`. - * Julia arrays are assigned by reference. After `A=B`, changing elements of `B` will modify `A` + * Julia arrays are not copied when assigned to another variable. After `A = B`, changing elements of `B` will modify `A` as well. - * Julia values are passed and assigned by reference. If a function modifies an array, the changes + * Julia values are not copied when passed to a function. If a function modifies an array, the changes will be visible in the caller. * Julia does not automatically grow arrays in an assignment statement. Whereas in MATLAB `a(4) = 3.2` can create the array `a = [0 0 0 3.2]` and `a(5) = 7` can grow it into `a = [0 0 0 3.2 7]`, the @@ -153,7 +153,7 @@ For users coming to Julia from R, these are some noteworthy differences: * Julia encourages users to write their own types, which are easier to use than S3 or S4 objects in R. Julia's multiple dispatch system means that `table(x::TypeA)` and `table(x::TypeB)` act like R's `table.TypeA(x)` and `table.TypeB(x)`. - * In Julia, values are passed and assigned by reference. If a function modifies an array, the changes + * In Julia, values are not copied when assigned or passed to a function. If a function modifies an array, the changes will be visible in the caller. This is very different from R and allows new functions to operate on large data structures much more efficiently. * In Julia, vectors and matrices are concatenated using [`hcat`](@ref), [`vcat`](@ref) and @@ -227,13 +227,13 @@ For users coming to Julia from R, these are some noteworthy differences: This syntax is not just syntactic sugar for a reference to a pointer or address as in C/C++. See the Julia documentation for the syntax for array construction (it has changed between versions). * In Julia, indexing of arrays, strings, etc. is 1-based not 0-based. - * Julia arrays are assigned by reference. After `A=B`, changing elements of `B` will modify `A` + * Julia arrays are not copied when assigned to another variable. After `A = B`, changing elements of `B` will modify `A` as well. Updating operators like `+=` do not operate in-place, they are equivalent to `A = A + B` which rebinds the left-hand side to the result of the right-hand side expression. * Julia arrays are column major (Fortran ordered) whereas C/C++ arrays are row major ordered by default. To get optimal performance when looping over arrays, the order of the loops should be reversed in Julia relative to C/C++ (see relevant section of [Performance Tips](@ref man-performance-tips)). - * Julia values are passed and assigned by reference. If a function modifies an array, the changes + * Julia values are not copied when assigned or passed to a function. If a function modifies an array, the changes will be visible in the caller. * In Julia, whitespace is significant, unlike C/C++, so care must be taken when adding/removing whitespace from a Julia program. diff --git a/codex/manual/performance-tips.md b/codex/manual/performance-tips.md index 84dd79c..bcd5abe 100644 --- a/codex/manual/performance-tips.md +++ b/codex/manual/performance-tips.md @@ -618,7 +618,7 @@ end ```jldoctest julia> function strange_twos(n) - a = Vector{rand(Bool) ? Int64 : Float64}(uninitialized, n) + a = Vector{rand(Bool) ? Int64 : Float64}(undef, n) for i = 1:n a[i] = 2 end @@ -644,7 +644,7 @@ julia> function fill_twos!(a) fill_twos! (generic function with 1 method) julia> function strange_twos(n) - a = Vector{rand(Bool) ? Int64 : Float64}(uninitialized, n) + a = Vector{rand(Bool) ? Int64 : Float64}(undef, n) fill_twos!(a) return a end @@ -931,7 +931,7 @@ function xinc!(ret::AbstractVector{T}, x::T) where T end function loopinc_prealloc() - ret = Vector{Int}(uninitialized, 3) + ret = Vector{Int}(undef, 3) y = 0 for i = 1:10^7 xinc!(ret, i) @@ -1282,7 +1282,7 @@ end function main() n = 2000 - u = Vector{Float64}(uninitialized, n) + u = Vector{Float64}(undef, n) init!(u) du = similar(u) diff --git a/codex/manual/style-guide.md b/codex/manual/style-guide.md index a62f853..10355e4 100644 --- a/codex/manual/style-guide.md +++ b/codex/manual/style-guide.md @@ -145,10 +145,10 @@ some alternatives to consider: It is usually not much help to construct arrays like the following: ```julia -a = Vector{Union{Int,AbstractString,Tuple,Array}}(uninitialized, n) +a = Vector{Union{Int,AbstractString,Tuple,Array}}(undef, n) ``` -In this case `Vector{Any}(uninitialized, n)` is better. It is also more helpful to the compiler to annotate specific +In this case `Vector{Any}(undef, n)` is better. It is also more helpful to the compiler to annotate specific uses (e.g. `a[i]::Int`) than to try to pack many alternatives into one type. ## Use naming conventions consistent with Julia's `base/` @@ -204,9 +204,9 @@ as applicable: 9. **Varargs**. This refers to arguments that can be listed indefinitely at the end of a function call. - For example, in `Matrix{T}(uninitialized, dims)`, the dimensions can be given as a - [`Tuple`](@ref), e.g. `Matrix{T}(uninitialized, (1,2))`, or as [`Vararg`](@ref)s, - e.g. `Matrix{T}(uninitialized, 1, 2)`. + For example, in `Matrix{T}(undef, dims)`, the dimensions can be given as a + [`Tuple`](@ref), e.g. `Matrix{T}(undef, (1,2))`, or as [`Vararg`](@ref)s, + e.g. `Matrix{T}(undef, 1, 2)`. 10. **Keyword arguments**. In Julia keyword arguments have to come last anyway in function definitions; they're diff --git a/codex/manual/types.md b/codex/manual/types.md index 20c40c3..1a7d849 100644 --- a/codex/manual/types.md +++ b/codex/manual/types.md @@ -372,8 +372,8 @@ julia> foo.qux Composite objects declared with `struct` are *immutable*; they cannot be modified after construction. This may seem odd at first, but it has several advantages: - * It can be more efficient. Some structs can be packed efficiently into arrays, and in some cases the - compiler is able to avoid allocating immutable objects entirely. + * It can be more efficient. Some structs can be packed efficiently into arrays, and + in some cases the compiler is able to avoid allocating immutable objects entirely. * It is not possible to violate the invariants provided by the type's constructors. * Code using immutable objects can be easier to reason about. @@ -433,18 +433,22 @@ over time. If they would be considered identical, the type should probably be im To recap, two essential properties define immutability in Julia: - * An object with an immutable type is passed around (both in assignment statements and in function - calls) by copying, whereas a mutable type is passed around by reference. - * It is not permitted to modify the fields of a composite immutable type. - -It is instructive, particularly for readers whose background is C/C++, to consider why these two -properties go hand in hand. If they were separated, i.e., if the fields of objects passed around -by copying could be modified, then it would become more difficult to reason about certain instances -of generic code. For example, suppose `x` is a function argument of an abstract type, and suppose -that the function changes a field: `x.isprocessed = true`. Depending on whether `x` is passed -by copying or by reference, this statement may or may not alter the actual argument in the calling -routine. Julia sidesteps the possibility of creating functions with unknown effects in this scenario -by forbidding modification of fields of objects passed around by copying. + * It is not permitted to modify the value of an immutable type. + * For bits types this means that the bit pattern of a value once set will never change + and that value is the identity of a bits type. + * For composite types, this means that the identity of the values of its fields will + never change. When the fields are bits types, that means their bits will never change, + for fields whose values are mutable types like arrays, that means the fields will + always refer to the same mutable value even though that mutable value's content may + itself be modified. + * An object with an immutable type may be copied freely by the compiler since its + immutabity makes it impossible to programmatically distinguish between the original + object and a copy. + * In particular, this means that small enough immutable values like integers and floats + are typically passed to functions in registers (or stack allocated). + * Mutable values, on the other hand are heap-allocated and passed to + functions as pointers to heap-allocated values except in cases where the compiler + is sure that there's no way to tell that this is not what is happening. ## Declared Types diff --git a/codex/manual/unicode-input.md b/codex/manual/unicode-input.md index e7dd653..5ed935a 100644 --- a/codex/manual/unicode-input.md +++ b/codex/manual/unicode-input.md @@ -19,7 +19,7 @@ the symbol). # # Generate a table containing all LaTeX and Emoji tab completions available in the REPL. # -import REPL +import REPL, Markdown const NBSP = '\u00A0' function tab_completions(symbols...) diff --git a/codex/manual/variables-and-scoping.md b/codex/manual/variables-and-scoping.md index 088aafd..38ac858 100644 --- a/codex/manual/variables-and-scoping.md +++ b/codex/manual/variables-and-scoping.md @@ -359,7 +359,7 @@ something like `let x = x` since the two `x` variables are distinct and have sep Here is an example where the behavior of `let` is needed: ```jldoctest -julia> Fs = Vector{Any}(uninitialized, 2); i = 1; +julia> Fs = Vector{Any}(undef, 2); i = 1; julia> while i <= 2 Fs[i] = ()->i @@ -378,7 +378,7 @@ variable `i`, so the two closures behave identically. We can use `let` to create for `i`: ```jldoctest -julia> Fs = Vector{Any}(uninitialized, 2); i = 1; +julia> Fs = Vector{Any}(undef, 2); i = 1; julia> while i <= 2 let i = i @@ -418,7 +418,7 @@ introduced in their body scopes are freshly allocated for each loop iteration, a were surrounded by a `let` block: ```jldoctest -julia> Fs = Vector{Any}(uninitialized, 2); +julia> Fs = Vector{Any}(undef, 2); julia> for j = 1:2 Fs[j] = ()->j diff --git a/codex/stdlib/Pkg3.md b/codex/stdlib/Pkg3.md new file mode 100644 index 0000000..b54bddc --- /dev/null +++ b/codex/stdlib/Pkg3.md @@ -0,0 +1,224 @@ +# Pkg3.jl + +!!! warning + This documentation is a work in progress and the information in it might be or become outdated. + +Sections: + +```@contents +Pages = [ + "index.md"] +``` + +## Introduction + +Pkg3 is the package manager for Julia. + +## Getting Started + +The Pkg REPL-mode is entered using from the Julia REPL using the key `]`. +To return to the `julia>` prompt, either press backspace when the input line is empty or press Ctrl+C. +Help is available by calling `pkg> help`. + +To generate files for a new project, use `pkg> generate`. + +``` +pkg> generate HelloWorld +``` + +This creates a new project `HelloWorld` with the following files + +```jl +julia> cd("HelloWorld") +shell> tree . +. +├── Project.toml +└── src + └── HelloWorld.jl + +1 directory, 2 files +``` + +The `Project.toml` file contains the name of the package, its unique UUID, its version, the author and eventual dependencies: + +```toml +name = "HelloWorld" +uuid = "b4cd1eb8-1e24-11e8-3319-93036a3eb9f3" +version = "0.1.0" +author = ["Some One "] + +[deps] +``` + +The content of `src/HelloWorld.jl` is: + +```jl +module HelloWorld + +greet() = print("Hello World!") + +end # module +``` + +We can now load the project and use it: + +```jl +julia> import HelloWorld + +julia> HelloWorld.greet() +Hello World! +``` + +### Adding packages to the project + +Let's say we want to use the standard library package `Random` and the registered package `JSON` in our project. +We simply `add` these packages: + +``` +pkg> add Random JSON + Resolving package versions... + Updating "~/Documents/HelloWorld/Project.toml" + [682c06a0] + JSON v0.17.1 + [9a3f8284] + Random + Updating "~/Documents/HelloWorld/Manifest.toml" + [34da2185] + Compat v0.57.0 + [682c06a0] + JSON v0.17.1 + [4d1e1d77] + Nullables v0.0.4 + ... +``` + +Both `Random` and `JSON` got added to the project's `Project.toml` file, and the resulting dependencies got added to the `Manifest.toml` file. +The resolver has installed each package with the highest possible version, while still respecting the compatibility that each package enforce on its dependencies. + +We can now use both `Random` and `JSON` in our project. Changing `src/HelloWorld.jl` to + +``` +module HelloWorld + +import Random +import JSON + +greet() = print("Hello World!") +greet_alien() = print("Hello ", Random.randstring(8)) + +end # module +``` + +and reloading the package, the new `greet_alien` function that uses `Random` can be used: + +``` +julia> HelloWorld.greet_alien() +Hello aT157rHV +``` + +Sometimes we might want to use the very latest, unreleased version of a package, or perhaps a specific branch in the package +git repository. We can use e.g. the `master` branch of `JSON` by specifying the branch after a `#` when adding the package: + +``` +pkg> add JSON#master + Cloning package from https://github.com/JuliaIO/JSON.jl.git + Resolving package versions... + Updating "~/Documents/HelloWorld/Project.toml" + [682c06a0] ~ JSON v0.17.1 ⇒ v0.17.1+ #master + Updating "~/Documents/HelloWorld/Manifest.toml" + [682c06a0] ~ JSON v0.17.1 ⇒ v0.17.1+ #master +``` + +If we want to use a package that has not been registered in a registry, we can `add` its git repository url: + +``` +pkg> add https://github.com/fredrikekre/ImportMacros.jl + Cloning package from https://github.com/fredrikekre/ImportMacros.jl + Resolving package versions... +Downloaded MacroTools ─ v0.4.0 + Updating "~/Documents/HelloWorld/Project.toml" + [5adcef86] + ImportMacros v0.1.0 #master + Updating "~/Documents/HelloWorld/Manifest.toml" + [5adcef86] + ImportMacros v0.1.0 #master + [1914dd2f] + MacroTools v0.4.0 +``` + +The dependencies of the unregistered package (here `MacroTools`) got installed. +For unregistered packages we could have given a branch (or commit SHA) to track using `#`, just like for registered packages. + +## Developing packages + +Let's say we found a bug in `JSON` that we want to fix. We can get the full git-repo using the `develop` command + +``` +pkg> develop JSON + Cloning package from https://github.com/JuliaIO/JSON.jl.git + Resolving package versions... + Updating "~/.julia/environments/v0.7/Project.toml" + [682c06a0] + JSON v0.17.1+ [~/.julia/dev/JSON] +... +``` + +By default, the package get cloned to the `~/.julia/dev` folder but can also be set by the `JULIA_PKG_DEVDIR` environment variable. +When we have fixed the bug and checked that `JSON` now works correctly with out project, we can make a PR to the `JSON` repository. +When a new release of `JSON` is made, we can go back to using the versioned `JSON` using the command `free` and `update` (see next section): + +``` +pkg> free JSON + Resolving package versions... + Updating "~/Documents/HelloWorld/Project.toml" + [682c06a0] ~ JSON v0.17.1+ #master ⇒ v0.17.1 + Updating "~/Documents/HelloWorld/Manifest.toml" + [682c06a0] ~ JSON v0.17.1+ #master ⇒ v0.17.1 +``` + +It is also possible to give a local path as the argument to `develop` which will not clone anything but simply use that directory for the package. + +Developing a non registered package is done by giving the git-repo url as an argument to `develop`. + +### Updating dependencies + +When new versions of packages the project is using are released, it is a good idea to update. Simply calling `up` will try to update *all* the dependencies of the project. Sometimes this is not what you want. You can specify a subset of the dependencies to upgrade by giving them as arguments to `up`, e.g: + +``` +pkg> up JSON +``` + +The version of all other dependencies will stay the same. If you only want to update the minor version of packages, to reduce the risk that your project breaks, you can give the `--minor` flag, e.g: + +``` +pkg> up --minor JSON +``` + +Packages that track a branch are not updated when a minor upgrade is done. +Developed packages are never touched by the package manager. + +If you just want install the packages that are given by the current `Manifest.toml` use + +``` +pkg> up --manifest --fixed +``` + +### Preview mode + +If you just want to see the effects of running a command, but not change your state you can `preview` a command. +For example: + +``` +pkg> preview add Plot +``` + +or + +``` +pkg> preview up +``` + +will show you the effects adding `Plots`, or doing a full upgrade, respectively, would have on your project. +However, nothing would be installed and your `Project.toml` and `Manfiest.toml` are untouched. + + +### Using someone elses project. + +Simple clone their project using e.g. `git clone`, `cd` to the project directory and call + +``` +pkg> up --manifest --fixed +``` + +This will install the packages at the same state that the project you cloned was using. diff --git a/make.jl b/make.jl index 392115c..52f9be4 100644 --- a/make.jl +++ b/make.jl @@ -132,7 +132,7 @@ for stdlib in STDLIB_DOCS end makedocs( - build = joinpath(pwd(), "_build/html/ko/latest"), + build = joinpath(pwd(), "local" in ARGS ? "_build_local" : "_build/html/ko/latest"), modules = [Base, Core, BuildSysImg, [Base.root_module(Base, stdlib.stdlib) for stdlib in STDLIB_DOCS]...], clean = false, # true doctest = "doctest" in ARGS, diff --git a/src/NEWS.md b/src/NEWS.md index 02511bd..315d250 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -108,12 +108,12 @@ Language changes * `global const` declarations may no longer appear inside functions ([#12010](https://github.com/JuliaLang/julia/issues/12010)). * Uninitialized `BitArray` constructors of the form `BitArray[{N}](shape...)` have been - deprecated in favor of equivalents accepting `uninitialized` (an alias for - `Uninitialized()`) as their first argument, as in - `BitArray[{N}](uninitialized, shape...)`. For example, `BitVector(3)` is now - `BitVector(uninitialized, 3)`, `BitMatrix((2, 4))` is now - `BitMatrix(uninitialized, (2, 4))`, and `BitArray{3}(11, 13, 17)` is now - `BitArray{3}(uninitialized, 11, 14, 17)` ([#24785](https://github.com/JuliaLang/julia/issues/24785)). + deprecated in favor of equivalents accepting `undef` (an alias for + `UndefInitializer()`) as their first argument, as in + `BitArray[{N}](undef, shape...)`. For example, `BitVector(3)` is now + `BitVector(undef, 3)`, `BitMatrix((2, 4))` is now + `BitMatrix(undef, (2, 4))`, and `BitArray{3}(11, 13, 17)` is now + `BitArray{3}(undef, 11, 14, 17)` ([#24785](https://github.com/JuliaLang/julia/issues/24785)). * Dispatch rules have been simplified: method matching is now determined exclusively by subtyping; @@ -449,6 +449,11 @@ Library improvements * `Char` is now a subtype of `AbstractChar`, and most of the functions that take character arguments now accept any `AbstractChar` ([#26286](https://github.com/JuliaLang/julia/issues/26286)). + * `String(array)` now accepts an arbitrary `AbstractVector{UInt8}`. For `Vector` + inputs, it "steals" the memory buffer, leaving them with an empty buffer which + is guaranteed not to be shared with the `String` object. For other types of vectors + (in particular immutable vectors), a copy is made and the input is not truncated ([#26093](https://github.com/JuliaLang/julia/issues/26093)). + * `Irrational` is now a subtype of `AbstractIrrational` ([#24245](https://github.com/JuliaLang/julia/issues/24245)). * Introduced the `empty` function, the functional pair to `empty!` which returns a new, @@ -650,11 +655,11 @@ Deprecated or removed * Uninitialized `Array` constructors of the form `Array[{T,N}](shape...)` have been deprecated in favor of equivalents - accepting `uninitialized` (an alias for `Uninitialized()`) as their first argument, - as in `Array[{T,N}](uninitialized, shape...)`. For example, - `Vector(3)` is now `Vector(uninitialized, 3)`, `Matrix{Int}((2, 4))` is now, - `Matrix{Int}(uninitialized, (2, 4))`, and `Array{Float32,3}(11, 13, 17)` is now - `Array{Float32,3}(uninitialized, 11, 13, 17)` ([#24781](https://github.com/JuliaLang/julia/issues/24781)). + accepting `undef` (an alias for `UndefInitializer()`) as their first argument, + as in `Array[{T,N}](undef, shape...)`. For example, + `Vector(3)` is now `Vector(undef, 3)`, `Matrix{Int}((2, 4))` is now, + `Matrix{Int}(undef, (2, 4))`, and `Array{Float32,3}(11, 13, 17)` is now + `Array{Float32,3}(undef, 11, 13, 17)` ([#24781](https://github.com/JuliaLang/julia/issues/24781)). * `LinAlg.fillslots!` has been renamed `LinAlg.fillstored!` ([#25030](https://github.com/JuliaLang/julia/issues/25030)). @@ -672,19 +677,19 @@ Deprecated or removed * `slicedim(A, d, i)` has been deprecated in favor of `copy(selectdim(A, d, i))`. The new `selectdim` function now always returns a view into `A`; in many cases the `copy` is not necessary. Previously, `slicedim` on a vector `V` over dimension `d=1` and scalar - index `i` would return the just selected element (unless `V` was a `BitVector`). This - has now been made consistent: `selectdim` now always returns a view into the original - array, with a zero-dimensional view in this specific case ([#26009](https://github.com/JuliaLang/julia/issues/26009)). + index `i` would return the just selected element (unless `V` was a `BitVector`). This + has now been made consistent: `selectdim` now always returns a view into the original + array, with a zero-dimensional view in this specific case ([#26009](https://github.com/JuliaLang/julia/issues/26009)). * `whos` has been renamed `varinfo`, and now returns a markdown table instead of printing output ([#12131](https://github.com/JuliaLang/julia/issues/12131)). * Uninitialized `RowVector` constructors of the form `RowVector{T}(shape...)` have been - deprecated in favor of equivalents accepting `uninitialized` (an alias for - `Uninitialized()`) as their first argument, as in - `RowVector{T}(uninitialized, shape...)`. For example, `RowVector{Int}(3)` is now - `RowVector{Int}(uninitialized, 3)`, and `RowVector{Float32}((1, 4))` is now - `RowVector{Float32}(uninitialized, (1, 4))` ([#24786](https://github.com/JuliaLang/julia/issues/24786)). + deprecated in favor of equivalents accepting `undef` (an alias for + `UndefInitializer()`) as their first argument, as in + `RowVector{T}(undef, shape...)`. For example, `RowVector{Int}(3)` is now + `RowVector{Int}(undef, 3)`, and `RowVector{Float32}((1, 4))` is now + `RowVector{Float32}(undef, (1, 4))` ([#24786](https://github.com/JuliaLang/julia/issues/24786)). * `writecsv(io, a; opts...)` has been deprecated in favor of `writedlm(io, a, ','; opts...)` ([#23529](https://github.com/JuliaLang/julia/issues/23529)). @@ -747,7 +752,7 @@ Deprecated or removed in favor of `replace(s::AbstractString, pat => r; [count])` ([#25165](https://github.com/JuliaLang/julia/issues/25165)). Moreover, `count` cannot be negative anymore (use `typemax(Int)` instead ([#22325](https://github.com/JuliaLang/julia/issues/22325)). - * `read(io, type, dims)` is deprecated to `read!(io, Array{type}(uninitialized, dims))` ([#21450](https://github.com/JuliaLang/julia/issues/21450)). + * `read(io, type, dims)` is deprecated to `read!(io, Array{type}(undef, dims))` ([#21450](https://github.com/JuliaLang/julia/issues/21450)). * `read(::IO, ::Ref)` is now a method of `read!`, since it mutates its `Ref` argument ([#21592](https://github.com/JuliaLang/julia/issues/21592)). diff --git a/src/base/arrays.md b/src/base/arrays.md index 11b3c6d..4c011a1 100644 --- a/src/base/arrays.md +++ b/src/base/arrays.md @@ -7,24 +7,24 @@ Core.AbstractArray Base.AbstractVector Base.AbstractMatrix Core.Array -Core.Array(::Uninitialized, ::Any) +Core.Array(::UndefInitializer, ::Any) Core.Array(::Nothing, ::Any) Core.Array(::Missing, ::Any) -Core.Uninitialized -Core.uninitialized +Core.UndefInitializer +Core.undef Base.Vector -Base.Vector(::Uninitialized, ::Any) +Base.Vector(::UndefInitializer, ::Any) Base.Vector(::Nothing, ::Any) Base.Vector(::Missing, ::Any) Base.Matrix -Base.Matrix(::Uninitialized, ::Any, ::Any) +Base.Matrix(::UndefInitializer, ::Any, ::Any) Base.Matrix(::Nothing, ::Any, ::Any) Base.Matrix(::Missing, ::Any, ::Any) Base.getindex(::Type, ::Any...) Base.zeros Base.ones Base.BitArray -Base.BitArray(::Uninitialized, ::Integer...) +Base.BitArray(::UndefInitializer, ::Integer...) Base.BitArray(::Any) Base.trues Base.falses @@ -115,7 +115,6 @@ Base.vcat Base.hcat Base.hvcat Base.vect -Base.flipdim Base.circshift Base.circshift! Base.circcopy! diff --git a/src/base/base.md b/src/base/base.md index 2c1db70..e62e4c0 100644 --- a/src/base/base.md +++ b/src/base/base.md @@ -245,7 +245,6 @@ Base.withenv Base.pipeline(::Any, ::Any, ::Any, ::Any...) Base.pipeline(::Base.AbstractCmd) Base.Libc.gethostname -Base.getipaddr Base.Libc.getpid Base.Libc.time() Base.time_ns @@ -291,7 +290,6 @@ Base.MissingException Core.OutOfMemoryError Core.ReadOnlyMemoryError Core.OverflowError -Base.ParseError Core.StackOverflowError Base.SystemError Core.TypeError @@ -336,6 +334,7 @@ Meta.lower Meta.@lower Meta.parse(::AbstractString, ::Int) Meta.parse(::AbstractString) +Meta.ParseError Base.macroexpand Base.@macroexpand Base.@macroexpand1 diff --git a/src/base/collections.md b/src/base/collections.md index cdc77c2..0e2c58a 100644 --- a/src/base/collections.md +++ b/src/base/collections.md @@ -203,8 +203,8 @@ Base.keys Base.values Base.pairs Base.merge -Base.merge!(::Associative, ::Associative...) -Base.merge!(::Function, ::Associative, ::Associative...) +Base.merge!(::AbstractDict, ::AbstractDict...) +Base.merge!(::Function, ::AbstractDict, ::AbstractDict...) Base.sizehint! Base.keytype Base.valtype diff --git a/src/devdocs/offset-arrays.md b/src/devdocs/offset-arrays.md index 5288f30..b5a1552 100644 --- a/src/devdocs/offset-arrays.md +++ b/src/devdocs/offset-arrays.md @@ -97,7 +97,7 @@ end ### Allocating storage using generalizations of `similar` -Storage is often allocated with `Array{Int}(uninitialized, dims)` or `similar(A, args...)`. When the result needs +Storage is often allocated with `Array{Int}(undef, dims)` or `similar(A, args...)`. When the result needs to match the indices of some other array, this may not always suffice. The generic replacement for such patterns is to use `similar(storagetype, shape)`. `storagetype` indicates the kind of underlying "conventional" behavior you'd like, e.g., `Array{Int}` or `BitArray` or even `dims->zeros(Float32, dims)` @@ -109,7 +109,7 @@ Let's walk through a couple of explicit examples. First, if `A` has conventional `similar(Array{Int}, axes(A))` would end up calling `Array{Int}(size(A))`, and thus return an array. If `A` is an `AbstractArray` type with unconventional indexing, then `similar(Array{Int}, axes(A))` should return something that "behaves like" an `Array{Int}` but with a shape (including indices) -that matches `A`. (The most obvious implementation is to allocate an `Array{Int}(uninitialized, size(A))` and +that matches `A`. (The most obvious implementation is to allocate an `Array{Int}(undef, size(A))` and then "wrap" it in a type that shifts the indices.) Note also that `similar(Array{Int}, (axes(A, 2),))` would allocate an `AbstractVector{Int}` diff --git a/src/devdocs/reflection.md b/src/devdocs/reflection.md index 23ff13b..f8af9b6 100644 --- a/src/devdocs/reflection.md +++ b/src/devdocs/reflection.md @@ -113,14 +113,13 @@ julia> Meta.lower(@__MODULE__, :(f() = 1) ) Inspecting the lowered form for functions requires selection of the specific method to display, because generic functions may have many methods with different type signatures. For this purpose, -method-specific code-lowering is available using [`code_lowered(f::Function, (Argtypes...))`](@ref), -and the type-inferred form is available using [`code_typed(f::Function, (Argtypes...))`](@ref). -[`code_warntype(f::Function, (Argtypes...))`](@ref) adds highlighting to the output of [`code_typed`](@ref) -(see [`@code_warntype`](@ref)). +method-specific code-lowering is available using [`code_lowered`](@ref), +and the type-inferred form is available using [`code_typed`](@ref). +[`code_warntype`](@ref) adds highlighting to the output of [`code_typed`](@ref). Closer to the machine, the LLVM intermediate representation of a function may be printed using -by [`code_llvm(f::Function, (Argtypes...))`](@ref), and finally the compiled machine code is available -using [`code_native(f::Function, (Argtypes...))`](@ref) (this will trigger JIT compilation/code +by [`code_llvm`](@ref), and finally the compiled machine code is available +using [`code_native`](@ref) (this will trigger JIT compilation/code generation for any function which has not previously been called). For convenience, there are macro versions of the above functions which take standard function @@ -137,4 +136,5 @@ top: } ``` -(likewise `@code_typed`, `@code_warntype`, `@code_lowered`, and `@code_native`) +See [`@code_lowered`](@ref), [`@code_typed`](@ref), [`@code_warntype`](@ref), +[`@code_llvm`](@ref), and [`@code_native`](@ref). diff --git a/src/index.md b/src/index.md index f08c212..1d77748 100644 --- a/src/index.md +++ b/src/index.md @@ -14,7 +14,7 @@ ## 매뉴얼 * [소개글](@ref man-introduction) - * [시작하기](@ref Getting-Started) + * [시작하기](@ref man-getting-started) * [변수](@ref Variables) * [정수와 부동 소수점 수](@ref Integers-and-Floating-Point-Numbers) * [Mathematical Operations and Elementary Functions](@ref) diff --git a/src/manual/arrays.md b/src/manual/arrays.md index b1e968a..8fb5e29 100644 --- a/src/manual/arrays.md +++ b/src/manual/arrays.md @@ -15,11 +15,17 @@ Julia는 배열을 특별하게 취급하지는 않는다. Julia 컴파일러는 타입 추론을 사용하여 스칼라 배열 인덱싱에 최적화된 코드를 생성한다. 따라서 편리하고 읽기 쉬운 스타일로 프로그램을 작성하더라도 성능을 희생하지 않으며, 오히려 메모리를 더 적게 사용하는 경우도 있다. -Julia에서 모든 인수는 참조에 의해 전달된다(pass by reference). -어떤 기술적 계산 언어는 배열을 값에 의해 전달하는데(pass by value), 이렇게 하는 것이 편리한 경우도 많이 있다. -Julia에서는 함수 내에서 일어난 입력 배열의 변화를 부모 함수에서도 볼 수 있다. -Julia 배열 라이브러리의 어떤 코드도 입력 배열을 변경하지 않는다. -사용자의 코드가 이와 비슷하게 행동하도록 하려면, 변경될 수도 있는 배열을 복사하는 것에 소홀해서는 안된다. +In Julia, all arguments to functions are [passed by +sharing](https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing) +(i.e. by pointers). Some technical computing languages pass arrays by value, and +while this prevents accidental modification by callees of a value in the caller, +it makes avoiding unwanted copying of arrays difficult. By convention, a +function name ending with a `!` indicates that it will mutate or destroy the +value of one or more of its arguments. Callees must make explicit copies to +ensure that they don't modify inputs that they don't intend to change. Many non- +mutating functions are implemented by calling a function of the same name with +an added `!` at the end on an explicit copy of the input, and returning that +copy. ## [배열](@id Arrays) @@ -47,7 +53,7 @@ Julia 배열 라이브러리의 어떤 코드도 입력 배열을 변경하지 | 함수 | 설명 | |:---------------------------------- |:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [`Array{T}(uninitialized, dims...)`](@ref) | 초기화 되지 않은 밀집 [`Array`](@ref) | +| [`Array{T}(undef, dims...)`](@ref) | 초기화 되지 않은 밀집 [`Array`](@ref) | | [`zeros(T, dims...)`](@ref) | 모든 값이 0으로 초기화 된 `Array` | | [`ones(T, dims...)`](@ref) | 모든 값이 1로 초기화 된 `Array` | | [`trues(dims...)`](@ref) | 모든 값이 `true`로 초기화 된 [`BitArray`](@ref) | @@ -652,11 +658,15 @@ Very few operations are implemented specifically for `Array` beyond those that a for all `AbstractArrays`s; much of the array library is implemented in a generic manner that allows all custom arrays to behave similarly. -`SubArray`는 복사가 아닌 참조로 인덱싱을 수행하는 `AbstractArray`의 특수화이다. -`SubArray`는 [`view`](@ref)함수로 생성되는데, 호출 방식은 [`getindex`](@ref)와 같다. -[`view`](@ref)의 결과는 [`getindex`](@ref)와 똑같이 보이나, 데이터가 복사되지 않는다는 차이점이 있다. -[`view`](@ref)는 입력 인덱스 벡터를 `SubArray` 객체에 저장하는데, 이는 참조되는 원 배열을 나중에 간접적으로 인덱싱 하는데에 쓰인다. -[`@views`](@ref) 매크로를 표현식이나 코드 블록 앞에 둠으로써, 그 표현식 내의 모든 `array[...]` 슬라이스가 `SubArray` 뷰를 생성하도록 할 수 있다. +`SubArray` is a specialization of `AbstractArray` that performs indexing by +sharing memory with the original array rather than by copying it. A `SubArray` +is created with the [`view`](@ref) function, which is called the same way as +[`getindex`](@ref) (with an array and a series of index arguments). The result +of [`view`](@ref) looks the same as the result of [`getindex`](@ref), except the +data is left in place. [`view`](@ref) stores the input index vectors in a +`SubArray` object, which can later be used to index the original array +indirectly. + [`@views`](@ref) 매크로를 표현식이나 코드 블록 앞에 둠으로써, 그 표현식 내의 모든 `array[...]` 슬라이스가 `SubArray` 뷰를 생성하도록 할 수 있다. A "strided" array is stored in memory with elements laid out in regular offsets such that an instance with a supported `isbits` element type can be passed to diff --git a/src/manual/calling-c-and-fortran-code.md b/src/manual/calling-c-and-fortran-code.md index a717d71..07d7f2f 100644 --- a/src/manual/calling-c-and-fortran-code.md +++ b/src/manual/calling-c-and-fortran-code.md @@ -26,11 +26,16 @@ A function name may be used alone in place of the tuple (just `:function` or `"f this case the name is resolved within the current process. This form can be used to call C library functions, functions in the Julia runtime, or functions in an application linked to Julia. -By default, Fortran compilers [generate mangled names](https://en.wikipedia.org/wiki/Name_mangling#Fortran) -(for example, converting function names to lowercase or uppercase, often appending an underscore), -and so to call a Fortran function via [`ccall`](@ref) you must pass the mangled identifier corresponding -to the rule followed by your Fortran compiler. Also, when calling a Fortran function, all inputs -must be passed by reference. +By default, Fortran compilers [generate mangled +names](https://en.wikipedia.org/wiki/Name_mangling#Fortran) (for example, +converting function names to lowercase or uppercase, often appending an +underscore), and so to call a Fortran function via [`ccall`](@ref) you must pass +the mangled identifier corresponding to the rule followed by your Fortran +compiler. Also, when calling a Fortran function, all inputs must be passed as +pointers to allocated values on the heap or stack. This applies not only to +arrays and other mutable objects which are normally heap-allocated, but also to +scalar values such as integers and floats which are normally stack-allocated and +commonly passed in registers when using C or Julia calling conventions. Finally, you can use [`ccall`](@ref) to actually generate a call to the library function. Arguments to [`ccall`](@ref) are as follows: @@ -385,8 +390,9 @@ checks and is only meant to improve readability of the call. | `wchar_t` | `Cwchar_t` | `Int32` (UNIX), `UInt16` (Windows) | !!! note - When calling a Fortran function, all inputs must be passed by reference, so all type correspondences - above should contain an additional `Ptr{..}` or `Ref{..}` wrapper around their type specification. + When calling Fortran, all inputs must be passed by pointers to heap- or stack-allocated + values, so all type correspondences above should contain an additional `Ptr{..}` or + `Ref{..}` wrapper around their type specification. !!! warning For string arguments (`char*`) the Julia type should be `Cstring` (if NUL- terminated data is @@ -590,9 +596,10 @@ of pointers to memory managed by either Julia or C through the implicit call to structs should be represented as fields of type `Ptr{T}` within the corresponding Julia struct types designed to mimic the internal structure of corresponding C structs. -In Julia code wrapping calls to external Fortran routines, all input arguments should be declared -as of type `Ref{T}`, as Fortran passes all variables by reference. The return type should either -be `Cvoid` for Fortran subroutines, or a `T` for Fortran functions returning the type `T`. +In Julia code wrapping calls to external Fortran routines, all input arguments +should be declared as of type `Ref{T}`, as Fortran passes all variables by +pointers to memory locations. The return type should either be `Cvoid` for +Fortran subroutines, or a `T` for Fortran functions returning the type `T`. ## Mapping C Functions to Julia @@ -763,11 +770,13 @@ that has no internal fields and whose sole purpose is to be placed in the type p `Ptr` type. The return type of the [`ccall`](@ref) is declared as `Ptr{gsl_permutation}`, since the memory allocated and pointed to by `output_ptr` is controlled by C (and not Julia). -The input `n` is passed by value, and so the function's input signature is simply declared as -`(Csize_t,)` without any `Ref` or `Ptr` necessary. (If the wrapper was calling a Fortran function -instead, the corresponding function input signature should instead be `(Ref{Csize_t},)`, since -Fortran variables are passed by reference.) Furthermore, `n` can be any type that is convertable -to a `Csize_t` integer; the [`ccall`](@ref) implicitly calls [`Base.cconvert(Csize_t, n)`](@ref). +The input `n` is passed by value, and so the function's input signature is +simply declared as `(Csize_t,)` without any `Ref` or `Ptr` necessary. (If the +wrapper was calling a Fortran function instead, the corresponding function input +signature should instead be `(Ref{Csize_t},)`, since Fortran variables are +passed by pointers.) Furthermore, `n` can be any type that is convertable to a +`Csize_t` integer; the [`ccall`](@ref) implicitly calls [`Base.cconvert(Csize_t, +n)`](@ref). Here is a second example wrapping the corresponding destructor: diff --git a/src/manual/control-flow.md b/src/manual/control-flow.md index c80cc6c..0528980 100644 --- a/src/manual/control-flow.md +++ b/src/manual/control-flow.md @@ -481,7 +481,7 @@ julia> for i = 1:2, j = 3:4 | [`RemoteException`](@ref) | | [`MethodError`](@ref) | | [`OverflowError`](@ref) | -| [`ParseError`](@ref) | +| [`Meta.ParseError`](@ref) | | [`SystemError`](@ref) | | [`TypeError`](@ref) | | [`UndefRefError`](@ref) | diff --git a/src/manual/environment-variables.md b/src/manual/environment-variables.md index 28dbf15..513b75c 100644 --- a/src/manual/environment-variables.md +++ b/src/manual/environment-variables.md @@ -97,7 +97,7 @@ respect to the working directory. If `$JULIA_PKGDIR` is not set, then $HOME/.julia ``` -Then the repository location [`Pkg.dir`](@ref) for a given Julia version is +Then the repository location `Pkg.dir` for a given Julia version is ``` $JULIA_PKGDIR/v$(VERSION.major).$(VERSION.minor) @@ -128,7 +128,7 @@ $HOME/.julia_history ### `JULIA_PKGRESOLVE_ACCURACY` A positive `Int` that determines how much time the max-sum subroutine -`MaxSum.maxsum()` of the package dependency resolver [`Base.Pkg.resolve`](@ref) +`MaxSum.maxsum()` of the package dependency resolver `Pkg.resolve` will devote to attempting satisfying constraints before giving up: this value is by default `1`, and larger values correspond to larger amounts of time. @@ -164,7 +164,7 @@ exists, or `emacs` otherwise. !!! note `$JULIA_EDITOR` is *not* used in the determination of the editor for - [`Base.Pkg.edit`](@ref): this function checks `$VISUAL` and `$EDITOR` alone. + `Pkg.edit`: this function checks `$VISUAL` and `$EDITOR` alone. ## Parallelization diff --git a/src/manual/getting-started.md b/src/manual/getting-started.md index d0f5ac2..50caf22 100644 --- a/src/manual/getting-started.md +++ b/src/manual/getting-started.md @@ -1,4 +1,4 @@ -# [시작하기](@id Getting-Started) +# [시작하기](@id man-getting-started) 줄리아의 설치는 어렵지 않다. 미리 컴파일된 실행파일을 이용하거나, 아니면 소스로부터 직접 컴파일하는 두가지 방법이 존재한다. [https://julialang.org/downloads/](https://julialang.org/downloads/)에서 알려주는 방법에 따라 Julia를 다운로드하고 설치하면 된다. diff --git a/src/manual/index.md b/src/manual/index.md index 148d5e0..5f79a98 100644 --- a/src/manual/index.md +++ b/src/manual/index.md @@ -1,7 +1,7 @@ # The Julia Manual * [Introduction](@ref man-introduction) - * [Getting Started](@ref) + * [Getting Started](@ref man-getting-started) * [Variables](@ref) * [Integers and Floating-Point Numbers](@ref) * [Mathematical Operations and Elementary Functions](@ref) diff --git a/src/manual/interfaces.md b/src/manual/interfaces.md index 2349da9..9a6b064 100644 --- a/src/manual/interfaces.md +++ b/src/manual/interfaces.md @@ -235,7 +235,7 @@ ourselves, we can officially define it as a subtype of an [`AbstractArray`](@ref | `similar(A)` | `similar(A, eltype(A), size(A))` | Return a mutable array with the same shape and element type | | `similar(A, ::Type{S})` | `similar(A, S, size(A))` | Return a mutable array with the same shape and the specified element type | | `similar(A, dims::NTuple{Int})` | `similar(A, eltype(A), dims)` | Return a mutable array with the same element type and size *dims* | -| `similar(A, ::Type{S}, dims::NTuple{Int})` | `Array{S}(uninitialized, dims)` | Return a mutable array with the specified element type and size | +| `similar(A, ::Type{S}, dims::NTuple{Int})` | `Array{S}(undef, dims)` | Return a mutable array with the specified element type and size | | **Non-traditional indices** | **Default definition** | **Brief description** | | `axes(A)` | `map(OneTo, size(A))` | Return the `AbstractUnitRange` of valid indices | | `Base.similar(A, ::Type{S}, inds::NTuple{Ind})` | `similar(A, S, Base.to_shape(inds))` | Return a mutable array with the specified indices `inds` (see below) | diff --git a/src/manual/noteworthy-differences.md b/src/manual/noteworthy-differences.md index dd0a8c1..c87b30c 100644 --- a/src/manual/noteworthy-differences.md +++ b/src/manual/noteworthy-differences.md @@ -7,9 +7,9 @@ major syntactic and functional differences. The following are some noteworthy di may trip up Julia users accustomed to MATLAB: * Julia arrays are indexed with square brackets, `A[i,j]`. - * Julia arrays are assigned by reference. After `A=B`, changing elements of `B` will modify `A` + * Julia arrays are not copied when assigned to another variable. After `A = B`, changing elements of `B` will modify `A` as well. - * Julia values are passed and assigned by reference. If a function modifies an array, the changes + * Julia values are not copied when passed to a function. If a function modifies an array, the changes will be visible in the caller. * Julia does not automatically grow arrays in an assignment statement. Whereas in MATLAB `a(4) = 3.2` can create the array `a = [0 0 0 3.2]` and `a(5) = 7` can grow it into `a = [0 0 0 3.2 7]`, the @@ -153,7 +153,7 @@ For users coming to Julia from R, these are some noteworthy differences: * Julia encourages users to write their own types, which are easier to use than S3 or S4 objects in R. Julia's multiple dispatch system means that `table(x::TypeA)` and `table(x::TypeB)` act like R's `table.TypeA(x)` and `table.TypeB(x)`. - * In Julia, values are passed and assigned by reference. If a function modifies an array, the changes + * In Julia, values are not copied when assigned or passed to a function. If a function modifies an array, the changes will be visible in the caller. This is very different from R and allows new functions to operate on large data structures much more efficiently. * In Julia, vectors and matrices are concatenated using [`hcat`](@ref), [`vcat`](@ref) and @@ -227,13 +227,13 @@ For users coming to Julia from R, these are some noteworthy differences: This syntax is not just syntactic sugar for a reference to a pointer or address as in C/C++. See the Julia documentation for the syntax for array construction (it has changed between versions). * In Julia, indexing of arrays, strings, etc. is 1-based not 0-based. - * Julia arrays are assigned by reference. After `A=B`, changing elements of `B` will modify `A` + * Julia arrays are not copied when assigned to another variable. After `A = B`, changing elements of `B` will modify `A` as well. Updating operators like `+=` do not operate in-place, they are equivalent to `A = A + B` which rebinds the left-hand side to the result of the right-hand side expression. * Julia arrays are column major (Fortran ordered) whereas C/C++ arrays are row major ordered by default. To get optimal performance when looping over arrays, the order of the loops should be reversed in Julia relative to C/C++ (see relevant section of [Performance Tips](@ref man-performance-tips)). - * Julia values are passed and assigned by reference. If a function modifies an array, the changes + * Julia values are not copied when assigned or passed to a function. If a function modifies an array, the changes will be visible in the caller. * In Julia, whitespace is significant, unlike C/C++, so care must be taken when adding/removing whitespace from a Julia program. diff --git a/src/manual/performance-tips.md b/src/manual/performance-tips.md index 84dd79c..bcd5abe 100644 --- a/src/manual/performance-tips.md +++ b/src/manual/performance-tips.md @@ -618,7 +618,7 @@ end ```jldoctest julia> function strange_twos(n) - a = Vector{rand(Bool) ? Int64 : Float64}(uninitialized, n) + a = Vector{rand(Bool) ? Int64 : Float64}(undef, n) for i = 1:n a[i] = 2 end @@ -644,7 +644,7 @@ julia> function fill_twos!(a) fill_twos! (generic function with 1 method) julia> function strange_twos(n) - a = Vector{rand(Bool) ? Int64 : Float64}(uninitialized, n) + a = Vector{rand(Bool) ? Int64 : Float64}(undef, n) fill_twos!(a) return a end @@ -931,7 +931,7 @@ function xinc!(ret::AbstractVector{T}, x::T) where T end function loopinc_prealloc() - ret = Vector{Int}(uninitialized, 3) + ret = Vector{Int}(undef, 3) y = 0 for i = 1:10^7 xinc!(ret, i) @@ -1282,7 +1282,7 @@ end function main() n = 2000 - u = Vector{Float64}(uninitialized, n) + u = Vector{Float64}(undef, n) init!(u) du = similar(u) diff --git a/src/manual/style-guide.md b/src/manual/style-guide.md index a62f853..10355e4 100644 --- a/src/manual/style-guide.md +++ b/src/manual/style-guide.md @@ -145,10 +145,10 @@ some alternatives to consider: It is usually not much help to construct arrays like the following: ```julia -a = Vector{Union{Int,AbstractString,Tuple,Array}}(uninitialized, n) +a = Vector{Union{Int,AbstractString,Tuple,Array}}(undef, n) ``` -In this case `Vector{Any}(uninitialized, n)` is better. It is also more helpful to the compiler to annotate specific +In this case `Vector{Any}(undef, n)` is better. It is also more helpful to the compiler to annotate specific uses (e.g. `a[i]::Int`) than to try to pack many alternatives into one type. ## Use naming conventions consistent with Julia's `base/` @@ -204,9 +204,9 @@ as applicable: 9. **Varargs**. This refers to arguments that can be listed indefinitely at the end of a function call. - For example, in `Matrix{T}(uninitialized, dims)`, the dimensions can be given as a - [`Tuple`](@ref), e.g. `Matrix{T}(uninitialized, (1,2))`, or as [`Vararg`](@ref)s, - e.g. `Matrix{T}(uninitialized, 1, 2)`. + For example, in `Matrix{T}(undef, dims)`, the dimensions can be given as a + [`Tuple`](@ref), e.g. `Matrix{T}(undef, (1,2))`, or as [`Vararg`](@ref)s, + e.g. `Matrix{T}(undef, 1, 2)`. 10. **Keyword arguments**. In Julia keyword arguments have to come last anyway in function definitions; they're diff --git a/src/manual/types.md b/src/manual/types.md index 20c40c3..1a7d849 100644 --- a/src/manual/types.md +++ b/src/manual/types.md @@ -372,8 +372,8 @@ julia> foo.qux Composite objects declared with `struct` are *immutable*; they cannot be modified after construction. This may seem odd at first, but it has several advantages: - * It can be more efficient. Some structs can be packed efficiently into arrays, and in some cases the - compiler is able to avoid allocating immutable objects entirely. + * It can be more efficient. Some structs can be packed efficiently into arrays, and + in some cases the compiler is able to avoid allocating immutable objects entirely. * It is not possible to violate the invariants provided by the type's constructors. * Code using immutable objects can be easier to reason about. @@ -433,18 +433,22 @@ over time. If they would be considered identical, the type should probably be im To recap, two essential properties define immutability in Julia: - * An object with an immutable type is passed around (both in assignment statements and in function - calls) by copying, whereas a mutable type is passed around by reference. - * It is not permitted to modify the fields of a composite immutable type. - -It is instructive, particularly for readers whose background is C/C++, to consider why these two -properties go hand in hand. If they were separated, i.e., if the fields of objects passed around -by copying could be modified, then it would become more difficult to reason about certain instances -of generic code. For example, suppose `x` is a function argument of an abstract type, and suppose -that the function changes a field: `x.isprocessed = true`. Depending on whether `x` is passed -by copying or by reference, this statement may or may not alter the actual argument in the calling -routine. Julia sidesteps the possibility of creating functions with unknown effects in this scenario -by forbidding modification of fields of objects passed around by copying. + * It is not permitted to modify the value of an immutable type. + * For bits types this means that the bit pattern of a value once set will never change + and that value is the identity of a bits type. + * For composite types, this means that the identity of the values of its fields will + never change. When the fields are bits types, that means their bits will never change, + for fields whose values are mutable types like arrays, that means the fields will + always refer to the same mutable value even though that mutable value's content may + itself be modified. + * An object with an immutable type may be copied freely by the compiler since its + immutabity makes it impossible to programmatically distinguish between the original + object and a copy. + * In particular, this means that small enough immutable values like integers and floats + are typically passed to functions in registers (or stack allocated). + * Mutable values, on the other hand are heap-allocated and passed to + functions as pointers to heap-allocated values except in cases where the compiler + is sure that there's no way to tell that this is not what is happening. ## Declared Types diff --git a/src/manual/unicode-input.md b/src/manual/unicode-input.md index b156bde..00ab38c 100644 --- a/src/manual/unicode-input.md +++ b/src/manual/unicode-input.md @@ -20,7 +20,7 @@ the symbol). # Generate a table containing all LaTeX and Emoji tab completions available in the REPL. # -import REPL +import REPL, Markdown const NBSP = '\u00A0' function tab_completions(symbols...) diff --git a/src/manual/variables-and-scoping.md b/src/manual/variables-and-scoping.md index 088aafd..38ac858 100644 --- a/src/manual/variables-and-scoping.md +++ b/src/manual/variables-and-scoping.md @@ -359,7 +359,7 @@ something like `let x = x` since the two `x` variables are distinct and have sep Here is an example where the behavior of `let` is needed: ```jldoctest -julia> Fs = Vector{Any}(uninitialized, 2); i = 1; +julia> Fs = Vector{Any}(undef, 2); i = 1; julia> while i <= 2 Fs[i] = ()->i @@ -378,7 +378,7 @@ variable `i`, so the two closures behave identically. We can use `let` to create for `i`: ```jldoctest -julia> Fs = Vector{Any}(uninitialized, 2); i = 1; +julia> Fs = Vector{Any}(undef, 2); i = 1; julia> while i <= 2 let i = i @@ -418,7 +418,7 @@ introduced in their body scopes are freshly allocated for each loop iteration, a were surrounded by a `let` block: ```jldoctest -julia> Fs = Vector{Any}(uninitialized, 2); +julia> Fs = Vector{Any}(undef, 2); julia> for j = 1:2 Fs[j] = ()->j diff --git a/src/stdlib/Pkg3.md b/src/stdlib/Pkg3.md new file mode 100644 index 0000000..b54bddc --- /dev/null +++ b/src/stdlib/Pkg3.md @@ -0,0 +1,224 @@ +# Pkg3.jl + +!!! warning + This documentation is a work in progress and the information in it might be or become outdated. + +Sections: + +```@contents +Pages = [ + "index.md"] +``` + +## Introduction + +Pkg3 is the package manager for Julia. + +## Getting Started + +The Pkg REPL-mode is entered using from the Julia REPL using the key `]`. +To return to the `julia>` prompt, either press backspace when the input line is empty or press Ctrl+C. +Help is available by calling `pkg> help`. + +To generate files for a new project, use `pkg> generate`. + +``` +pkg> generate HelloWorld +``` + +This creates a new project `HelloWorld` with the following files + +```jl +julia> cd("HelloWorld") +shell> tree . +. +├── Project.toml +└── src + └── HelloWorld.jl + +1 directory, 2 files +``` + +The `Project.toml` file contains the name of the package, its unique UUID, its version, the author and eventual dependencies: + +```toml +name = "HelloWorld" +uuid = "b4cd1eb8-1e24-11e8-3319-93036a3eb9f3" +version = "0.1.0" +author = ["Some One "] + +[deps] +``` + +The content of `src/HelloWorld.jl` is: + +```jl +module HelloWorld + +greet() = print("Hello World!") + +end # module +``` + +We can now load the project and use it: + +```jl +julia> import HelloWorld + +julia> HelloWorld.greet() +Hello World! +``` + +### Adding packages to the project + +Let's say we want to use the standard library package `Random` and the registered package `JSON` in our project. +We simply `add` these packages: + +``` +pkg> add Random JSON + Resolving package versions... + Updating "~/Documents/HelloWorld/Project.toml" + [682c06a0] + JSON v0.17.1 + [9a3f8284] + Random + Updating "~/Documents/HelloWorld/Manifest.toml" + [34da2185] + Compat v0.57.0 + [682c06a0] + JSON v0.17.1 + [4d1e1d77] + Nullables v0.0.4 + ... +``` + +Both `Random` and `JSON` got added to the project's `Project.toml` file, and the resulting dependencies got added to the `Manifest.toml` file. +The resolver has installed each package with the highest possible version, while still respecting the compatibility that each package enforce on its dependencies. + +We can now use both `Random` and `JSON` in our project. Changing `src/HelloWorld.jl` to + +``` +module HelloWorld + +import Random +import JSON + +greet() = print("Hello World!") +greet_alien() = print("Hello ", Random.randstring(8)) + +end # module +``` + +and reloading the package, the new `greet_alien` function that uses `Random` can be used: + +``` +julia> HelloWorld.greet_alien() +Hello aT157rHV +``` + +Sometimes we might want to use the very latest, unreleased version of a package, or perhaps a specific branch in the package +git repository. We can use e.g. the `master` branch of `JSON` by specifying the branch after a `#` when adding the package: + +``` +pkg> add JSON#master + Cloning package from https://github.com/JuliaIO/JSON.jl.git + Resolving package versions... + Updating "~/Documents/HelloWorld/Project.toml" + [682c06a0] ~ JSON v0.17.1 ⇒ v0.17.1+ #master + Updating "~/Documents/HelloWorld/Manifest.toml" + [682c06a0] ~ JSON v0.17.1 ⇒ v0.17.1+ #master +``` + +If we want to use a package that has not been registered in a registry, we can `add` its git repository url: + +``` +pkg> add https://github.com/fredrikekre/ImportMacros.jl + Cloning package from https://github.com/fredrikekre/ImportMacros.jl + Resolving package versions... +Downloaded MacroTools ─ v0.4.0 + Updating "~/Documents/HelloWorld/Project.toml" + [5adcef86] + ImportMacros v0.1.0 #master + Updating "~/Documents/HelloWorld/Manifest.toml" + [5adcef86] + ImportMacros v0.1.0 #master + [1914dd2f] + MacroTools v0.4.0 +``` + +The dependencies of the unregistered package (here `MacroTools`) got installed. +For unregistered packages we could have given a branch (or commit SHA) to track using `#`, just like for registered packages. + +## Developing packages + +Let's say we found a bug in `JSON` that we want to fix. We can get the full git-repo using the `develop` command + +``` +pkg> develop JSON + Cloning package from https://github.com/JuliaIO/JSON.jl.git + Resolving package versions... + Updating "~/.julia/environments/v0.7/Project.toml" + [682c06a0] + JSON v0.17.1+ [~/.julia/dev/JSON] +... +``` + +By default, the package get cloned to the `~/.julia/dev` folder but can also be set by the `JULIA_PKG_DEVDIR` environment variable. +When we have fixed the bug and checked that `JSON` now works correctly with out project, we can make a PR to the `JSON` repository. +When a new release of `JSON` is made, we can go back to using the versioned `JSON` using the command `free` and `update` (see next section): + +``` +pkg> free JSON + Resolving package versions... + Updating "~/Documents/HelloWorld/Project.toml" + [682c06a0] ~ JSON v0.17.1+ #master ⇒ v0.17.1 + Updating "~/Documents/HelloWorld/Manifest.toml" + [682c06a0] ~ JSON v0.17.1+ #master ⇒ v0.17.1 +``` + +It is also possible to give a local path as the argument to `develop` which will not clone anything but simply use that directory for the package. + +Developing a non registered package is done by giving the git-repo url as an argument to `develop`. + +### Updating dependencies + +When new versions of packages the project is using are released, it is a good idea to update. Simply calling `up` will try to update *all* the dependencies of the project. Sometimes this is not what you want. You can specify a subset of the dependencies to upgrade by giving them as arguments to `up`, e.g: + +``` +pkg> up JSON +``` + +The version of all other dependencies will stay the same. If you only want to update the minor version of packages, to reduce the risk that your project breaks, you can give the `--minor` flag, e.g: + +``` +pkg> up --minor JSON +``` + +Packages that track a branch are not updated when a minor upgrade is done. +Developed packages are never touched by the package manager. + +If you just want install the packages that are given by the current `Manifest.toml` use + +``` +pkg> up --manifest --fixed +``` + +### Preview mode + +If you just want to see the effects of running a command, but not change your state you can `preview` a command. +For example: + +``` +pkg> preview add Plot +``` + +or + +``` +pkg> preview up +``` + +will show you the effects adding `Plots`, or doing a full upgrade, respectively, would have on your project. +However, nothing would be installed and your `Project.toml` and `Manfiest.toml` are untouched. + + +### Using someone elses project. + +Simple clone their project using e.g. `git clone`, `cd` to the project directory and call + +``` +pkg> up --manifest --fixed +``` + +This will install the packages at the same state that the project you cloned was using. From e8cb2eb2627df73abf6e5d89f3ef026d6490a7e1 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Sat, 17 Mar 2018 00:22:02 +0900 Subject: [PATCH 013/153] update Julia Commit 277e6d5570 --- codex/NEWS.md | 11 +- codex/base/base.md | 1 - codex/base/strings.md | 8 +- codex/manual/getting-started.md | 133 +++++++----------- .../integers-and-floating-point-numbers.md | 13 +- codex/manual/strings.md | 12 +- codex/stdlib/LinearAlgebra.md | 6 +- codex/stdlib/linearalgebra.md | 6 +- src/NEWS.md | 11 +- src/base/base.md | 1 - src/base/strings.md | 8 +- src/manual/getting-started.md | 119 ++++++---------- .../integers-and-floating-point-numbers.md | 18 +-- src/manual/strings.md | 12 +- src/stdlib/LinearAlgebra.md | 6 +- src/stdlib/linearalgebra.md | 6 +- 16 files changed, 162 insertions(+), 209 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index 43b4ba9..723afc3 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -562,8 +562,8 @@ Library improvements * `diagm` now accepts several diagonal index/vector `Pair`s ([#24047](https://github.com/JuliaLang/julia/issues/24047)). - * New function `equalto(x)`, which returns a function that compares its argument to `x` - using `isequal` ([#23812](https://github.com/JuliaLang/julia/issues/23812)). + * `isequal`, `==`, and `in` have one argument "curried" forms. For example `isequal(x)` + returns a function that compares its argument to `x` using `isequal` ([#23812](https://github.com/JuliaLang/julia/issues/23812)). * `reinterpret` now works on any AbstractArray using the new `ReinterpretArray` type. This supersedes the old behavior of reinterpret on Arrays. As a result, reinterpreting @@ -1027,7 +1027,7 @@ Deprecated or removed `F.Q` instead of `F[:Q]` ([#25184](https://github.com/JuliaLang/julia/issues/25184)). * `search` and `rsearch` have been deprecated in favor of `findfirst`/`findnext` and - `findlast`/`findprev` respectively, in combination with the new `equalto` and `occursin` + `findlast`/`findprev` respectively, in combination with curried `isequal` and `in` predicates for some methods ([#24673](https://github.com/JuliaLang/julia/issues/24673) * `ismatch(regex, str)` has been deprecated in favor of `contains(str, regex)` ([#24673](https://github.com/JuliaLang/julia/issues/24673)). @@ -1038,7 +1038,7 @@ Deprecated or removed `similar(::Associative, ::Pair{K, V})` has been deprecated in favour of `empty(::Associative, K, V)` ([#24390](https://github.com/JuliaLang/julia/issues/24390)). - * `findin(a, b)` has been deprecated in favor of `findall(occursin(b), a)` ([#24673](https://github.com/JuliaLang/julia/issues/24673)). + * `findin(a, b)` has been deprecated in favor of `findall(in(b), a)` ([#24673](https://github.com/JuliaLang/julia/issues/24673)). * `module_name` has been deprecated in favor of a new, general `nameof` function. Similarly, the unexported `Base.function_name` and `Base.datatype_name` have been deprecated in favor @@ -1104,6 +1104,9 @@ Deprecated or removed `show(IOContext(io, :compact => true), x...)` ([#26080](https://github.com/JuliaLang/julia/issues/26080)). Use `sprint(show, x..., context=:compact => true)` instead of `sprint(showcompact, x...)`. + * `isupper`, `islower`, `ucfirst` and `lcfirst` have been deprecated in favor of `isuppercase`, + `islowercase`, `uppercasefirst` and `lowercasefirst`, respectively ([#26442](https://github.com/JuliaLang/julia/issues/26442)). + Command-line option changes --------------------------- diff --git a/codex/base/base.md b/codex/base/base.md index e62e4c0..f9a8354 100644 --- a/codex/base/base.md +++ b/codex/base/base.md @@ -194,7 +194,6 @@ Base.invokelatest new Base.:(|>) Base.:(∘) -Base.equalto ``` ## Syntax diff --git a/codex/base/strings.md b/codex/base/strings.md index 816f607..35c3405 100644 --- a/codex/base/strings.md +++ b/codex/base/strings.md @@ -53,8 +53,8 @@ Base.last(::AbstractString, ::Integer) Base.uppercase Base.lowercase Base.titlecase -Base.ucfirst -Base.lcfirst +Base.uppercasefirst +Base.lowercasefirst Base.join Base.chop Base.chomp @@ -66,12 +66,12 @@ Base.isalpha Base.isascii Base.iscntrl Base.isdigit -Base.islower +Base.islowercase Base.isnumeric Base.isprint Base.ispunct Base.isspace -Base.isupper +Base.isuppercase Base.isxdigit Core.Symbol Base.escape_string diff --git a/codex/manual/getting-started.md b/codex/manual/getting-started.md index e995f84..f3c4849 100644 --- a/codex/manual/getting-started.md +++ b/codex/manual/getting-started.md @@ -4,29 +4,19 @@ Julia installation is straightforward, whether using precompiled binaries or com Download and install Julia by following the instructions at [https://julialang.org/downloads/](https://julialang.org/downloads/). The easiest way to learn and experiment with Julia is by starting an interactive session (also -known as a read-eval-print loop or "repl") by double-clicking the Julia executable or running +known as a read-eval-print loop or "REPL") by double-clicking the Julia executable or running `julia` from the command line: -``` -$ julia - _ - _ _ _(_)_ | A fresh approach to technical computing - (_) | (_) (_) | Documentation: https://docs.julialang.org - _ _ _| |_ __ _ | Type "?help" for help. - | | | | | | |/ _` | | - | | |_| | | | (_| | | Version 0.5.0-dev+2440 (2016-02-01 02:22 UTC) - _/ |\__'_|_|_|\__'_| | Commit 2bb94d6 (11 days old master) -|__/ | x86_64-apple-darwin13.1.0 - -julia> 1 + 2 -3 - -julia> ans -3 +```@eval +io = IOBuffer() +Base.banner(io) +banner = String(take!(io)) +import Markdown +Markdown.parse("```\n\$ julia\n\n$(banner)\njulia> 1 + 2\n3\n\njulia> ans\n3\n```") ``` -To exit the interactive session, type `^D` -- the control key together with the `d` key or type -`quit()`. When run in interactive mode, `julia` displays a banner and prompts the user for input. +To exit the interactive session, type `CTRL-D` (press the Control/`^` key together with the `d` key), or type +`exit()`. When run in interactive mode, `julia` displays a banner and prompts the user for input. Once the user has entered a complete expression, such as `1 + 2`, and hits enter, the interactive session evaluates the expression and shows its value. If an expression is entered into an interactive session with a trailing semicolon, its value is not shown. The variable `ans` is bound to the @@ -42,11 +32,12 @@ command: $ julia script.jl arg1 arg2... ``` -As the example implies, the following command-line arguments to `julia` are taken as command-line -arguments to the program `script.jl`, passed in the global constant `ARGS`. The name of the script -itself is passed in as the global `PROGRAM_FILE`. Note that `ARGS` is also set when script code -is given using the `-e` option on the command line (see the `julia` help output below) but `PROGRAM_FILE` -will be empty. For example, to just print the arguments given to a script, you could do this: +As the example implies, the following command-line arguments to `julia` are interpreted as +command-line arguments to the program `script.jl`, passed in the global constant `ARGS`. The +name of the script itself is passed in as the global `PROGRAM_FILE`. Note that `ARGS` is +also set when a Julia expression is given using the `-e` option on the command line (see the +`julia` help output below) but `PROGRAM_FILE` will be empty. For example, to just print the +arguments given to a script, you could do this: ``` $ julia -e 'println(PROGRAM_FILE); for x in ARGS; println(x); end' foo bar @@ -65,7 +56,7 @@ foo bar ``` -The `--` delimiter can be used to separate command-line args to the scriptfile from args to Julia: +The `--` delimiter can be used to separate command-line arguments intended for the script file from arguments intended for Julia: ``` $ julia --color=yes -O -- foo.jl arg1 arg2.. @@ -73,11 +64,11 @@ $ julia --color=yes -O -- foo.jl arg1 arg2.. Julia can be started in parallel mode with either the `-p` or the `--machine-file` options. `-p n` will launch an additional `n` worker processes, while `--machine-file file` will launch a worker -for each line in file `file`. The machines defined in `file` must be accessible via a passwordless +for each line in file `file`. The machines defined in `file` must be accessible via a password-less `ssh` login, with Julia installed at the same location as the current host. Each machine definition -takes the form `[count*][user@]host[:port] [bind_addr[:port]]` . `user` defaults to current user, +takes the form `[count*][user@]host[:port] [bind_addr[:port]]`. `user` defaults to current user, `port` to the standard ssh port. `count` is the number of workers to spawn on the node, and defaults -to 1. The optional `bind-to bind_addr[:port]` specifies the ip-address and port that other workers +to 1. The optional `bind-to bind_addr[:port]` specifies the IP address and port that other workers should use to connect to this worker. If you have code that you want executed whenever Julia is run, you can put it in @@ -96,59 +87,41 @@ There are various ways to run Julia code and provide options, similar to those a ``` julia [switches] -- [programfile] [args...] - -v, --version Display version information - -h, --help Print this message - - -J, --sysimage Start up with the given system image file - -H, --home Set location of `julia` executable - --startup-file={yes|no} Load `~/.julia/config/startup.jl` - --handle-signals={yes|no} Enable or disable Julia's default signal handlers - --sysimage-native-code={yes|no} - Use native code from system image if available - --compiled-modules={yes|no} - Enable or disable incremental precompilation of modules - - -e, --eval Evaluate - -E, --print Evaluate and display the result - -L, --load Load immediately on all processors - - -p, --procs {N|auto} Integer value N launches N additional local worker processes - "auto" launches as many workers as the number of local cores - --machine-file Run processes on hosts listed in - - -i Interactive mode; REPL runs and isinteractive() is true - -q, --quiet Quiet startup: no banner, suppress REPL warnings - --banner={yes|no|auto} Enable or disable startup banner - --color={yes|no|auto} Enable or disable color text - --history-file={yes|no} Load or save history - - --depwarn={yes|no|error} Enable or disable syntax and method deprecation warnings ("error" turns warnings into errors) - --warn-overwrite={yes|no} Enable or disable method overwrite warnings - - -C, --cpu-target Limit usage of cpu features up to ; set to "help" to see the available options - -O, --optimize={0,1,2,3} Set the optimization level (default level is 2 if unspecified or 3 if used without a level) - -g, -g Enable / Set the level of debug info generation (default level is 1 if unspecified or 2 if used without a level) - --inline={yes|no} Control whether inlining is permitted, including overriding @inline declarations - --check-bounds={yes|no} Emit bounds checks always or never (ignoring declarations) - --math-mode={ieee,fast} Disallow or enable unsafe floating point optimizations (overrides @fastmath declaration) - - --code-coverage={none|user|all}, --code-coverage - Count executions of source lines (omitting setting is equivalent to "user") - --track-allocation={none|user|all}, --track-allocation - Count bytes allocated by each source line ``` +|Switch |Description| +|:--- |:---| +|`-v`, `--version` |Display version information| +|`-h`, `--help` |Print this message| +|`-J`, `--sysimage ` |Start up with the given system image file| +|`-H`, `--home ` |Set location of `julia` executable| +|`--startup-file={yes\|no}` |Load `~/.julia/config/startup.jl`| +|`--handle-signals={yes\|no}` |Enable or disable Julia's default signal handlers| +|`--sysimage-native-code={yes\|no}` |Use native code from system image if available| +|`--compiled-modules={yes\|no}` |Enable or disable incremental precompilation of modules| +|`-e`, `--eval ` |Evaluate ``| +|`-E`, `--print ` |Evaluate `` and display the result| +|`-L`, `--load ` |Load `` immediately on all processors| +|`-p`, `--procs {N\|auto`} |Integer value N launches N additional local worker processes; `auto` launches as many workers as the number of local cores| +|`--machine-file ` |Run processes on hosts listed in ``| +|`-i` |Interactive mode; REPL runs and `isinteractive()` is true| +|`-q`, `--quiet` |Quiet startup: no banner, suppress REPL warnings| +|`--banner={yes\|no\|auto}` |Enable or disable startup banner| +|`--color={yes\|no\|auto}` |Enable or disable color text| +|`--history-file={yes\|no}` |Load or save history| +|`--depwarn={yes\|no\|error}` |Enable or disable syntax and method deprecation warnings (`error` turns warnings into errors)| +|`--warn-overwrite={yes\|no}` |Enable or disable method overwrite warnings| +|`-C`, `--cpu-target ` |Limit usage of cpu features up to ; set to `help` to see the available options| +|`-O`, `--optimize={0,1,2,3}` |Set the optimization level (default level is 2 if unspecified or 3 if used without a level)| +|`-g`, `-g ` |Enable / Set the level of debug info generation (default level is 1 if unspecified or 2 if used without a level)| +|`--inline={yes\|no}` |Control whether inlining is permitted, including overriding `@inline` declarations| +|`--check-bounds={yes\|no}` |Emit bounds checks always or never (ignoring declarations)| +|`--math-mode={ieee,fast}` |Disallow or enable unsafe floating point optimizations (overrides @fastmath declaration)| +|`--code-coverage={none\|user\|all}` |Count executions of source lines| +|`--code-coverage` |equivalent to `--code-coverage=user`| +|`--track-allocation={none\|user\|all}` |Count bytes allocated by each source line| +|`--track-allocation` |equivalent to `--track-allocation=user`| + ## Resources -In addition to this manual, there are various other resources that may help new users get started -with Julia: - - * [Julia and IJulia cheatsheet](http://math.mit.edu/~stevenj/Julia-cheatsheet.pdf) - * [Learn Julia in a few minutes](https://learnxinyminutes.com/docs/julia/) - * [Learn Julia the Hard Way](https://github.com/chrisvoncsefalvay/learn-julia-the-hard-way) - * [Julia by Example](http://samuelcolvin.github.io/JuliaByExample/) - * [Hands-on Julia](https://github.com/dpsanders/hands_on_julia) - * [Tutorial for Homer Reid's numerical analysis class](http://homerreid.dyndns.org/teaching/18.330/JuliaProgramming.shtml) - * [An introductory presentation](https://raw.githubusercontent.com/ViralBShah/julia-presentations/master/Fifth-Elephant-2013/Fifth-Elephant-2013.pdf) - * [Videos from the Julia tutorial at MIT](https://julialang.org/blog/2013/03/julia-tutorial-MIT) - * [YouTube videos from the JuliaCons](https://www.youtube.com/user/JuliaLanguage/playlists) +A curated list of useful learning resources to help new users get started can be found on the [learning](https://julialang.org/learning/) page of the main Julia web site. diff --git a/codex/manual/integers-and-floating-point-numbers.md b/codex/manual/integers-and-floating-point-numbers.md index b1295d1..80b0092 100644 --- a/codex/manual/integers-and-floating-point-numbers.md +++ b/codex/manual/integers-and-floating-point-numbers.md @@ -338,7 +338,7 @@ julia> 10_000, 0.000_000_005, 0xdead_beef, 0b1011_0010 Floating-point numbers have [two zeros](https://en.wikipedia.org/wiki/Signed_zero), positive zero and negative zero. They are equal to each other but have different binary representations, as -can be seen using the `bits` function: +can be seen using the [`bitstring`](@ref) function: ```jldoctest julia> 0.0 == -0.0 @@ -491,9 +491,10 @@ also have adjacent binary integer representations. ### Rounding modes -If a number doesn't have an exact floating-point representation, it must be rounded to an appropriate -representable value, however, if wanted, the manner in which this rounding is done can be changed -according to the rounding modes presented in the [IEEE 754 standard](https://en.wikipedia.org/wiki/IEEE_754-2008). +If a number doesn't have an exact floating-point representation, it must be rounded to an +appropriate representable value. However, the manner in which this rounding is done can be +changed if required according to the rounding modes presented in the [IEEE 754 +standard](https://en.wikipedia.org/wiki/IEEE_754-2008). ```jldoctest julia> x = 1.1; y = 0.1; @@ -613,7 +614,7 @@ julia> setprecision(40) do ## [Numeric Literal Coefficients](@id man-numeric-literal-coefficients) -To make common numeric formulas and expressions clearer, Julia allows variables to be immediately +To make common numeric formulae and expressions clearer, Julia allows variables to be immediately preceded by a numeric literal, implying multiplication. This makes writing polynomial expressions much cleaner: @@ -689,7 +690,7 @@ where syntactic conflicts arise: * The floating-point literal expression `1e10` could be interpreted as the numeric literal `1` multiplied by the variable `e10`, and similarly with the equivalent `E` form. -In both cases, we resolve the ambiguity in favor of interpretation as a numeric literals: +In both cases, we resolve the ambiguity in favor of interpretation as numeric literals: * Expressions starting with `0x` are always hexadecimal literals. * Expressions starting with a numeric literal followed by `e` or `E` are always floating-point literals. diff --git a/codex/manual/strings.md b/codex/manual/strings.md index 68c2ccf..6887919 100644 --- a/codex/manual/strings.md +++ b/codex/manual/strings.md @@ -515,26 +515,26 @@ true You can search for the index of a particular character using the [`findfirst`](@ref) function: ```jldoctest -julia> findfirst(equalto('x'), "xylophone") +julia> findfirst(isequal('x'), "xylophone") 1 -julia> findfirst(equalto('p'), "xylophone") +julia> findfirst(isequal('p'), "xylophone") 5 -julia> findfirst(equalto('z'), "xylophone") +julia> findfirst(isequal('z'), "xylophone") ``` You can start the search for a character at a given offset by using [`findnext`](@ref) with a third argument: ```jldoctest -julia> findnext(equalto('o'), "xylophone", 1) +julia> findnext(isequal('o'), "xylophone", 1) 4 -julia> findnext(equalto('o'), "xylophone", 5) +julia> findnext(isequal('o'), "xylophone", 5) 7 -julia> findnext(equalto('o'), "xylophone", 8) +julia> findnext(isequal('o'), "xylophone", 8) ``` You can use the [`contains`](@ref) function to check if a substring is contained in a string: diff --git a/codex/stdlib/LinearAlgebra.md b/codex/stdlib/LinearAlgebra.md index e46e75e..8ccffe5 100644 --- a/codex/stdlib/LinearAlgebra.md +++ b/codex/stdlib/LinearAlgebra.md @@ -5,7 +5,7 @@ DocTestSetup = :(using LinearAlgebra) ``` In addition to (and as part of) its support for multi-dimensional arrays, Julia provides native implementations -of many common and useful linear algebra operations. Basic operations, such as [`trace`](@ref), [`det`](@ref), +of many common and useful linear algebra operations. Basic operations, such as [`tr`](@ref), [`det`](@ref), and [`inv`](@ref) are all supported: ```jldoctest @@ -15,7 +15,7 @@ julia> A = [1 2 3; 4 1 6; 7 8 1] 4 1 6 7 8 1 -julia> trace(A) +julia> tr(A) 3 julia> det(A) @@ -371,7 +371,7 @@ LinearAlgebra.normalize! LinearAlgebra.normalize LinearAlgebra.cond LinearAlgebra.condskeel -LinearAlgebra.trace +LinearAlgebra.tr LinearAlgebra.det LinearAlgebra.logdet LinearAlgebra.logabsdet diff --git a/codex/stdlib/linearalgebra.md b/codex/stdlib/linearalgebra.md index e46e75e..8ccffe5 100644 --- a/codex/stdlib/linearalgebra.md +++ b/codex/stdlib/linearalgebra.md @@ -5,7 +5,7 @@ DocTestSetup = :(using LinearAlgebra) ``` In addition to (and as part of) its support for multi-dimensional arrays, Julia provides native implementations -of many common and useful linear algebra operations. Basic operations, such as [`trace`](@ref), [`det`](@ref), +of many common and useful linear algebra operations. Basic operations, such as [`tr`](@ref), [`det`](@ref), and [`inv`](@ref) are all supported: ```jldoctest @@ -15,7 +15,7 @@ julia> A = [1 2 3; 4 1 6; 7 8 1] 4 1 6 7 8 1 -julia> trace(A) +julia> tr(A) 3 julia> det(A) @@ -371,7 +371,7 @@ LinearAlgebra.normalize! LinearAlgebra.normalize LinearAlgebra.cond LinearAlgebra.condskeel -LinearAlgebra.trace +LinearAlgebra.tr LinearAlgebra.det LinearAlgebra.logdet LinearAlgebra.logabsdet diff --git a/src/NEWS.md b/src/NEWS.md index 315d250..e0d2227 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -550,8 +550,8 @@ Library improvements * `diagm` now accepts several diagonal index/vector `Pair`s ([#24047](https://github.com/JuliaLang/julia/issues/24047)). - * New function `equalto(x)`, which returns a function that compares its argument to `x` - using `isequal` ([#23812](https://github.com/JuliaLang/julia/issues/23812)). + * `isequal`, `==`, and `in` have one argument "curried" forms. For example `isequal(x)` + returns a function that compares its argument to `x` using `isequal` ([#23812](https://github.com/JuliaLang/julia/issues/23812)). * `reinterpret` now works on any AbstractArray using the new `ReinterpretArray` type. This supersedes the old behavior of reinterpret on Arrays. As a result, reinterpreting @@ -1015,7 +1015,7 @@ Deprecated or removed `F.Q` instead of `F[:Q]` ([#25184](https://github.com/JuliaLang/julia/issues/25184)). * `search` and `rsearch` have been deprecated in favor of `findfirst`/`findnext` and - `findlast`/`findprev` respectively, in combination with the new `equalto` and `occursin` + `findlast`/`findprev` respectively, in combination with curried `isequal` and `in` predicates for some methods ([#24673](https://github.com/JuliaLang/julia/issues/24673) * `ismatch(regex, str)` has been deprecated in favor of `contains(str, regex)` ([#24673](https://github.com/JuliaLang/julia/issues/24673)). @@ -1026,7 +1026,7 @@ Deprecated or removed `similar(::Associative, ::Pair{K, V})` has been deprecated in favour of `empty(::Associative, K, V)` ([#24390](https://github.com/JuliaLang/julia/issues/24390)). - * `findin(a, b)` has been deprecated in favor of `findall(occursin(b), a)` ([#24673](https://github.com/JuliaLang/julia/issues/24673)). + * `findin(a, b)` has been deprecated in favor of `findall(in(b), a)` ([#24673](https://github.com/JuliaLang/julia/issues/24673)). * `module_name` has been deprecated in favor of a new, general `nameof` function. Similarly, the unexported `Base.function_name` and `Base.datatype_name` have been deprecated in favor @@ -1092,6 +1092,9 @@ Deprecated or removed `show(IOContext(io, :compact => true), x...)` ([#26080](https://github.com/JuliaLang/julia/issues/26080)). Use `sprint(show, x..., context=:compact => true)` instead of `sprint(showcompact, x...)`. + * `isupper`, `islower`, `ucfirst` and `lcfirst` have been deprecated in favor of `isuppercase`, + `islowercase`, `uppercasefirst` and `lowercasefirst`, respectively ([#26442](https://github.com/JuliaLang/julia/issues/26442)). + Command-line option changes --------------------------- diff --git a/src/base/base.md b/src/base/base.md index e62e4c0..f9a8354 100644 --- a/src/base/base.md +++ b/src/base/base.md @@ -194,7 +194,6 @@ Base.invokelatest new Base.:(|>) Base.:(∘) -Base.equalto ``` ## Syntax diff --git a/src/base/strings.md b/src/base/strings.md index 816f607..35c3405 100644 --- a/src/base/strings.md +++ b/src/base/strings.md @@ -53,8 +53,8 @@ Base.last(::AbstractString, ::Integer) Base.uppercase Base.lowercase Base.titlecase -Base.ucfirst -Base.lcfirst +Base.uppercasefirst +Base.lowercasefirst Base.join Base.chop Base.chomp @@ -66,12 +66,12 @@ Base.isalpha Base.isascii Base.iscntrl Base.isdigit -Base.islower +Base.islowercase Base.isnumeric Base.isprint Base.ispunct Base.isspace -Base.isupper +Base.isuppercase Base.isxdigit Core.Symbol Base.escape_string diff --git a/src/manual/getting-started.md b/src/manual/getting-started.md index 50caf22..087956e 100644 --- a/src/manual/getting-started.md +++ b/src/manual/getting-started.md @@ -5,26 +5,16 @@ Julia를 처음 접할 때는 대화형 실행 환경을 통해서 시작하는 것이 가장 쉽게 Julia를 익힐 수 있는 방법이다. 대화형 실행 환경은 단순히 Julia 실행파일을 더블 클릭하거나, 명령창에서 `julia` 명령어를 입력하여 실행할 수 있다. -``` -$ julia - _ - _ _ _(_)_ | A fresh approach to technical computing - (_) | (_) (_) | Documentation: https://docs.julialang.org - _ _ _| |_ __ _ | Type "?help" for help. - | | | | | | |/ _` | | - | | |_| | | | (_| | | Version 0.5.0-dev+2440 (2016-02-01 02:22 UTC) - _/ |\__'_|_|_|\__'_| | Commit 2bb94d6 (11 days old master) -|__/ | x86_64-apple-darwin13.1.0 - -julia> 1 + 2 -3 - -julia> ans -3 +```@eval +io = IOBuffer() +Base.banner(io) +banner = String(take!(io)) +import Markdown +Markdown.parse("```\n\$ julia\n\n$(banner)\njulia> 1 + 2\n3\n\njulia> ans\n3\n```") ``` -대화형 실행 환경을 종료하기 위해서는 `^D`(컨트롤 키와 `d` 키를 함께 누른다.) 를 입력하거나 -`quit()`를 대화형 실행 환경 입력창에 타이핑한다. 대화형 실행 환경을 실행하면, 위와 같이 `julia` 배너가 보여지고, 커서창이 사용자의 입력을 기다리며 깜빡이고 있다. 사용자가 `1 + 2`, 와 같은 표현식을 입력한 뒤, 엔터 버튼을 누르는 순간, Julia는 표현식을 평가하고 그 결과를 보여준다. 만약 사용자가 입력한 표현식이 세미콜론(;)으로 끝난다면, 대화형 실행 환경은 결과를 바로 보여주지 않는다. 대신에 `ans` 라는 변수가 결과를 보여주든 보여주지 않든 가장 마지막으로 계산된 표현식의 결과를 저장하고 있다 `ans` 변수는 대화형 실행 환경에서만 존재하며, 다른 방식으로 동작하는 Julia 코드 상에서는 나타나지 않는다. +대화형 실행 환경을 종료하기 위해서는 `CTRL-D`(컨트롤/`^` 키와 `d` 키를 함께 누른다) 를 입력하거나 +`exit()`를 대화형 실행 환경 입력창에 타이핑한다. 대화형 실행 환경을 실행하면, 위와 같이 `julia` 배너가 보여지고, 커서창이 사용자의 입력을 기다리며 깜빡이고 있다. 사용자가 `1 + 2`, 와 같은 표현식을 입력한 뒤, 엔터 버튼을 누르는 순간, Julia는 표현식을 평가하고 그 결과를 보여준다. 만약 사용자가 입력한 표현식이 세미콜론(;)으로 끝난다면, 대화형 실행 환경은 결과를 바로 보여주지 않는다. 대신에 `ans` 라는 변수가 결과를 보여주든 보여주지 않든 가장 마지막으로 계산된 표현식의 결과를 저장하고 있다 `ans` 변수는 대화형 실행 환경에서만 존재하며, 다른 방식으로 동작하는 Julia 코드 상에서는 나타나지 않는다. `file.jl`라는 소스 파일에 저장되어 있는 표현식을 계산하기 위해서는, `include("file.jl")`와 같이 입력한다. @@ -36,7 +26,7 @@ julia> ans $ julia script.jl arg1 arg2... ``` -예제와 같이`julia` 실행 명령 뒤에 오는 매개변수들은 전역 상수 `ARGS`라고 불리우는 `script.jl`라는 프로그램의 명령줄 인자로 작동한다. 이 프로그램의 이름은 전역 상수 `PROGRAM_FILE` 에도 설정된다. 또한 `ARGS`는 이 뿐만이 아니라`-e` 옵션을 통해서 julia 스크립트를 실행할 때도 설정할 수 있음을 알 필요가 있다. 그러나 이 경우에는 `PROGRAM_FILE` 은 아무것도 설정되지 않은 채로 실행될 것이다.(아래의 `julia` 도움말을 보도록 하자.) 예를 들어, 단순히 스크립트에 주어진 명령줄 인자를 출력할 때는 다음과 같이 입력하면 된다. +예제와 같이 `julia` 실행 명령 뒤에 오는 매개변수들은 전역 상수 `ARGS`라고 불리우는 `script.jl`라는 프로그램의 명령줄 인자로 작동한다. 이 프로그램의 이름은 전역 상수 `PROGRAM_FILE` 에도 설정된다. 또한 `ARGS`는 이 뿐만이 아니라`-e` 옵션을 통해서 julia 스크립트를 실행할 때도 설정할 수 있음을 알 필요가 있다. 그러나 이 경우에는 `PROGRAM_FILE` 은 아무것도 설정되지 않은 채로 실행될 것이다.(아래의 `julia` 도움말을 보도록 하자.) 예를 들어, 단순히 스크립트에 주어진 명령줄 인자를 출력할 때는 다음과 같이 입력하면 된다. ``` $ julia -e 'println(PROGRAM_FILE); for x in ARGS; println(x); end' foo bar @@ -61,7 +51,7 @@ bar $ julia --color=yes -O -- foo.jl arg1 arg2.. ``` -Julia는 `-p` 옵션이나 `--machine-file` 옵션을 이용하여 병렬 환경에서 실행시킬 수 있다. `-p n` 옵션은 n개의 worker 프로세스를 생성하지만, `--machine-file file` 옵션은 file의 각 행에 지정된 노드마다 worker를 생성한다. `file` 에 지정된 노드(machine)들은 `ssh` 로그인을 통해 패스워드가 필요없이 실행할 수 있어야 하며, Julia는 현재 호스트와 같은 경로에 설치가 되어 있어야 한다. `file` 에 작성되는 노드는 `[count*][user@]host[:port] [bind_addr[:port]]` 와 같은 형식으로 작성한다. `user` 는 현재 user id를 나타내고, `port` 는 기본 ssh port, `count` 는 각 노드당 생성하는 worker의 개수 (기본값 : 1) `bin-to bind_addr[:port]` 은 선택적인 옵션으로 다른 worker들이 현재의 worker로 연결하기 위해 필요한 특정 ip 주소와 포트를 지정한다. +Julia는 `-p` 옵션이나 `--machine-file` 옵션을 이용하여 병렬 환경에서 실행시킬 수 있다. `-p n` 옵션은 n개의 worker 프로세스를 생성하지만, `--machine-file file` 옵션은 file의 각 행에 지정된 노드마다 worker를 생성한다. `file` 에 지정된 노드(machine)들은 `ssh` 로그인을 통해 패스워드가 필요없이 실행할 수 있어야 하며, Julia는 현재 호스트와 같은 경로에 설치가 되어 있어야 한다. `file` 에 작성되는 노드는 `[count*][user@]host[:port] [bind_addr[:port]]` 와 같은 형식으로 작성한다. `user` 는 현재 user id를 나타내고, `port` 는 기본 ssh port, `count` 는 각 노드당 생성하는 worker의 개수 (기본값 : 1) `bin-to bind_addr[:port]` 은 선택적인 옵션으로 다른 worker들이 현재의 worker로 연결하기 위해 필요한 특정 IP 주소와 포트를 지정한다. 만약 Julia가 실행할 때마다 실행되는 코드가 있다면, 그 코드를 `~/.juliarc.ji` 에 넣으면 된다. @@ -77,58 +67,41 @@ Greetings! 你好! 안녕하세요? ``` julia [switches] -- [programfile] [args...] - -v, --version 버전 정보를 표시한다. - -h, --help 이 메세지를 표시한다. - - -J, --sysimage 이라는 시스템 이미지 파일을 로드한 뒤 실행한다. - -H, --home julia 실행파일의 위치를 지정한다. - --startup-file={yes|no} `~/.julia/config/startup.jl` 를 불러온다. - --handle-signals={yes|no} Julia의 기본 시그널 핸들러를 켜거나 끈다. - --sysimage-native-code={yes|no} - 시스템 이미지의 기존 코드 사용/사용하지 않는다. - --compiled-modules={yes|no} - 모듈의 사전 증분 컴파일을 활성화/비활성화 한다. - - -e, --eval 를 실행만 한다 - -E, --print 를 실행하고 표시한다. - -L, --load 을 모든 프로세서에 로드한다. - - -p, --procs {N|auto} N개의 worker 프로세스를 추가로 생성한다. "auto"는 현재 Julia를 실행하는 컴퓨터의 최대 코어수만큼 worker 프로세스를 생성한다. - - --machine-file 에 나열된 호스트에서 worker 프로세스를 실행한다. - - -i 대화형 모드; PEPL을 돌리며 ininteractive()는 true이다. - -q, --quiet 시작할 때 배너, REPL 경고를 제거한다. - --banner={yes|no|auto} 시작 배너 사용/사용하지 않는다. - --color={yes|no|auto} 모든 텍스트에 색상을 표시하거나 표시하지 않는다. - --history-file={yes|no} 작업내역을 저장하거나 로드한다. - - --depwarn={yes|no|error} 문법과 함수가 폐기됐다는 경고를 활성화/비활성화 한다.("error"는 경고를 에러로 바꾼다.) - --warn-overwrite={yes|no} 메소드 오버라이딩 경고를 활성화/비활성화 한다. - - -C, --cpu-target 까지의 CUPU기능만을 사용한다() 사용 가능한 옵션을 보려면 "help"로 설정) - -O, --optimize={0,1,2,3} 코드 실행시간에 관련된 최적화를 실행한다.(지정되지 않을 경우 2단계 실행, 레벨 이외의 값을 사용할 경우 3단계 실행) - -g, -g 디버그 정보 생성 수준을 활성화/비활성화 합니다.(지정되지 않을 경우 레벨 1, 레벨 이외의 값을 사용할 경우 레벨 2) - --inline={yes|no} @inline으로 선언된 함수를 덮어쓰는 경우를 포함해서, inlining을 허용할지 결정한다. - --check-bounds={yes|no} 배열의 경계 체크를 항상 실행/생략한다. (변수 선언을 무시) - --math-mode={ieee,fast} IEEE 부동소수점 표준을 쓰거나(변수 선언을 무시) 소스에서 선언된 부동소수점을 따른다. - - --code-coverage={none|user|all}, --code-coverage - 소스 코드 라인의 실행 횟수를 기록한다. (기본값:"user") - --track-allocation={none|user|all}, --track-allocation - 각 소스 코드 라인에 의해 할당되는 바이트 수를 기록한다. ``` -## 읽을거리 - -이 매뉴얼 뿐만 아니라 Julia를 처음 접하는 사용자들에게 도움을 줄 수 있는 다른 문서를 소개한다. - - * [Julia and IJulia cheatsheet](http://math.mit.edu/~stevenj/Julia-cheatsheet.pdf) - * [Learn Julia in a few minutes](https://learnxinyminutes.com/docs/julia/) - * [Learn Julia the Hard Way](https://github.com/chrisvoncsefalvay/learn-julia-the-hard-way) - * [Julia by Example](http://samuelcolvin.github.io/JuliaByExample/) - * [Hands-on Julia](https://github.com/dpsanders/hands_on_julia) - * [Tutorial for Homer Reid's numerical analysis class](http://homerreid.dyndns.org/teaching/18.330/JuliaProgramming.shtml) - * [An introductory presentation](https://raw.githubusercontent.com/ViralBShah/julia-presentations/master/Fifth-Elephant-2013/Fifth-Elephant-2013.pdf) - * [Videos from the Julia tutorial at MIT](https://julialang.org/blog/2013/03/julia-tutorial-MIT) - * [YouTube videos from the JuliaCons](https://www.youtube.com/user/JuliaLanguage/playlists) +|스위치 |설명| +|:--- |:---| +|`-v`, `--version` |버전 정보를 표시한다| +|`-h`, `--help` |이 메세지를 표시한다| +|`-J`, `--sysimage ` |주어진 시스템 이미지 파일로 실행한다| +|`-H`, `--home ` |`julia` 실행파일의 위치를 지정한다| +|`--startup-file={yes\|no}` |`~/.julia/config/startup.jl` 를 불러온다| +|`--handle-signals={yes\|no}` |Julia의 기본 시그널 핸들러를 켜거나 끈다| +|`--sysimage-native-code={yes\|no}` |시스템 이미지의 기존 코드 사용/사용하지 않는다| +|`--compiled-modules={yes\|no}` |모듈의 사전 증분 컴파일을 활성화/비활성화 한다| +|`-e`, `--eval ` |``를 실행만 한다| +|`-E`, `--print ` |``를 실행하고 결과를 표시한다| +|`-L`, `--load ` |``을 모든 프로세서에 로드한다| +|`-p`, `--procs {N\|auto`} |N개의 worker 프로세스를 추가로 생성한다; `auto`는 현재 컴퓨터의 최대 코어수만큼 worker 프로세스를 생성한다| +|`--machine-file ` |``에 나열된 호스트에서 worker 프로세스를 실행한다| +|`-i` |대화형 모드; PEPL을 돌리며 `ininteractive()`는 true이다| +|`-q`, `--quiet` |깔끔히 시작하기: 배너 없이, REPL 경고도 안 보여준다| +|`--banner={yes\|no\|auto}` |시작 배너 사용/사용하지 않는다| +|`--color={yes\|no\|auto}` |모든 텍스트에 색상을 표시하거나 표시하지 않는다| +|`--history-file={yes\|no}` |작업내역을 저장하거나 로드한다| +|`--depwarn={yes\|no\|error}` |문법과 함수가 폐기됐다는 경고를 활성화/비활성화 한다 (`error`는 경고를 에러로 바꾼다)| +|`--warn-overwrite={yes\|no}` |메소드 오버라이딩 경고를 활성화/비활성화 한다| +|`-C`, `--cpu-target ` |까지의 CUPU기능만을 사용한다; 사용 가능한 옵션을 보려면 `help`로 설정| +|`-O`, `--optimize={0,1,2,3}` |코드 실행시간에 관련된 최적화를 실행한다 (지정되지 않을 경우 2단계 실행, 레벨 이외의 값을 사용할 경우 3단계 실행)| +|`-g`, `-g ` |디버그 정보 생성 수준을 활성화/비활성화 합니다 (지정되지 않을 경우 레벨 1, 레벨 이외의 값을 사용할 경우 레벨 2)| +|`--inline={yes\|no}` |`@inline`으로 선언된 함수를 덮어쓰는 경우를 포함해서, 인라이닝을 허용할지 결정한다| +|`--check-bounds={yes\|no}` |배열의 경계 체크를 항상 실행/생략한다 (변수 선언을 무시)| +|`--math-mode={ieee,fast}` |unsafe 부동소수점 최적화를 끄거나 켠다 (@fastmath 선언을 오버라이드한다)| +|`--code-coverage={none\|user\|all}` |소스 코드 라인의 실행 횟수를 기록한다| +|`--code-coverage` |`--code-coverage=user`와 같다| +|`--track-allocation={none\|user\|all}` |각 소스 코드 라인에 의해 할당되는 바이트 수를 기록한다| +|`--track-allocation` |`--track-allocation=user`와 같다| + +## 참고 자료 + +줄리아 웹사이트의 [배우기](https://juliakorea.github.io/learning/) 페이지에 사용자가 보면 유용한 자료를 엄선하여 모아두었다. diff --git a/src/manual/integers-and-floating-point-numbers.md b/src/manual/integers-and-floating-point-numbers.md index 00dd816..340b04e 100644 --- a/src/manual/integers-and-floating-point-numbers.md +++ b/src/manual/integers-and-floating-point-numbers.md @@ -311,7 +311,8 @@ julia> 10_000, 0.000_000_005, 0xdead_beef, 0b1011_0010 ### 실수로서의 숫자 0 -부동 소수점은 양수 0과 음수 0으로 불리는 [두 개의 0](https://en.wikipedia.org/wiki/Signed_zero)을 가진다. 그 둘은 값은 0으로써 같지만, 다음과 같이 `bits`함수를 잉ㅇ하면 알 수 있듯이, 바이너리로 표기했을 때 다르다는 것을 알 수 있다: +부동 소수점은 양수 0과 음수 0으로 불리는 [두 개의 0](https://en.wikipedia.org/wiki/Signed_zero)을 가진다. +그 둘은 값은 0으로써 같지만, 다음과 같이 [`bitstring`](@ref) 함수를 사용하면, 바이너리로 표기했을 때와 차이를 알 수 있다: ```jldoctest julia> 0.0 == -0.0 @@ -446,9 +447,10 @@ julia> bitstring(nextfloat(x)) 위의 예제는 서로 이웃한 표현 가능한 부동 소수점 수는 바이너리 정수 표기법을 가질 수 있다는 기본적인 원리를 새삼 일깨워준다. -### 반올림 모드 +### 라운딩 모드 -만약 어떤 숫자가 정확한 부동 소수점 표현을 가지고 있지 않다면, 그 수는 반드시 어떤 표현 가능한 값으로 반올림되어야 한다. 그러나, 만약 사용자가 원한다면[IEEE 754 standard](https://en.wikipedia.org/wiki/IEEE_754-2008)에 따라 반올림 방식을 변경할 수 있다. +만약 어떤 숫자가 정확한 부동 소수점 표현을 가지고 있지 않다면, 그 수는 반드시 어떤 표현 가능한 값으로 라운딩 되어야 한다. +[IEEE 754 표준](https://en.wikipedia.org/wiki/IEEE_754-2008)에 나오는 라운딩 모드로 라운딩 방식을 바꿀 수 있다. ```jldoctest julia> x = 1.1; y = 0.1; @@ -456,17 +458,17 @@ julia> x = 1.1; y = 0.1; julia> x + y 1.2000000000000002 -julia> setrounding(Float64,RoundDown) do +julia> setrounding(Float64, RoundDown) do x + y end 1.2 ``` -기본 반올림 모드는 항상 [`RoundNearest`](@ref)이다. 이는 가장 근접한 표현 가능한 값으로 반올림 하지만, 만약 두 표현 값 중간에 주어진 값이 걸쳐 있으면 가수부 값 중 짝수(바이너리 임으로 0)로 반올림 하는 모드이다. +기본 라운딩 모드는 항상 [`RoundNearest`](@ref)이다. 이는 가장 근접한 표현 가능한 값으로 라운딩 하지만, 만약 두 표현 값 중간에 주어진 값이 걸쳐 있으면 가수부 값 중 짝수(바이너리 임으로 0)로 라운딩 하는 모드이다. !!! 경고 - : 반올림은 일반적으로 기본 산술 함수([`+`](@ref), [`-`](@ref), - [`*`](@ref), [`/`](@ref), [`sqrt`](@ref))와 타입 변환 연산에서만 정확하다. 많은 다른 함수들은 기본 값인 [`RoundNearest`](@ref)를 가정하고 짜여져 있고, 이는 다른 반올림 모드에서는 부정확한 값을 제공할 수 있다. + : 라운딩은 일반적으로 기본 산술 함수([`+`](@ref), [`-`](@ref), + [`*`](@ref), [`/`](@ref), [`sqrt`](@ref))와 타입 변환 연산에서만 정확하다. 많은 다른 함수들은 기본 값인 [`RoundNearest`](@ref)를 가정하고 짜여져 있고, 이는 다른 라운딩 모드에서는 부정확한 값을 제공할 수 있다. ### 부동 소수점 실수에 대해서 더 읽으면 좋은 문서들 @@ -523,7 +525,7 @@ julia> typeof(y) BigInt ``` -[`BigFloat`](@ref)타입에서 기본 정밀도(가수부의 비트수)와 반올림 모드는 [`setprecision`](@ref)와 [`setrounding`](@ref)를 호출함으로써 변경할 수 있으며, 한 번 호출된 이후에는 그 설정이 계속 유지 된다. 특정 블럭의 코드에서만 정밀도와 반올림을 변경하기 위해서는 `do`블럭의 코드에서와 같은 함수를 호출한다: +[`BigFloat`](@ref)타입에서 기본 정밀도(가수부의 비트수)와 라운딩 모드는 [`setprecision`](@ref)와 [`setrounding`](@ref)를 호출함으로써 변경할 수 있으며, 한 번 호출된 이후에는 그 설정이 계속 유지 된다. 특정 블럭의 코드에서만 정밀도와 라운딩을 변경하기 위해서는 `do`블럭의 코드에서와 같은 함수를 호출한다: ```jldoctest julia> setrounding(BigFloat, RoundUp) do diff --git a/src/manual/strings.md b/src/manual/strings.md index 68c2ccf..6887919 100644 --- a/src/manual/strings.md +++ b/src/manual/strings.md @@ -515,26 +515,26 @@ true You can search for the index of a particular character using the [`findfirst`](@ref) function: ```jldoctest -julia> findfirst(equalto('x'), "xylophone") +julia> findfirst(isequal('x'), "xylophone") 1 -julia> findfirst(equalto('p'), "xylophone") +julia> findfirst(isequal('p'), "xylophone") 5 -julia> findfirst(equalto('z'), "xylophone") +julia> findfirst(isequal('z'), "xylophone") ``` You can start the search for a character at a given offset by using [`findnext`](@ref) with a third argument: ```jldoctest -julia> findnext(equalto('o'), "xylophone", 1) +julia> findnext(isequal('o'), "xylophone", 1) 4 -julia> findnext(equalto('o'), "xylophone", 5) +julia> findnext(isequal('o'), "xylophone", 5) 7 -julia> findnext(equalto('o'), "xylophone", 8) +julia> findnext(isequal('o'), "xylophone", 8) ``` You can use the [`contains`](@ref) function to check if a substring is contained in a string: diff --git a/src/stdlib/LinearAlgebra.md b/src/stdlib/LinearAlgebra.md index e46e75e..8ccffe5 100644 --- a/src/stdlib/LinearAlgebra.md +++ b/src/stdlib/LinearAlgebra.md @@ -5,7 +5,7 @@ DocTestSetup = :(using LinearAlgebra) ``` In addition to (and as part of) its support for multi-dimensional arrays, Julia provides native implementations -of many common and useful linear algebra operations. Basic operations, such as [`trace`](@ref), [`det`](@ref), +of many common and useful linear algebra operations. Basic operations, such as [`tr`](@ref), [`det`](@ref), and [`inv`](@ref) are all supported: ```jldoctest @@ -15,7 +15,7 @@ julia> A = [1 2 3; 4 1 6; 7 8 1] 4 1 6 7 8 1 -julia> trace(A) +julia> tr(A) 3 julia> det(A) @@ -371,7 +371,7 @@ LinearAlgebra.normalize! LinearAlgebra.normalize LinearAlgebra.cond LinearAlgebra.condskeel -LinearAlgebra.trace +LinearAlgebra.tr LinearAlgebra.det LinearAlgebra.logdet LinearAlgebra.logabsdet diff --git a/src/stdlib/linearalgebra.md b/src/stdlib/linearalgebra.md index e46e75e..8ccffe5 100644 --- a/src/stdlib/linearalgebra.md +++ b/src/stdlib/linearalgebra.md @@ -5,7 +5,7 @@ DocTestSetup = :(using LinearAlgebra) ``` In addition to (and as part of) its support for multi-dimensional arrays, Julia provides native implementations -of many common and useful linear algebra operations. Basic operations, such as [`trace`](@ref), [`det`](@ref), +of many common and useful linear algebra operations. Basic operations, such as [`tr`](@ref), [`det`](@ref), and [`inv`](@ref) are all supported: ```jldoctest @@ -15,7 +15,7 @@ julia> A = [1 2 3; 4 1 6; 7 8 1] 4 1 6 7 8 1 -julia> trace(A) +julia> tr(A) 3 julia> det(A) @@ -371,7 +371,7 @@ LinearAlgebra.normalize! LinearAlgebra.normalize LinearAlgebra.cond LinearAlgebra.condskeel -LinearAlgebra.trace +LinearAlgebra.tr LinearAlgebra.det LinearAlgebra.logdet LinearAlgebra.logabsdet From ebadaa02c2d545f2fe8eb53aa9403bd362f3bb8f Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Wed, 21 Mar 2018 13:15:09 +0900 Subject: [PATCH 014/153] update Julia Commit 2723d745c4 --- codex/NEWS.md | 11 +- codex/base/strings.md | 2 +- codex/manual/control-flow.md | 24 ++- codex/manual/methods.md | 4 +- codex/manual/strings.md | 26 +-- codex/manual/variables-and-scoping.md | 4 +- codex/stdlib/Dates.md | 4 +- codex/stdlib/Pkg3.md | 2 +- codex/stdlib/dates.md | 4 +- src/NEWS.md | 11 +- src/base/strings.md | 2 +- src/manual/control-flow.md | 24 ++- src/manual/methods.md | 257 ++++++++++++++------------ src/manual/strings.md | 26 +-- src/manual/variables-and-scoping.md | 4 +- src/stdlib/Dates.md | 4 +- src/stdlib/Pkg3.md | 2 +- src/stdlib/dates.md | 4 +- 18 files changed, 240 insertions(+), 175 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index 723afc3..16e0a09 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -151,6 +151,10 @@ Language changes * In `for i in x`, `x` used to be evaluated in a new scope enclosing the `for` loop. Now it is evaluated in the scope outside the `for` loop. + * In `for i in x, j in y`, all variables now have fresh bindings on each iteration of the + innermost loop. For example, an assignment to `i` will not be visible on the next `j` + loop iteration ([#330](https://github.com/JuliaLang/julia/issues/330)). + * Variable bindings local to `while` loop bodies are now freshly allocated on each loop iteration, matching the behavior of `for` loops. @@ -563,7 +567,7 @@ Library improvements * `diagm` now accepts several diagonal index/vector `Pair`s ([#24047](https://github.com/JuliaLang/julia/issues/24047)). * `isequal`, `==`, and `in` have one argument "curried" forms. For example `isequal(x)` - returns a function that compares its argument to `x` using `isequal` ([#23812](https://github.com/JuliaLang/julia/issues/23812)). + returns a function that compares its argument to `x` using `isequal` ([#26436](https://github.com/JuliaLang/julia/issues/26436)). * `reinterpret` now works on any AbstractArray using the new `ReinterpretArray` type. This supersedes the old behavior of reinterpret on Arrays. As a result, reinterpreting @@ -1075,6 +1079,11 @@ Deprecated or removed * The `remove_destination` keyword argument to `cp`, `mv`, and the unexported `cptree` has been renamed to `force` ([#25979](https://github.com/JuliaLang/julia/issues/25979)). + * `contains` has been deprecated in favor of a more general `occursin` function, which + takes its arguments in reverse order from `contains` ([#26283](https://github.com/JuliaLang/julia/issues/26283)). + + * `Regex` objects are no longer callable. Use `occursin` instead ([#26283](https://github.com/JuliaLang/julia/issues/26283)). + * The methods of `range` based on positional arguments have been deprecated in favor of keyword arguments ([#25896](https://github.com/JuliaLang/julia/issues/25896)). diff --git a/codex/base/strings.md b/codex/base/strings.md index 35c3405..efa0a51 100644 --- a/codex/base/strings.md +++ b/codex/base/strings.md @@ -38,7 +38,7 @@ Base.findfirst(::AbstractString, ::AbstractString) Base.findnext(::AbstractString, ::AbstractString, ::Integer) Base.findlast(::AbstractString, ::AbstractString) Base.findprev(::AbstractString, ::AbstractString, ::Integer) -Base.contains +Base.occursin Base.reverse(::Union{String,SubString{String}}) Base.replace(s::AbstractString, ::Pair) Base.split diff --git a/codex/manual/control-flow.md b/codex/manual/control-flow.md index 458789a..bc2e105 100644 --- a/codex/manual/control-flow.md +++ b/codex/manual/control-flow.md @@ -383,7 +383,7 @@ julia> i = 1; julia> while i <= 5 println(i) - i += 1 + global i += 1 end 1 2 @@ -471,7 +471,7 @@ julia> while true if i >= 5 break end - i += 1 + global i += 1 end 1 2 @@ -527,7 +527,25 @@ julia> for i = 1:2, j = 3:4 (2, 4) ``` -A `break` statement inside such a loop exits the entire nest of loops, not just the inner one. +With this syntax, iterables may still refer to outer loop variables; e.g. `for i = 1:n, j = 1:i` +is valid. +However a `break` statement inside such a loop exits the entire nest of loops, not just the inner one. +Both variables (`i` and `j`) are set to their current iteration values each time the inner loop runs. +Therefore, assignments to `i` will not be visible to subsequent iterations: + +```jldoctest +julia> for i = 1:2, j = 3:4 + println((i, j)) + i = 0 + end +(1, 3) +(1, 4) +(2, 3) +(2, 4) +``` + +If this example were rewritten to use a `for` keyword for each variable, then the output would +be different: the second and fourth values would contain `0`. ## Exception Handling diff --git a/codex/manual/methods.md b/codex/manual/methods.md index 2d9a490..60bd61e 100644 --- a/codex/manual/methods.md +++ b/codex/manual/methods.md @@ -509,12 +509,12 @@ julia> f(1) julia> g(1) "definition for Int" -julia> wait(schedule(t, 1)) +julia> fetch(schedule(t, 1)) "original definition" julia> t = @async f(wait()); yield(); -julia> wait(schedule(t, 1)) +julia> fetch(schedule(t, 1)) "definition for Int" ``` diff --git a/codex/manual/strings.md b/codex/manual/strings.md index 6887919..e03c6a9 100644 --- a/codex/manual/strings.md +++ b/codex/manual/strings.md @@ -537,23 +537,23 @@ julia> findnext(isequal('o'), "xylophone", 5) julia> findnext(isequal('o'), "xylophone", 8) ``` -You can use the [`contains`](@ref) function to check if a substring is contained in a string: +You can use the [`occursin`](@ref) function to check if a substring is found within a string: ```jldoctest -julia> contains("Hello, world.", "world") +julia> occursin("world", "Hello, world.") true -julia> contains("Xylophon", "o") +julia> occursin("o", "Xylophon") true -julia> contains("Xylophon", "a") +julia> occursin("a", "Xylophon") false -julia> contains("Xylophon", 'o') +julia> occursin('o', "Xylophon") true ``` -The last example shows that [`contains`](@ref) can also look for a character literal. +The last example shows that [`occursin`](@ref) can also look for a character literal. Two other handy string functions are [`repeat`](@ref) and [`join`](@ref): @@ -608,20 +608,20 @@ julia> typeof(ans) Regex ``` -To check if a regex matches a string, use [`contains`](@ref): +To check if a regex matches a string, use [`occursin`](@ref): ```jldoctest -julia> contains("not a comment", r"^\s*(?:#|$)") +julia> occursin(r"^\s*(?:#|$)", "not a comment") false -julia> contains("# a comment", r"^\s*(?:#|$)") +julia> occursin(r"^\s*(?:#|$)", "# a comment") true ``` -As one can see here, [`contains`](@ref) simply returns true or false, indicating whether the -given regex matches the string or not. Commonly, however, one wants to know not just whether a -string matched, but also *how* it matched. To capture this information about a match, use the -[`match`](@ref) function instead: +As one can see here, [`occursin`](@ref) simply returns true or false, indicating whether a +match for the given regex occurs in the string. Commonly, however, one wants to know not +just whether a string matched, but also *how* it matched. To capture this information about +a match, use the [`match`](@ref) function instead: ```jldoctest julia> match(r"^\s*(?:#|$)", "not a comment") diff --git a/codex/manual/variables-and-scoping.md b/codex/manual/variables-and-scoping.md index 38ac858..5e769ca 100644 --- a/codex/manual/variables-and-scoping.md +++ b/codex/manual/variables-and-scoping.md @@ -363,7 +363,7 @@ julia> Fs = Vector{Any}(undef, 2); i = 1; julia> while i <= 2 Fs[i] = ()->i - i += 1 + global i += 1 end julia> Fs[1]() @@ -384,7 +384,7 @@ julia> while i <= 2 let i = i Fs[i] = ()->i end - i += 1 + global i += 1 end julia> Fs[1]() diff --git a/codex/stdlib/Dates.md b/codex/stdlib/Dates.md index 3a434cc..0c76284 100644 --- a/codex/stdlib/Dates.md +++ b/codex/stdlib/Dates.md @@ -399,7 +399,7 @@ of dealing with daylight savings, leap seconds, etc.). As a bonus, all period arithmetic objects work directly with ranges: ```jldoctest -julia> dr = Date(2014,1,29):Date(2014,2,3) +julia> dr = Date(2014,1,29):Day(1):Date(2014,2,3) 2014-01-29:1 day:2014-02-03 julia> collect(dr) @@ -484,7 +484,7 @@ range: ```jldoctest # Pittsburgh street cleaning; Every 2nd Tuesday from April to November # Date range from January 1st, 2014 to January 1st, 2015 -julia> dr = Dates.Date(2014):Dates.Date(2015); +julia> dr = Dates.Date(2014):Day(1):Dates.Date(2015); julia> filter(dr) do x Dates.dayofweek(x) == Dates.Tue && diff --git a/codex/stdlib/Pkg3.md b/codex/stdlib/Pkg3.md index b54bddc..b5e8d1a 100644 --- a/codex/stdlib/Pkg3.md +++ b/codex/stdlib/Pkg3.md @@ -26,7 +26,7 @@ To generate files for a new project, use `pkg> generate`. pkg> generate HelloWorld ``` -This creates a new project `HelloWorld` with the following files +This creates a new project `HelloWorld` with the following files (visualized with the external [`tree` command](https://linux.die.net/man/1/tree)): ```jl julia> cd("HelloWorld") diff --git a/codex/stdlib/dates.md b/codex/stdlib/dates.md index 3a434cc..0c76284 100644 --- a/codex/stdlib/dates.md +++ b/codex/stdlib/dates.md @@ -399,7 +399,7 @@ of dealing with daylight savings, leap seconds, etc.). As a bonus, all period arithmetic objects work directly with ranges: ```jldoctest -julia> dr = Date(2014,1,29):Date(2014,2,3) +julia> dr = Date(2014,1,29):Day(1):Date(2014,2,3) 2014-01-29:1 day:2014-02-03 julia> collect(dr) @@ -484,7 +484,7 @@ range: ```jldoctest # Pittsburgh street cleaning; Every 2nd Tuesday from April to November # Date range from January 1st, 2014 to January 1st, 2015 -julia> dr = Dates.Date(2014):Dates.Date(2015); +julia> dr = Dates.Date(2014):Day(1):Dates.Date(2015); julia> filter(dr) do x Dates.dayofweek(x) == Dates.Tue && diff --git a/src/NEWS.md b/src/NEWS.md index e0d2227..e5c6265 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -139,6 +139,10 @@ Language changes * In `for i in x`, `x` used to be evaluated in a new scope enclosing the `for` loop. Now it is evaluated in the scope outside the `for` loop. + * In `for i in x, j in y`, all variables now have fresh bindings on each iteration of the + innermost loop. For example, an assignment to `i` will not be visible on the next `j` + loop iteration ([#330](https://github.com/JuliaLang/julia/issues/330)). + * Variable bindings local to `while` loop bodies are now freshly allocated on each loop iteration, matching the behavior of `for` loops. @@ -551,7 +555,7 @@ Library improvements * `diagm` now accepts several diagonal index/vector `Pair`s ([#24047](https://github.com/JuliaLang/julia/issues/24047)). * `isequal`, `==`, and `in` have one argument "curried" forms. For example `isequal(x)` - returns a function that compares its argument to `x` using `isequal` ([#23812](https://github.com/JuliaLang/julia/issues/23812)). + returns a function that compares its argument to `x` using `isequal` ([#26436](https://github.com/JuliaLang/julia/issues/26436)). * `reinterpret` now works on any AbstractArray using the new `ReinterpretArray` type. This supersedes the old behavior of reinterpret on Arrays. As a result, reinterpreting @@ -1063,6 +1067,11 @@ Deprecated or removed * The `remove_destination` keyword argument to `cp`, `mv`, and the unexported `cptree` has been renamed to `force` ([#25979](https://github.com/JuliaLang/julia/issues/25979)). + * `contains` has been deprecated in favor of a more general `occursin` function, which + takes its arguments in reverse order from `contains` ([#26283](https://github.com/JuliaLang/julia/issues/26283)). + + * `Regex` objects are no longer callable. Use `occursin` instead ([#26283](https://github.com/JuliaLang/julia/issues/26283)). + * The methods of `range` based on positional arguments have been deprecated in favor of keyword arguments ([#25896](https://github.com/JuliaLang/julia/issues/25896)). diff --git a/src/base/strings.md b/src/base/strings.md index 35c3405..efa0a51 100644 --- a/src/base/strings.md +++ b/src/base/strings.md @@ -38,7 +38,7 @@ Base.findfirst(::AbstractString, ::AbstractString) Base.findnext(::AbstractString, ::AbstractString, ::Integer) Base.findlast(::AbstractString, ::AbstractString) Base.findprev(::AbstractString, ::AbstractString, ::Integer) -Base.contains +Base.occursin Base.reverse(::Union{String,SubString{String}}) Base.replace(s::AbstractString, ::Pair) Base.split diff --git a/src/manual/control-flow.md b/src/manual/control-flow.md index 0528980..64adefc 100644 --- a/src/manual/control-flow.md +++ b/src/manual/control-flow.md @@ -328,7 +328,7 @@ julia> i = 1; julia> while i <= 5 println(i) - i += 1 + global i += 1 end 1 2 @@ -400,7 +400,7 @@ julia> while true if i >= 5 break end - i += 1 + global i += 1 end 1 2 @@ -451,7 +451,25 @@ julia> for i = 1:2, j = 3:4 (2, 4) ``` -이러한 루프 내부의 `break`문은 내부의 루프 하나만을 종료하는 것이 아닌, 루프 전체를 종료합니다. +With this syntax, iterables may still refer to outer loop variables; e.g. `for i = 1:n, j = 1:i` +is valid. +However a `break` statement inside such a loop exits the entire nest of loops, not just the inner one. +Both variables (`i` and `j`) are set to their current iteration values each time the inner loop runs. +Therefore, assignments to `i` will not be visible to subsequent iterations: + +```jldoctest +julia> for i = 1:2, j = 3:4 + println((i, j)) + i = 0 + end +(1, 3) +(1, 4) +(2, 3) +(2, 4) +``` + +If this example were rewritten to use a `for` keyword for each variable, then the output would +be different: the second and fourth values would contain `0`. ## 예외 처리 diff --git a/src/manual/methods.md b/src/manual/methods.md index cf6022b..7e9cf0a 100644 --- a/src/manual/methods.md +++ b/src/manual/methods.md @@ -1,21 +1,41 @@ # [메서드](@id Methods) -[함수](@ref man-functions)에서 함수는 인수의 튜플을 반환 값으로 매핑하는 객체이거나 적절한 값을 반환 할 수없는 경우 예외를 throw합니다. 두 가지 정수를 더하는 것은 부동 소수점 수에 정수를 더하는 것과는 다른 두 개의 부동 소수점 수를 더하는 것과는 매우 다릅니다. 이러한 구현의 차이점에도 불구하고 이러한 작업은 모두 "추가"라는 일반적인 개념에 속합니다. 따라서 줄리아에서 이러한 동작은 모두 하나의 객체 인 `+` 함수에 속합니다. - -동일한 개념의 여러 구현을 원활하게 사용하기 위해 함수를 한꺼번에 정의 할 필요는 없지만 인수 유형 및 개수의 특정 조합에 특정 동작을 제공함으로써 구분할 수 있습니다. 함수에 대해 가능한 한 행동의 정의를 *메서드* 라고합니다. 지금까지 우리는 하나의 메서드로 정의 된 함수의 예제만을 제시했으며, 모든 유형의 인수에 적용 할 수 있습니다. 그러나 메서드 정의의 서명에는 그 수 이외에 인수의 유형을 표시하기 위해 주석을 달 수 있으며 단일 메서드 정의 이상이 제공 될 수 있습니다. 함수가 특정 튜플의 인수에 적용되면 해당 인수에 적용 할 수있는 가장 구체적인 메서드가 적용됩니다. 따라서 함수의 전반적인 동작은 다양한 메서드 정의의 동작을 패치하는 것입니다. 패치 워크가 잘 설계된 경우, 메서드의 구현이 상당히 다를 수도 있지만, 함수의 외부 동작은 매끄럽고 일관성있게 나타납니다. - -함수가 적용될 때 실행할 메서드의 선택은 *dispatch* 라고합니다. 줄리아는 파견 프로세스가 주어진 인수의 수와 함수의 모든 인수 유형에 따라 함수의 메서드 중 어느 것을 호출 할 것인지 선택할 수 있습니다. 이것은 전통적인 객체 지향 언어와는 다르다. 디스패치는 특별한 인수 구문을 사용하는 첫 번째 인수에만 기반을 두며 종종 인수로 명시 적으로 작성되지 않고 암시된다. +[함수](@ref man-functions)에서 함수는 인수의 튜플을 반환 값으로 매핑하는 객체이거나 적절한 값을 반환 할 수없는 경우 예외를 throw합니다. +두 가지 정수를 더하는 것은 부동 소수점 수에 정수를 더하는 것과는 다른 두 개의 부동 소수점 수를 더하는 것과는 매우 다릅니다. +이러한 구현의 차이점에도 불구하고 이러한 작업은 모두 "추가"라는 일반적인 개념에 속합니다. +따라서 줄리아에서 이러한 동작은 모두 하나의 객체인 `+` 함수에 속합니다. + +동일한 개념의 여러 구현을 원활하게 사용하기 위해 함수를 한꺼번에 정의할 필요는 없지만 +인수 유형 및 개수의 특정 조합에 특정 동작을 제공함으로써 구분할 수 있습니다. +함수에 대해 가능한 한 행동의 정의를 *메서드* 라고합니다. +지금까지 우리는 하나의 메서드로 정의 된 함수의 예제만을 제시했으며, 모든 유형의 인수에 적용 할 수 있습니다. +그러나 메서드 정의의 서명에는 그 수 이외에 인수의 유형을 표시하기 위해 주석을 달 수 있으며 +단일 메서드 정의 이상이 제공 될 수 있습니다. +함수가 특정 튜플의 인수에 적용되면 해당 인수에 적용 할 수있는 가장 구체적인 메서드가 적용됩니다. +따라서 함수의 전반적인 동작은 다양한 메서드 정의의 동작을 패치하는 것입니다. +패치 워크가 잘 설계된 경우, 메서드의 구현이 상당히 다를 수도 있지만, 함수의 외부 동작은 매끄럽고 일관성있게 나타납니다. + +함수가 적용될 때 실행할 메서드의 선택은 *dispatch* 라고 합니다. +줄리아는 파견 프로세스가 주어진 인수의 수와 함수의 모든 인수 유형에 따라 함수의 메서드 중 어느 것을 호출 할 것인지 선택할 수 있습니다. +이것은 전통적인 객체 지향 언어와는 다르다. 디스패치는 특별한 인수 구문을 사용하는 첫 번째 인수에만 기반을 두며 종종 인수로 명시 적으로 작성되지 않고 암시된다. [^1] 함수의 인수를 모두 사용하여 첫 번째 메서드가 아닌 호출 할 메서드를 선택하는 것이 [다중 디스패치](https://en.wikipedia.org/wiki/Multiple_dispatch)로 알려져 있습니다. -다중 디스패치는 수학적 코드에서 특히 유용합니다. 다른 연산보다 하나의 인수에 "속하는"연산을 인위적으로 판단하는 것은 의미가 없습니다. `x + y` 의 더하기 연산이 `y` 보다 `x` 에 속해 있습니까? 수학 연산자의 구현은 일반적으로 모든 인수의 유형에 따라 다릅니다. 그러나 수학적 작업을 넘어서더라도, 다중 파견은 프로그램을 구조화하고 조직화하는 데있어 유쾌하고 편리한 패러다임입니다. +다중 디스패치는 수학적 코드에서 특히 유용합니다. 다른 연산보다 하나의 인수에 "속하는" 연산을 인위적으로 판단하는 것은 의미가 없습니다. +`x + y` 의 더하기 연산이 `y` 보다 `x` 에 속해 있습니까? 수학 연산자의 구현은 일반적으로 모든 인수의 유형에 따라 다릅니다. +그러나 수학적 작업을 넘어서더라도, 다중 파견은 프로그램을 구조화하고 조직화하는 데있어 유쾌하고 편리한 패러다임입니다. [^1]: - 예를 들어,`obj.meth(arg1, arg2)` 와 같은 메서드 호출에서 C ++이나 Java에서 객체 obj는 메서드 호출을 "받는다"는 의미가 아니라 `this` 키워드를 통해 메서드에 암묵적으로 전달됩니다. 명시적인 메서드 인수. 현재 `this` 객체가 메서드 호출의 수신자 일 때 `meth (arg1, arg2)` 만 쓰고 `this` 를 수신 객체로 함축하여 생략 할 수 있습니다. + 예를 들어,`obj.meth(arg1, arg2)` 와 같은 메서드 호출에서 C ++이나 Java에서 객체 obj는 메서드 호출을 "받는다"는 의미가 아니라 + `this` 키워드를 통해 메서드에 암묵적으로 전달됩니다. + 명시적인 메서드 인수. 현재 `this` 객체가 메서드 호출의 수신자 일 때 `meth (arg1, arg2)` 만 쓰고 `this` 를 수신 객체로 함축하여 생략 할 수 있습니다. ## 메서드 정의 -지금까지 우리는 예제에서 제약되지 않은 인자 타입을 가진 하나의 메서드를 가진 함수만을 정의했다. 이러한 함수는 전통적인 동적 유형 지정 언어 에서처럼 작동합니다. 그럼에도 불구하고 우리는 다중 디스패치와 메서드를 의식하지 않고 거의 연속적으로 사용했습니다. 앞서 말한 `+` 함수와 같은 모든 줄리아의 표준 함수와 연산자에는 인수 유형과 개수의 다양한 조합을 통해 동작을 정의하는 많은 메서드가 있습니다. +지금까지 우리는 예제에서 제약되지 않은 인자 타입을 가진 하나의 메서드를 가진 함수만을 정의했다. +이러한 함수는 전통적인 동적 유형 지정 언어 에서처럼 작동합니다. +그럼에도 불구하고 우리는 다중 디스패치와 메서드를 의식하지 않고 거의 연속적으로 사용했습니다. +앞서 말한 `+` 함수와 같은 모든 줄리아의 표준 함수와 연산자에는 인수 유형과 개수의 다양한 조합을 통해 동작을 정의하는 많은 메서드가 있습니다. -함수를 정의 할 때 [Composite Types](@ref) 섹션에서 소개 한 `::` type-assertion 연산자를 사용하여 적용 할 수있는 매개 변수의 유형을 선택적으로 제한 할 수 있습니다. : +함수를 정의 할 때 [Composite Types](@ref) 섹션에서 소개 한 `::` type-assertion 연산자를 사용하여 적용 할 수있는 매개 변수의 유형을 선택적으로 제한 할 수 있습니다: ```jldoctest fofxy julia> f(x::Float64, y::Float64) = 2x + y @@ -52,7 +72,10 @@ julia> f("2.0", "3.0") ERROR: MethodError: no method matching f(::String, ::String) ``` -보시다시피, 인수는 정확히 [`Float64`](@ref) 유형이어야합니다. 정수 또는 32 비트 부동 소수점 값과 같은 다른 숫자 유형은 자동으로 '64 비트 부동 소수점으로 변환되지 않으며 숫자로 해석되는 문자열도 아닙니다. `Float64` 는 구체적인 타입이고 줄리아에서 구체적인 타입을 서브 클래 싱 할 수 없기 때문에, 그러한 정의는 정확히 `Float64` 타입의 인자에만 적용될 수 있습니다. 그러나 선언 된 매개 변수 유형이 추상 인 경우보다 일반적인 메서드를 작성하는 것이 종종 유용 할 수 있습니다. +보시다시피, 인수는 정확히 [`Float64`](@ref) 유형이어야합니다. +정수 또는 32 비트 부동 소수점 값과 같은 다른 숫자 유형은 자동으로 '64 비트 부동 소수점으로 변환되지 않으며 숫자로 해석되는 문자열도 아닙니다. +`Float64` 는 구체적인 타입이고 줄리아에서 구체적인 타입을 서브 클래 싱 할 수 없기 때문에, 그러한 정의는 정확히 `Float64` 타입의 인자에만 적용될 수 있습니다. +그러나 선언 된 매개 변수 유형이 추상 인 경우보다 일반적인 메서드를 작성하는 것이 종종 유용 할 수 있습니다. ```jldoctest fofxy julia> f(x::Number, y::Number) = 2x - y @@ -62,9 +85,15 @@ julia> f(2.0, 3) 1.0 ``` -이 메서드 정의는 [`Number`](@ref) 의 인스턴스 인 모든 인수 쌍에 적용됩니다. 그들은 각각 숫자 값인 한 동일한 유형일 필요는 없습니다. 서로 다른 숫자 타입을 처리하는 문제는 `2x - y` 표현식의 산술 연산에 위임됩니다. +이 메서드 정의는 [`Number`](@ref) 의 인스턴스 인 모든 인수 쌍에 적용됩니다. +그들은 각각 숫자 값인 한 동일한 유형일 필요는 없습니다. 서로 다른 숫자 타입을 처리하는 문제는 `2x - y` 표현식의 산술 연산에 위임 됩니다. -여러 메서드로 함수를 정의하려면 함수의 수와 유형을 여러 번 정의해야합니다. 함수에 대한 첫 번째 메서드 정의는 함수 개체를 만들고 후속 메서드 정의는 기존 함수 개체에 새 메서드를 추가합니다. 인수의 수와 유형과 일치하는 가장 구체적인 메서드 정의는 함수가 적용될 때 실행됩니다. 따라서, 위의 두 메서드 정의는 함께 추상 타입 `Number` 의 모든 인스턴스 쌍에 대해 `f` 에 대한 동작을 정의하지만 [`Float64`](@ref) 쌍에 고유 한 다른 동작을 사용하여 정의됩니다. 값. 인수 중 하나가 64 비트 부동 소수점이지만 다른 하나는 부동 소수점인 경우 `f(Float64, Float64)` 메서드를 호출 할 수 없으며보다 일반적인 `f(Number, Number)` 메서드를 사용해야합니다. +여러 메서드로 함수를 정의하려면 함수의 수와 유형을 여러 번 정의해야합니다. +함수에 대한 첫 번째 메서드 정의는 함수 개체를 만들고 후속 메서드 정의는 기존 함수 개체에 새 메서드를 추가합니다. +인수의 수와 유형과 일치하는 가장 구체적인 메서드 정의는 함수가 적용될 때 실행됩니다. +따라서, 위의 두 메서드 정의는 함께 추상 타입 `Number` 의 모든 인스턴스 쌍에 대해 `f` 에 대한 동작을 정의하지만 +[`Float64`](@ref) 쌍에 고유 한 다른 동작을 사용하여 정의됩니다. +값. 인수 중 하나가 64 비트 부동 소수점이지만 다른 하나는 부동 소수점인 경우 `f(Float64, Float64)` 메서드를 호출 할 수 없으며 보다 일반적인 `f(Number, Number)` 메서드를 사용해야합니다. ```jldoctest fofxy julia> f(2.0, 3.0) @@ -80,10 +109,11 @@ julia> f(2, 3) 1 ``` -`2x + y` 정의는 첫 번째 경우에만 사용되는 반면, `2x-y` 정의는 다른 것에 사용됩니다. 자동 주조 또는 함수 인수 변환이 수행되지 않습니다. 줄리아의 모든 변환은 비 마법적이고 완전히 명시 적입니다. 그러나 [전환 및 판촉](@ref conversion-and-promotion) 은 충분히 발전된 기술의 영리한 적용이 마법과 구별 될 수 없음을 보여줍니다. [^Clarke61] - +`2x + y` 정의는 첫 번째 경우에만 사용되는 반면, `2x-y` 정의는 다른 것에 사용됩니다. +자동 주조 또는 함수 인수 변환이 수행되지 않습니다. 줄리아의 모든 변환은 비 마법적이고 완전히 명시적입니다. +그러나 [전환 및 판촉](@ref conversion-and-promotion)은 충분히 발전된 기술의 영리한 적용이 마법과 구별 될 수 없음을 보여줍니다. [^Clarke61] -숫자가 아닌 값과 2 개보다 적거나 많은 인수의 경우, `f` 함수는 정의되지 않은 채로 남아 있으며, 여전히 [`MethodError`](@ref) 가됩니다 : +숫자가 아닌 값과 2 개보다 적거나 많은 인수의 경우, `f` 함수는 정의되지 않은 채로 남아 있으며, 여전히 [`MethodError`](@ref) 가 됩니다: ```jldoctest fofxy julia> f("foo", 3) @@ -98,7 +128,7 @@ Closest candidates are: f(!Matched::Number, !Matched::Number) at none:1 ``` -대화 형 세션에서 함수 객체 자체를 입력하면 함수에 어떤 메서드가 있는지 쉽게 알 수 있습니다. +대화형 세션에서 함수 객체 자체를 입력하면 함수에 어떤 메서드가 있는지 쉽게 알 수 있습니다. ```jldoctest fofxy julia> f @@ -114,9 +144,12 @@ julia> methods(f) [2] f(x::Number, y::Number) in Main at none:1 ``` -`f` 에는 두 개의 Float64 인수를 취하는 메서드와 `Number` 타입의 인수를 취하는 메서드가 있습니다. 또한 메서드가 정의 된 파일과 행 번호를 표시합니다.이 메서드가 REPL에 정의 되었기 때문에 명백한 행 번호는 `none:1` 입니다. +`f` 에는 두 개의 Float64 인수를 취하는 메서드와 `Number` 타입의 인수를 취하는 메서드가 있습니다. +또한 메서드가 정의 된 파일과 행 번호를 표시합니다.이 메서드가 REPL에 정의 되었기 때문에 명백한 행 번호는 `none:1` 입니다. -`::` 를 사용한 타입 선언이 없으면 메서드 매개 변수의 타입은 기본적으로 `Any` 이며, 이는 줄리아의 모든 값이 추상 타입 `Any` 의 인스턴스이기 때문에 제약이 없다는 것을 의미합니다. 따라서 `f` 에 대한 catch-all 메서드를 다음과 같이 정의 할 수 있습니다 : +`::` 를 사용한 타입 선언이 없으면 메서드 매개 변수의 타입은 기본적으로 `Any` 이며, +이는 줄리아의 모든 값이 추상 타입 `Any` 의 인스턴스이기 때문에 제약이 없다는 것을 의미합니다. +따라서 `f` 에 대한 catch-all 메서드를 다음과 같이 정의 할 수 있습니다 : ```jldoctest fofxy julia> f(x,y) = println("Whoa there, Nelly.") @@ -126,10 +159,10 @@ julia> f("foo", 1) Whoa there, Nelly. ``` - 이 catch-all은 한 쌍의 매개 변수 값에 대해 가능한 다른 메서드 정의보다 덜 구체적이므로 다른 메서드 정의가 적용되지 않는 인수 쌍에서만 호출됩니다. -단순한 개념으로 보일지라도, 가치 유형에 대한 다중 파견은 아마도 줄리아 언어의 가장 강력하고 핵심적인 단일 기능 일 것입니다. 핵심 운영에는 일반적으로 수십 가지 방법이 있습니다 : +단순한 개념으로 보일지라도, 가치 유형에 대한 다중 파견은 아마도 줄리아 언어의 가장 강력하고 핵심적인 단일 기능 일 것입니다. +핵심 운영에는 일반적으로 수십 가지 방법이 있습니다: ```julia-repl julia> methods(+) @@ -155,12 +188,12 @@ julia> methods(+) [180] +(a, b, c, xs...) in Base at operators.jl:424 ``` -유연한 파라 메트릭 유형 시스템과의 다중 디스패치 기능을 통해 줄리아는 구현 세부 정보에서 분리 된 상위 수준의 알고리즘을 추상적으로 표현할 수 있지만 런타임에 각 사례를 처리 할 수있는 효율적인 특수 코드를 생성 할 수 있습니다. +유연한 파라 메트릭 유형 시스템과의 다중 디스패치 기능을 통해 +줄리아는 구현 세부 정보에서 분리 된 상위 수준의 알고리즘을 추상적으로 표현할 수 있지만 런타임에 각 사례를 처리 할 수있는 효율적인 특수 코드를 생성 할 수 있습니다. ## [방법 모호성](@id man-ambiguities) - -일부 인수 조합에 적용 할 수있는 고유 한 가장 구체적인 메서드가 없도록 함수 메서드 세트를 정의 할 수 있습니다. : +일부 인수 조합에 적용 할 수있는 고유 한 가장 구체적인 메서드가 없도록 함수 메서드 세트를 정의 할 수 있습니다: ```jldoctest gofxy julia> g(x::Float64, y) = 2x + y @@ -183,7 +216,9 @@ Possible fix, define g(::Float64, ::Float64) ``` -여기서 `g (2.0, 3.0)` 호출은 `g (Float64, Any)` 또는 `g (Any, Float64)` 메서드에 의해 처리 될 수 있으며, 어느 쪽도 더 구체적이지 않습니다. 이런 경우 줄리아는 임의로 메서드를 선택하는 것이 아니라 [`MethodError`](@ref) 를 발생시킵니다. 교차 사례의 적절한 방법을 지정하여 메서드 모호성을 피할 수 있습니다. : +여기서 `g (2.0, 3.0)` 호출은 `g (Float64, Any)` 또는 `g (Any, Float64)` 메서드에 의해 처리 될 수 있으며, 어느 쪽도 더 구체적이지 않습니다. +이런 경우 줄리아는 임의로 메서드를 선택하는 것이 아니라 [`MethodError`](@ref) 를 발생시킵니다. +교차 사례의 적절한 방법을 지정하여 메서드 모호성을 피할 수 있습니다: ```jldoctest gofxy julia> g(x::Float64, y::Float64) = 2x + 2y @@ -199,10 +234,9 @@ julia> g(2.0, 3.0) 10.0 ``` - 일시적인 경우보다 구체적인 방법이 정의 될 때까지 모호성이 존재하기 때문에 모호성을 제거하는 방법을 먼저 정의하는 것이 좋습니다. -보다 복잡한 경우, 방법 모호성 해결 은 디자인의 특정 요소를 포함합니다. 이 주제는 [아래](@ref man-method-design-ambiguities) 에서 더 자세히 다루어집니다. +보다 복잡한 경우, 방법 모호성 해결 은 디자인의 특정 요소를 포함합니다. 이 주제는 [아래](@ref man-method-design-ambiguities) 에서 더 자세히 다루어 집니다. ## [파라메트릭 메서드](@id Parametric-Methods) @@ -216,8 +250,9 @@ julia> same_type(x,y) = false same_type (generic function with 2 methods) ``` - -첫 번째 방법은 두 인수가 모두 동일한 구체 유형일 때마다 적용됩니다. 두 번째 방법은 다른 모든 경우를 포괄하는 포괄적인 방식으로 작동합니다. 따라서 전반적으로 두 인수가 같은 유형인지 여부를 확인하는 부울 함수를 정의합니다. +첫 번째 방법은 두 인수가 모두 동일한 구체 유형일 때마다 적용됩니다. +두 번째 방법은 다른 모든 경우를 포괄하는 포괄적인 방식으로 작동합니다. +따라서 전반적으로 두 인수가 같은 유형인지 여부를 확인하는 부울 함수를 정의합니다. ```jldoctest same_typefunc julia> same_type(1, 2) @@ -239,14 +274,15 @@ julia> same_type(Int32(1), Int64(2)) false ``` - 이러한 정의는 형식 서명이 `UnionAll` ([UnionAll Types](@ref) 참조) 유형인 메서드에 해당합니다. -이러한 종류의 파견에 의한 기능 행동의 정의는 매우 흔하며, 심지어 줄리아에서도 관용적입니다. 메서드 유형 매개 변수는 인수의 유형으로 사용되는 것으로 제한되지 않으며 함수의 본문 또는 본문에 값이있는 모든 위치에서 사용할 수 있습니다. 다음은 메서드 시그니처의 매개 변수 유형 `Vector {T}` 에 대한 유형 매개 변수로 메서드 유형 매개 변수 `T` 가 사용되는 예제입니다. +이러한 종류의 파견에 의한 기능 행동의 정의는 매우 흔하며, 심지어 줄리아에서도 관용적입니다. +메서드 유형 매개 변수는 인수의 유형으로 사용되는 것으로 제한되지 않으며 함수의 본문 또는 본문에 값이있는 모든 위치에서 사용할 수 있습니다. +다음은 메서드 시그니처의 매개 변수 유형 `Vector {T}` 에 대한 유형 매개 변수로 메서드 유형 매개 변수 `T` 가 사용되는 예제입니다. ```jldoctest julia> myappend(v::Vector{T}, x::T) where {T} = [v..., x] -myappend (한가지 메서드를 가진 일반함수) +myappend (generic function with 1 method) julia> myappend([1,2,3],4) 4-element Array{Int64,1}: @@ -256,8 +292,8 @@ julia> myappend([1,2,3],4) 4 julia> myappend([1,2,3],2.5) -ERROR: MethodError : myappend와 일치하는 메서드가 없습니다.(::Array{Int64,1}, ::Float64) -가장 가까운 후보자는: +ERROR: MethodError: no method matching myappend(::Array{Int64,1}, ::Float64) +Closest candidates are: myappend(::Array{T,1}, !Matched::T) where T at none:1 julia> myappend([1.0,2.0,3.0],4.0) @@ -268,17 +304,17 @@ julia> myappend([1.0,2.0,3.0],4.0) 4.0 julia> myappend([1.0,2.0,3.0],4) -ERROR : MethodError : myappend와 일치하는 메서드가 없습니다.(::Array{Float64,1}, ::Int64) -가장 가까운 후보자는: +ERROR: MethodError: no method matching myappend(::Array{Float64,1}, ::Int64) +Closest candidates are: myappend(::Array{T,1}, !Matched::T) where T at none:1 ``` - -보시다시피, 첨부 된 요소의 유형은 추가되는 벡터의 요소 유형과 일치해야합니다. 그렇지 않으면 [`MethodError`](@ref) 가 발생합니다. 다음 예제에서는 메서드 유형 매개 변수 `T` 가 반환 값으로 사용됩니다. +보시다시피, 첨부된 요소의 유형은 추가되는 벡터의 요소 유형과 일치해야합니다. +그렇지 않으면 [`MethodError`](@ref) 가 발생합니다. 다음 예제에서는 메서드 유형 매개 변수 `T` 가 반환 값으로 사용됩니다. ```jldoctest julia> mytypeof(x::T) where {T} = T -mytypeof (한가지 메서드를 가진 일반함수) +mytypeof (generic function with 1 method) julia> mytypeof(1) Int64 @@ -287,15 +323,15 @@ julia> mytypeof(1.0) Float64 ``` - -타입 선언에 타입 파라미터에 하위 타입 제약 조건을 넣을 수있는 것처럼 ([파라메트릭 타입](@ref Parametric-Types) 참조), 메서드의 타입 파라미터를 제한 할 수도 있습니다 : +타입 선언에 타입 파라미터에 하위 타입 제약 조건을 넣을 수있는 것처럼 ([파라메트릭 타입](@ref Parametric-Types) 참조), +메서드의 타입 파라미터를 제한 할 수도 있습니다: ```jldoctest julia> same_type_numeric(x::T, y::T) where {T<:Number} = true -same_type_numeric (한가지 메서드를 가진 일반함수) +same_type_numeric (generic function with 1 method) julia> same_type_numeric(x::Number, y::Number) = false -same_type_numeric (두가지 메서드를 가진 일반함수s) +same_type_numeric (generic function with 2 methods) julia> same_type_numeric(1, 2) true @@ -307,25 +343,25 @@ julia> same_type_numeric(1.0, 2.0) true julia> same_type_numeric("foo", 2.0) -ERROR: MethodError : same_type_numeric과 일치하는 메서드가 없습니다.(::String, ::Float64) -가장 가까운 후보자는: +ERROR: MethodError: no method matching same_type_numeric(::String, ::Float64) +Closest candidates are: same_type_numeric(!Matched::T<:Number, ::T<:Number) where T<:Number at none:1 same_type_numeric(!Matched::Number, ::Number) at none:1 julia> same_type_numeric("foo", "bar") -ERROR: MethodError: same_type_numeric과 일치하는 메서드가 없습니다.(::String, ::String) +ERROR: MethodError: no method matching same_type_numeric(::String, ::String) julia> same_type_numeric(Int32(1), Int64(2)) false ``` -`same_type_numeric` 함수는 위에 정의 된 `same_type` 함수와 매우 비슷하게 동작하지만 숫자 쌍에 대해서만 정의됩니다. +`same_type_numeric` 함수는 위에 정의된 `same_type` 함수와 매우 비슷하게 동작하지만 숫자 쌍에 대해서만 정의됩니다. 파라 메트릭 메서드는 타입 작성에 사용되는 `where` 표현식과 같은 구문을 허용합니다 ([UnionAll Types](@ref) 참조). 하나의 매개 변수 만있는 경우에는 `{T}` 에있는 중괄호를 생략 할 수 있지만 명확성을 위해 선호하는 경우가 많습니다. 여러 매개 변수는 쉼표로 구분할 수 있습니다. e.g. `where {T, S<:Real}`, 또는 `where` 중첩을 사용하여 작성 , e.g. `where S<:Real where T`. -재정의 메서드 +메서드 재정의 ------------- 메서드를 재정의하거나 새 메서드를 추가 할 때 이러한 변경 사항이 즉시 적용되지 않는다는 것을 인식하는 것이 중요합니다. @@ -341,10 +377,10 @@ julia> function tryeval() tryeval (generic function with 1 method) julia> tryeval() -ERROR: MethodError: newfun ()과 일치하는 메서드가 없습니다 -적용 가능한 방법이 너무 새롭다: current world is xxxx2인동안 world age xxxx1실행. -가장 가까운 후보자는 다음과 같습니다: - none:1 에서 newfun() (this world context에서 호출하기에는 너무 새로운 메서드.) +ERROR: MethodError: no method matching newfun() +The applicable method may be too new: running in world age xxxx1, while current world is xxxx2. +Closest candidates are: + newfun() at none:1 (method too new to be called from this world context.) in tryeval() at none:1 ... @@ -352,7 +388,6 @@ julia> newfun() 1 ``` - 이 예제에서는 `newfun` 에 대한 새로운 정의가 생성되었지만 즉시 호출 할 수 없음을 관찰합니다. 새로운 전역 변수는 `tryeval` 함수에서 즉시 볼 수 있으므로 `return newfun` (괄호없이)을 쓸 수 있습니다. 그러나 당신이나 당신의 호출자, 또는 그들이 부르는 기능도 아닙니다. @@ -360,15 +395,14 @@ julia> newfun() 그러나 예외가 있습니다 : 미래의`newfun` 호출은 예상대로 *REPL* 에서 작동합니다. newfun의 새로운 정의를보고 호출 할 수 있습니다. -그러나 'tryeval'에 대한 향후 호출은 *이전 선언문 REPL* 에서처럼 `newfun` 의 정의를 계속 볼 것이며, 따라서 `tryeval` 에 대한 호출 전에 나타납니다. - +그러나 'tryeval'에 대한 향후 호출은 *REPL에서 처럼* `newfun` 의 정의를 계속 볼 것이며, 따라서 `tryeval` 에 대한 호출 전에 나타납니다. 어떻게 작동하는지 직접 확인해보십시오. 이 동작의 구현은 "세계 시대 카운터"입니다.이 단조 증가 값은 각 메서드 정의 연산을 추적합니다. 이를 통해 "주어진 런타임 환경에서 볼 수있는 메서드 정의 세트"를 단일 숫자 또는 "world age"로 설명 할 수 있습니다. 또한 서수 값을 비교하여 두 worlds에서 사용할 수있는 방법을 비교할 수 있습니다. -위 예제에서 "current world"("newfun"메서드가있는)는 `tryeval` 실행이 시작될 때 수정 된 작업 로컬 "런타임 환경" 보다 큰 것입니다. +위 예제에서 "current world" ("newfun" 메서드가 있는)는 `tryeval` 실행이 시작될 때 수정 된 작업 로컬 "런타임 환경" 보다 큰 것입니다. 때로는 이것을 피하는 것이 필요합니다 (예를 들어 위의 REPL을 구현하는 경우). 다행히도 쉬운 해결책이 있습니다 : [`Base.invokelatest`](@ref)를 사용하여 함수를 호출하십시오 : @@ -378,55 +412,54 @@ julia> function tryeval2() @eval newfun2() = 2 Base.invokelatest(newfun2) end -tryeval2 (한가지 메서드를 가진 일반함수) +tryeval2 (generic function with 1 method) julia> tryeval2() 2 ``` -마지막으로,이 규칙이 적용되는 좀 더 복잡한 예제를 살펴 보겠습니다. +마지막으로, 이 규칙이 적용되는 좀 더 복잡한 예제를 살펴 보겠습니다. 처음에는 하나의 메서드를 가지고있는 함수 `f(x)` 를 정의합니다 : -```jldoctest 메서드재정의 -julia> f(x) = "원래 정의" -f (한가지 메서드를 가진 일반함수) +```jldoctest redefinemethod +julia> f(x) = "기본 정의" +f (generic function with 1 method) ``` - `f (x)`를 사용하는 다른 연산을 시작합니다.: -```jldoctest 메서드재정의 +```jldoctest redefinemethod julia> g(x) = f(x) -g (한가지 메서드를 가진 일반함수) +g (generic function with 1 method) julia> t = @async f(wait()); yield(); ``` 이제 우리는`f (x)`에 몇 가지 새로운 메서드를 추가합니다 : -```jldoctest 메서드재정의 +```jldoctest redefinemethod julia> f(x::Int) = "Int로 정의" -f (두가지 메서드를 가진 일반함수) +f (generic function with 2 methods) julia> f(x::Type{Int}) = "Type{Int}로 정의" -f (세가지 메서드를 가진 일반함수) +f (generic function with 3 methods) ``` 결과가 어떻게 다른지 비교해봅시다.: -```jldoctest 메서드재정의 +```jldoctest redefinemethod julia> f(1) "Int로 정의" julia> g(1) "Int로 정의" -julia> wait(schedule(t, 1)) +julia> fetch(schedule(t, 1)) "기본 정의" julia> t = @async f(wait()); yield(); -julia> wait(schedule(t, 1)) +julia> fetch(schedule(t, 1)) "Int로 정의" ``` @@ -434,12 +467,11 @@ julia> wait(schedule(t, 1)) 성능이나 유용성에 복잡한 디스패치 로직이 필요하지는 않지만 때로는 일부 알고리즘을 표현하는 가장 좋은 방법 일 수 있습니다. -이런 방식으로 디스패치를 ​​사용할 때 때로는 나타나는 몇 가지 일반적인 디자인 패턴이 있습니다. +이런 방식으로 디스패치를 사용할 때 때로는 나타나는 몇 가지 일반적인 디자인 패턴이 있습니다. ### super-type 에서 type 매개 변수 추출 - 여기 `AbstractArray` 의 임의의 하위 유형의 요소 유형 `T` 를 반환하기위한 올바른 코드 템플릿이 있습니다.: ```julia @@ -448,10 +480,8 @@ eltype(::Type{<:AbstractArray{T}}) where {T} = T ``` 삼각 파견을 사용합니다. 예를 들어 `T` 가 `UnionAll` 타입 인 경우에 주목합니다. `eltype(Array{T} where T <: Integer)` 이면 `Any` 가 반환됩니다. (`Base` 에있는 `eltype` 의 버전도 마찬가지입니다). - Note that if `T` is a `UnionAll` - - 줄리아 v0.6에서 삼각형 파견의 출현 이전에 유일한 올바른 방법이었던 또 다른 방법은 다음과 같습니다. : +줄리아 v0.6에서 삼각형 파견의 출현 이전에 유일한 올바른 방법이었던 또 다른 방법은 다음과 같습니다: ```julia abstract type AbstractArray{T, N} end @@ -461,8 +491,7 @@ eltype(::Type{AbstractArray{T, N}}) where {T, N} = T eltype(::Type{A}) where {A<:AbstractArray} = eltype(supertype(A)) ``` -또 다른 가능성은 다음과 같습니다. 매개 변수 `T` 가 더 좁게 일치해야하는 경우에 적용하는 것이 유용 할 수 있습니다. - +또다른 가능성은 다음과 같습니다. 매개 변수 `T` 가 더 좁게 일치해야하는 경우에 적용하는 것이 유용 할 수 있습니다: ```julia eltype(::Type{AbstractArray{T, N} where {T<:S, N<:M}}) where {M, S} = Any eltype(::Type{AbstractArray{T, N} where {T<:S}}) where {N, S} = Any @@ -478,7 +507,7 @@ eltype(::Type{A}) where {A <: AbstractArray} = eltype(supertype(A)) eltype_wrong(::Type{A}) where {A<:AbstractArray} = A.parameters[1] ``` -그러나 이것이 실패 할 경우를 만드는 것은 어렵지 않습니다. : +그러나 이것이 실패할 경우를 만드는 것은 어렵지 않습니다: ```julia struct BitVector <: AbstractArray{Bool, 1}; end @@ -489,15 +518,14 @@ struct BitVector <: AbstractArray{Bool, 1}; end ### 다른 형식 매개 변수를 사용하여 비슷한 유형 만들기 - 일반적인 코드를 만들 때 유형의 레이아웃을 변경하고 유사한 유형의 객체를 생성해야하는 경우가 종종 있습니다. 유형 매개 변수의 변경이 필요합니다. 예를 들어 임의의 요소 유형을 가진 일종의 추상 배열을 가질 수 있으며 특정 요소 유형으로 계산을 작성하려고합니다. 이 유형 변환을 계산하는 방법을 설명하는 각 `AbstractArray{T}` 하위 유형에 대한 메서드를 구현해야합니다. 하나의 부속 유형에 대해 다른 매개 변수를 갖는 다른 부속 유형으로의 변환이 없습니다. (빠른 검토 : 이것이 왜 있는지 보시겠습니까?) - -`AbstractArray` 의 부속유형은 일반적으로이를 달성하는 두가지 메서드를 구현합니다. 입력배열을 특정 `AbstractArray {T, N}` 추상유형의 부속유형으로 변환하는 메서드 및 특정요소 유형을 가진 초기화되지 않은 새로운 배열을 만드는 방법. +`AbstractArray` 의 부속유형은 일반적으로이를 달성하는 두가지 메서드를 구현합니다. +입력배열을 특정 `AbstractArray {T, N}` 추상유형의 부속유형으로 변환하는 메서드 및 특정요소 유형을 가진 초기화되지 않은 새로운 배열을 만드는 방법. 이들의 샘플구현은 줄리아 Base에서 찾을 수 있습니다. 다음은 `input` 과 `output` 이 같은 타입으로되어 있다는 것을 보장하는 기본적인 예제사용법입니다 : @@ -516,11 +544,9 @@ copy_with_eltype(input, Eltype) = copyto!(similar(input, Eltype), input) ### 반복 디스패치 - 다단계 매개변수 목록을 발송하려면 종종 각 발송 단계를 별개의 기능으로 분리하는 것이 가장 좋습니다. 단일발송에 대한 접근방식과 비슷할 수도 있지만, 아래에서 보게 되겠지만 더 유연합니다. - 예를들어 배열의 요소유형을 디스패칭하려고하면 종종 모호한 상황이 발생합니다. 대신 일반적으로 코드는 컨테이너유형에 먼저 전달되고 eltype를 기반으로 한 것 보다 구체적인 메서드로 순환됩니다. 대부분의 경우 알고리즘은이 계층적 접근방식을 편리하게 사용하지만 다른 경우에는 수동으로 이 엄격성을 해결해야합니다. @@ -539,16 +565,15 @@ copy_with_eltype(input, Eltype) = copyto!(similar(input, Eltype), input) ### Trait-based 디스패치 -위의 iterated 디스패치를 ​​자연스럽게 확장하면 형식계층에 정의된 집합과 독립적인 형식집합을 디스패치 할 수있는 계층을 메서드선택에 추가 할 수 있습니다. +위의 iterated 디스패치를 자연스럽게 확장하면 형식계층에 정의된 집합과 독립적인 형식집합을 디스패치 할 수있는 계층을 메서드선택에 추가 할 수 있습니다. 우리는 문제의유형의 `조합` 을 작성하여 그러한 집합을 구성 할 수 있지만, 생성 후에 `연합` 유형을 변경할 수 없으므로이 집합은 확장 할 수 없습니다. -그러나 이러한 확장가능 세트는 종종 ["Holy-trait"](https://github.com/줄리아Lang/julia/issues/2345#issuecomment-54537633) 이라고하는 디자인 패턴으로 프로그래밍 될 수 있습니다. +그러나 이러한 확장가능 세트는 종종 ["Holy-trait"](https://github.com/JuliaLang/julia/issues/2345#issuecomment-54537633) 라는 디자인 패턴으로 프로그래밍 될 수 있습니다. 이 패턴은 함수인수가 속할 수있는 각 특성집합에 대해 다른 단일값 (또는 유형)을 계산하는 일반함수를 정의하여 구현됩니다. 이 기능이 순수하면 정상적인 발송과 비교하여 성능에 영향을주지 않습니다. - 이전 섹션의 예제는 [`map`](@ref) 및 [`promote`](@ref)의 구현세부사항을 설명했습니다.이 두 특성은 이러한 특성에 따라 작동합니다. `map` 의 구현과 같이 행렬을 반복 할 때 중요한 질문 중 하나는 데이터를 순회하기 위해 사용하는 순서입니다. -`AbstractArray` 보조형이 [`Base.IndexStyle`](@ref) 형질을 구현할 때 `map` 과 같은 다른함수는 이러한 정보를 보내서 최상의 알고리즘을 선택합니다 ([Abstract Array Interface](@ref man-interface-array)). +`AbstractArray` 보조형이 [`Base.IndexStyle`](@ref) 형질을 구현할 때 `map` 과 같은 다른 함수는 이러한 정보를 보내서 최상의 알고리즘을 선택합니다 ([Abstract Array Interface](@ref man-interface-array)). 즉, 일반정의 + 특성클래스를 사용하면 시스템에서 가장 빠른 버전을 선택할 수 있기 때문에 각 하위유형에서 `map` 의 사용자정의버전을 구현할 필요가 없습니다. trait-based의 디스패치를 보여주는 `map` 의 장난감 구현: @@ -626,7 +651,8 @@ end ### 별도의 변환과 커널로직 -컴파일 시간을 줄이고 복잡성을 테스트하는 한 가지 방법은 원하는 유형으로 변환하기위한 로직과 계산을 분리하는 것입니다. 이를 통해 컴파일러는 변환 논리를 대형 커널의 나머지 본문과 독립적으로 특수화하고 인라인 할 수 있습니다. +컴파일 시간을 줄이고 복잡성을 테스트하는 한 가지 방법은 원하는 유형으로 변환하기위한 로직과 계산을 분리하는 것입니다. +이를 통해 컴파일러는 변환 논리를 대형 커널의 나머지 본문과 독립적으로 특수화하고 인라인 할 수 있습니다. 이것은 더 큰 클래스 유형에서 변환 할 때 나타나는 공통 패턴입니다 알고리즘이 실제로 지원하는 특정 인수 유형으로 변환합니다. @@ -643,23 +669,23 @@ matmul(a, b) = matmul(promote(a, b)...) 함수매개변수는 "varargs"함수 ([Varargs Functions](@ref))에 제공 될 수있는 인수의 수를 제한하는 데 사용될 수도 있습니다. -`Vararg {T, N}` 표기법은 그러한 제약을 나타내기 위해 사용됩니다. 예 : +`Vararg {T, N}` 표기법은 그러한 제약을 나타내기 위해 사용됩니다. 예: ```jldoctest julia> bar(a,b,x::Vararg{Any,2}) = (a,b,x) -bar (한가지 방법을 가진 일반함수) +bar (generic function with 1 method) julia> bar(1,2,3) -ERROR: MethodError: 메서드 일치 bar(::Int64, ::Int64, ::Int64) 없음 -가장 가까운 후보자는 다음과 같습니다.: +ERROR: MethodError: no method matching bar(::Int64, ::Int64, ::Int64) +Closest candidates are: bar(::Any, ::Any, ::Any, !Matched::Any) at none:1 julia> bar(1,2,3,4) (1, 2, (3, 4)) julia> bar(1,2,3,4,5) -ERROR: MethodError: 메서드 일치 bar(::Int64, ::Int64, ::Int64, ::Int64, ::Int64) 없음 -가장 가까운 후보자는 다음과 같습니다.: +ERROR: MethodError: no method matching bar(::Int64, ::Int64, ::Int64, ::Int64, ::Int64) +Closest candidates are: bar(::Any, ::Any, ::Any, ::Any) at none:1 ``` @@ -740,7 +766,6 @@ julia> p(3) 931 ``` - 이 메카니즘은 타입 생성자와 클로저 (주변 환경을 참조하는 내부 함수)가 줄리아에서 어떻게 작동 하는지를 결정하는 열쇠이기도합니다. ## 빈 일반 함수 @@ -817,20 +842,15 @@ f(x::A, y::A) = ... f(x, y) = f(g(x), g(y)) ``` -where `g` converts the argument to type `A`. This is a very specific -example of the more general principle of -[orthogonal design](https://en.wikipedia.org/wiki/Orthogonality_(programming)), -in which separate concepts are assigned to separate methods. Here, `g` -will most likely need a fallback definition 여기서 `g` 는 인수를 타입 A로 변환합니다. -이것은 별도의 개념이 별도의 방법으로 할당 된 [직교 설계](https://en.wikipedia.org/wiki/Orthogonality_ (프로그래밍))의 보다 일반적인 매우 구체적인 예입니다. -여기서 `g` 는 대개 대체 정의를 요구합니다. +이것은 별도의 개념이 별도의 방법으로 할당된 [직교 설계(orthogonal design)](https://en.wikipedia.org/wiki/Orthogonality_(programming))의 보다 일반적인 매우 구체적인 예입니다. +여기서 `g` 는 대개 fallback 정의를 요구합니다 + ```julia g(x::A) = x ``` - -A related strategy은 `x`와`y`를 일반적인 유형으로 유도하기 위해 `promote` 을 이용합니다 : +이와 관련된 전략은 `x`와`y`를 일반적인 유형으로 유도하기 위해 `promote` 을 이용합니다: ```julia f(x::T, y::T) where {T} = ... @@ -838,18 +858,12 @@ f(x, y) = f(promote(x, y)...) ``` 이 디자인의 한 가지 위험은 `x` 와 `y` 를 같은 유형으로 변환하는 적절한 프로모션 방법이 없으면 두 번째 방법이 무한히 반복되어 스택 오버플로가 트리거 될 수 있다는 것입니다. -exported 안된 함수 `Base.promote_noncircular` 는 대안으로 사용할 수 있습니다. 프로모션이 실패하면 여전히 오류가 발생하지만 더 구체적인 오류 메시지로 인해 더 빨리 오류가 발생합니다. +exported 안 된 함수 `Base.promote_noncircular` 는 대안으로 사용할 수 있습니다. 프로모션이 실패하면 여전히 오류가 발생하지만 더 구체적인 오류 메시지로 인해 더 빨리 오류가 발생합니다. ### 한 번에 하나의 인수로 디스패치 -If you need to dispatch on multiple arguments, and there are many -fallbacks with too many combinations to make it practical to define -all possible variants, then consider introducing a "name cascade" -where (for example) you dispatch on the first argument and then call -an internal method: - 여러 인수를 전달해야하거나 가능한 많은 변형을 정의하기 위해 너무 많은 조합을 사용하는 많은 대체 시스템이있는 경우에는 -"name cascade"를 도입하여 (예를 들어) 첫 번째 인수로 전달한 다음 내부 메서드를 호출하는 것을 고려하십시오. +"name cascade"를 도입하여 (예를 들어) 첫 번째 인수로 전달한 다음 내부 메서드를 호출하는 것을 고려하십시오: ```julia f(x::A, y) = _fA(x, y) @@ -877,10 +891,13 @@ f(x::B, y) = _fB(x, y) ``` 가장 좋은 방법은 다음중 하나의 방법을 정의하는 것을 피하는 것입니다. -대신, 일반적인 메서드`- A::AbstractArray, b)` 이 메서드가 각 컨테이너 유형과 요소 유형에 대해 올바른 작업을 수행하는 일반 호출(예 :`similar` and `-`)로 구현되었는지 확인하십시오. 이것은 당신의 메서드를 [직교 화](@ref man-methods-orthogonalize) 하는 조언의 좀 더 복잡한 변형입니다. +대신, 일반적인 메서드`- A::AbstractArray, b)` 이 메서드가 +각 컨테이너 유형과 요소 유형에 대해 올바른 작업을 수행하는 일반 호출(예 :`similar` and `-`)로 구현되었는지 확인하십시오. +이것은 당신의 메서드를 [직교화](@ref man-methods-orthogonalize) 하는 조언의 좀 더 복잡한 변형입니다. - -이 접근법이 가능하지 않을 때 모호성을 해결하는 것에 대해 다른 개발자와 토론을 시작하는 것이 좋습니다. 처음에 하나의 방법이 정의되었다고해서 그것이 반드시 수정되거나 제거 될 수 없다는 것을 의미하지는 않습니다. 최후의 수단으로 한 개발자는 "반창고"방법을 정의 할 수 있습니다 +이 접근법이 가능하지 않을 때 모호성을 해결하는 것에 대해 다른 개발자와 토론을 시작하는 것이 좋습니다. +처음에 하나의 방법이 정의되었다고해서 그것이 반드시 수정되거나 제거 될 수 없다는 것을 의미하지는 않습니다. +최후의 수단으로 한 개발자는 "반창고(band-aid)" 방법을 정의 할 수 있습니다 ```julia -(A::MyArrayType{T}, b::Date) where {T<:Date} = ... @@ -891,7 +908,7 @@ f(x::B, y) = _fB(x, y) ### 복잡한 인수 "cascades"와 기본 인수 기본값을 제공하는 "cascades"메서드를 정의하는 경우 잠재적 기본값에 해당하는 인수를 삭제하는 데 주의해야합니다. - 예를 들어, 디지털 필터링 알고리즘을 작성 중이며 패딩을 적용하여 신호의 가장자리를 처리하는 방법이 있다고 가정합니다. : +예를 들어, 디지털 필터링 알고리즘을 작성 중이며 패딩을 적용하여 신호의 가장자리를 처리하는 방법이 있다고 가정합니다: ```julia function myfilter(A, kernel, ::Replicate) @@ -900,7 +917,7 @@ function myfilter(A, kernel, ::Replicate) end ``` -이것은 디폴트 패딩을 제공하는 메서드와 충돌 할 것이다. : +이것은 디폴트 패딩을 제공하는 메서드와 충돌 할 것이다: ```julia myfilter(A, kernel) = myfilter(A, kernel, Replicate()) # replicate the edge by default @@ -923,16 +940,10 @@ end # 다른 패딩 방법은 여기에 있습니다. function myfilter(A, kernel, ::NoPad) - # 다음은 핵심 계산의 "실제"구현입니다. + # 다음은 핵심 계산의 "실제" 구현입니다. end ``` -`NoPad` is supplied in the same argument position as any other kind of -padding, so it keeps the dispatch hierarchy well organized and with -reduced likelihood of ambiguities. Moreover, it extends the "public" -`myfilter` interface: a user who wants to control the padding -explicitly can call the `NoPad` variant directly. - `NoPad`는 다른 종류의 패딩과 같은 인수 위치에서 제공되기 때문에, 디스패치 계층을 잘 정리하고 애매하게 만들 가능성이 낮습니다. 또한, "public" `myfilter` 인터페이스를 확장합니다. 패딩을 명시 적으로 제어하려는 사용자는 `NoPad` 변형을 직접 호출 할 수 있습니다. diff --git a/src/manual/strings.md b/src/manual/strings.md index 6887919..e03c6a9 100644 --- a/src/manual/strings.md +++ b/src/manual/strings.md @@ -537,23 +537,23 @@ julia> findnext(isequal('o'), "xylophone", 5) julia> findnext(isequal('o'), "xylophone", 8) ``` -You can use the [`contains`](@ref) function to check if a substring is contained in a string: +You can use the [`occursin`](@ref) function to check if a substring is found within a string: ```jldoctest -julia> contains("Hello, world.", "world") +julia> occursin("world", "Hello, world.") true -julia> contains("Xylophon", "o") +julia> occursin("o", "Xylophon") true -julia> contains("Xylophon", "a") +julia> occursin("a", "Xylophon") false -julia> contains("Xylophon", 'o') +julia> occursin('o', "Xylophon") true ``` -The last example shows that [`contains`](@ref) can also look for a character literal. +The last example shows that [`occursin`](@ref) can also look for a character literal. Two other handy string functions are [`repeat`](@ref) and [`join`](@ref): @@ -608,20 +608,20 @@ julia> typeof(ans) Regex ``` -To check if a regex matches a string, use [`contains`](@ref): +To check if a regex matches a string, use [`occursin`](@ref): ```jldoctest -julia> contains("not a comment", r"^\s*(?:#|$)") +julia> occursin(r"^\s*(?:#|$)", "not a comment") false -julia> contains("# a comment", r"^\s*(?:#|$)") +julia> occursin(r"^\s*(?:#|$)", "# a comment") true ``` -As one can see here, [`contains`](@ref) simply returns true or false, indicating whether the -given regex matches the string or not. Commonly, however, one wants to know not just whether a -string matched, but also *how* it matched. To capture this information about a match, use the -[`match`](@ref) function instead: +As one can see here, [`occursin`](@ref) simply returns true or false, indicating whether a +match for the given regex occurs in the string. Commonly, however, one wants to know not +just whether a string matched, but also *how* it matched. To capture this information about +a match, use the [`match`](@ref) function instead: ```jldoctest julia> match(r"^\s*(?:#|$)", "not a comment") diff --git a/src/manual/variables-and-scoping.md b/src/manual/variables-and-scoping.md index 38ac858..5e769ca 100644 --- a/src/manual/variables-and-scoping.md +++ b/src/manual/variables-and-scoping.md @@ -363,7 +363,7 @@ julia> Fs = Vector{Any}(undef, 2); i = 1; julia> while i <= 2 Fs[i] = ()->i - i += 1 + global i += 1 end julia> Fs[1]() @@ -384,7 +384,7 @@ julia> while i <= 2 let i = i Fs[i] = ()->i end - i += 1 + global i += 1 end julia> Fs[1]() diff --git a/src/stdlib/Dates.md b/src/stdlib/Dates.md index 3a434cc..0c76284 100644 --- a/src/stdlib/Dates.md +++ b/src/stdlib/Dates.md @@ -399,7 +399,7 @@ of dealing with daylight savings, leap seconds, etc.). As a bonus, all period arithmetic objects work directly with ranges: ```jldoctest -julia> dr = Date(2014,1,29):Date(2014,2,3) +julia> dr = Date(2014,1,29):Day(1):Date(2014,2,3) 2014-01-29:1 day:2014-02-03 julia> collect(dr) @@ -484,7 +484,7 @@ range: ```jldoctest # Pittsburgh street cleaning; Every 2nd Tuesday from April to November # Date range from January 1st, 2014 to January 1st, 2015 -julia> dr = Dates.Date(2014):Dates.Date(2015); +julia> dr = Dates.Date(2014):Day(1):Dates.Date(2015); julia> filter(dr) do x Dates.dayofweek(x) == Dates.Tue && diff --git a/src/stdlib/Pkg3.md b/src/stdlib/Pkg3.md index b54bddc..b5e8d1a 100644 --- a/src/stdlib/Pkg3.md +++ b/src/stdlib/Pkg3.md @@ -26,7 +26,7 @@ To generate files for a new project, use `pkg> generate`. pkg> generate HelloWorld ``` -This creates a new project `HelloWorld` with the following files +This creates a new project `HelloWorld` with the following files (visualized with the external [`tree` command](https://linux.die.net/man/1/tree)): ```jl julia> cd("HelloWorld") diff --git a/src/stdlib/dates.md b/src/stdlib/dates.md index 3a434cc..0c76284 100644 --- a/src/stdlib/dates.md +++ b/src/stdlib/dates.md @@ -399,7 +399,7 @@ of dealing with daylight savings, leap seconds, etc.). As a bonus, all period arithmetic objects work directly with ranges: ```jldoctest -julia> dr = Date(2014,1,29):Date(2014,2,3) +julia> dr = Date(2014,1,29):Day(1):Date(2014,2,3) 2014-01-29:1 day:2014-02-03 julia> collect(dr) @@ -484,7 +484,7 @@ range: ```jldoctest # Pittsburgh street cleaning; Every 2nd Tuesday from April to November # Date range from January 1st, 2014 to January 1st, 2015 -julia> dr = Dates.Date(2014):Dates.Date(2015); +julia> dr = Dates.Date(2014):Day(1):Dates.Date(2015); julia> filter(dr) do x Dates.dayofweek(x) == Dates.Tue && From dd19fe502b94e3643ebc739794c88e57eb5e2b70 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Tue, 27 Mar 2018 03:47:52 +0900 Subject: [PATCH 015/153] update Julia Commit 89c4e3d2ee --- codex/NEWS.md | 9 +++ codex/stdlib/Pkg3.md | 182 +++++++++++++++++++++++++++++++++++++++++-- src/NEWS.md | 9 +++ src/stdlib/Pkg3.md | 182 +++++++++++++++++++++++++++++++++++++++++-- tools/check_codex.jl | 2 +- 5 files changed, 373 insertions(+), 11 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index 16e0a09..5652188 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -456,6 +456,9 @@ This section lists changes that do not have deprecation warnings. * `indexin` now returns the first rather than the last matching index ([#25998](https://github.com/JuliaLang/julia/issues/25998)). + * `parse(::Type, ::Char)` now uses a default base of 10, like other number parsing + methods, instead of 36 ([#26576](https://github.com/JuliaLang/julia/issues/26576)). + Library improvements -------------------- @@ -914,6 +917,12 @@ Deprecated or removed * `map` on dictionaries previously operated on `key=>value` pairs. This behavior is deprecated, and in the future `map` will operate only on values ([#5794](https://github.com/JuliaLang/julia/issues/5794)). + * Previously, broadcast defaulted to treating its arguments as scalars if they were not + arrays. This behavior is deprecated, and in the future `broadcast` will default to + iterating over all its arguments. Wrap arguments you wish to be treated as scalars with + `Ref()` or a 1-tuple. Package developers can choose to allow a non-iterable type `T` to + always behave as a scalar by implementing `broadcastable(x::T) = Ref(x)` ([#26212](https://github.com/JuliaLang/julia/issues/26212)). + * Automatically broadcasted `+` and `-` for `array + scalar`, `scalar - array`, and so-on have been deprecated due to inconsistency with linear algebra. Use `.+` and `.-` for these operations instead ([#22880](https://github.com/JuliaLang/julia/issues/22880), [#22932](https://github.com/JuliaLang/julia/issues/22932)). diff --git a/codex/stdlib/Pkg3.md b/codex/stdlib/Pkg3.md index b5e8d1a..13307ef 100644 --- a/codex/stdlib/Pkg3.md +++ b/codex/stdlib/Pkg3.md @@ -12,7 +12,179 @@ Pages = [ ## Introduction -Pkg3 is the package manager for Julia. +Pkg3 is the standard package manager for Julia 1.0 and newer. Unlike traditional +package managers, which install and manage a single global set of packages, Pkg3 +is designed around “environments”: independent sets of packages that can be +local to an individual project or shared and selected by name. The exact set of +packages and versions in an environment is captured in a _manifest file_ which +can be checked into a project repository and tracked in version control, +significantly improving reproducibility of projects. If you’ve ever tried to run +code you haven’t used in a while only to find that you can’t get anything to +work because you’ve updated or uninstalled some of the packages your project was +using, you’ll understand the motivation for this approach. In Pkg3, since each +project maintains its own independent set of package versions, you’ll never have +this problem again. Moreover, if you check out a project on a new system, you +can simply materialize the environment described by its manifest file and +immediately be up and running with a known-good set of dependencies. + +Since environments are managed and updated independently from each other, +“dependency hell” is significantly alleviated in Pkg3. If you want to use the +latest and greatest version of some package in a new project but you’re stuck on +an older version in a different project, that’s no problem – since they have +separate environments they can just use different versions, which are both +installed at the same time in different locations on your system. The location +of each package version is canonical, so when environments use the same versions +of packages, they can share installations, avoiding unnecessary duplication of +the package. Old package versions that are no longer used by any environments +are periodically “garbage collected” by the package manager. + +Pkg3’s approach to local environments may be familiar to people who have used +Python’s `virtualenv` or Ruby’s `bundler`. In Julia, instead of hacking the +language’s code loading mechanisms to support environments, we have the benefit +that Julia natively understands them. In addition, Julia environments are +“stackable”: you can overlay one environment with another and thereby have +access to additional packages outside of the primary environment. This makes it +easy to work on a project, which provides the primary environment, while still +having access to all your usual dev tools like profilers, debuggers, and so on, +just by having an environment including these dev tools later in the load path. + +Last but not least, Pkg3 is designed to support federated package registries. +This means that it allows multiple registries managed by different parties to +interact seamlessly. In particular, this includes private registries which can +live behind corporate firewalls. You can install and update your own packages +from a private registry with exactly the same tools and workflows that you use +to install and manage official Julia packages. If you urgently need to apply a +hotfix for a public package that’s critical to your company’s product, you can +tag a private version of it in your company’s internal registry and get a fix to +your developers and ops teams quickly and easily without having to wait for an +upstream patch to be accepted and published. Once an official fix is published, +however, you can just upgrade your dependencies and you'll be back on an +official release again. + +## Glossary + +**Project:** a source tree with a standard layout, including a `src` directory +for the main body of Julia code, a `test` directory for testing the project, +`docs` for documentation files, and optionally a `build` directory for a build +script and its outputs. A project will typically also have a project file and +may optionally have a manifest file: + +- **Project file:** a file in the root directory of a project, named + `Project.toml` (or `JuliaProject.toml`) describing metadata about the project, + including its name, UUID (for packages), authors, license, and the names and + UUIDs of packages and libraries that it depends on. + +- **Manifest file:** a file in the root directory of a project, named + `Manifest.toml` (or `JuliaManifest.toml`) describing a complete dependency graph + and exact versions of each package and library used by a project. + +**Package:** a project which provides reusable functionality that can be used by +other Julia projects via `import X` or `using X`. A package should have a +project file with a `uuid` entry giving its package UUID. This UUID is used to +identify the package in projects that depend on it. + +!!! note + For legacy reasons it is possible to load a package without a project file or + UUID from the REPL or the top-level of a script. It is not possible, however, + to load a package with a project file or UUID from a project with them. Once + you've loaded from a project file, everything needs a project file and UUID. + +**Application:** a project which provides standalone functionality not intended +to be reused by other Julia projects. For example a web application or a +commmand-line utility. An application may have a UUID but does not need one. An +application may also provide global configuration options for packages it +depends on. Packages, on the other hand, may not provide global configuration +since that could conflict with the configuration of the main application. + +!!! note + **Projects _vs._ Packages _vs._ Applications:** + + 1. Project is an umbrella term: packages and applications are kinds of projects. + 2. Packages should have UUIDs, applications can have a UUIDs but don't need them. + 3. Applications can provide global configuration, whereas packages cannot. + +**Library (future work):** a compiled binary dependency (not written in Julia) +packaged to be used by a Julia project. These are currently typically built in- +place by a `deps/build.jl` script in a project’s source tree, but in the future +we plan to make libraries first-class entities directly installed and upgraded +by the package manager. + +**Environment:** the combination of the top-level name map provided by a project +file combined with the dependency graph and map from packages to their entry points +provided by a manifest file. For more detail see the manual section on code loading. + +- **Explicit environment:** an environment in the form of an explicit project + file and an optional corresponding manifest file together in a directory. If the + manifest file is absent then the implied dependency graph and location maps are + empty. + +- **Implicit environment:** an environment provided as a directory (without a + project file or manifest file) containing packages with entry points of the form + `X.jl`, `X.jl/src/X.jl` or `X/src/X.jl`. The top-level name map is implied by + these entry points. The dependency graph is implied by the existence of project + files inside of these package directories, e.g. `X.jl/Project.toml` or + `X/Project.toml`. The dependencies of the `X` package are the dependencies in + the corresponding project file if there is one. The location map is implied by + the entry points themselves. + +**Registry:** a source tree with a standard layout recording metadata about a +registered set of packages, the tagged versions of them which are available, and +which versions of packages are compatible or incompatible with each other. A +registry is indexed by package name and UUID, and has a directory for each +registered package providing the following metadata about it: + + - name – e.g. `DataFrames` + - UUID – e.g. `a93c6f00-e57d-5684-b7b6-d8193f3e46c0` + - authors – e.g. `Jane Q. Developer ` + - license – e.g. MIT, BSD3, or GPLv2 + - repository – e.g. `https://github.com/JuliaData/DataFrames.jl.git` + - description – a block of text summarizing the functionality of a package + - keywords – e.g. `data`, `tabular`, `analysis`, `statistics` + - versions – a list of all registered version tags + +For each registered version of a package, the following information is provided: + + - its semantic version number – e.g. `v1.2.3` + - its git tree SHA-1 hash – e.g. `7ffb18ea3245ef98e368b02b81e8a86543a11103` + - a map from names to UUIDs of dependencies + - which versions of other packages it is compatible/incompatible with + +Dependencies and compatiblity are stored in a compressed but human-readable +format using ranges of package verions. + +**Depot:** a directory on a system where various package-related resources live, +including: + + - `environments`: shared named environments (e.g. `v0.7`, `devtools`) + - `clones`: bare clones of package repositories + - `compiled`: cached compiled package images (`.ji` files) + - `config`: global configuration files (e.g. `startup.jl`) + - `dev`: default directory for package development + - `logs`: log files (e.g. `manifest_usage.toml`, `repl_history.jl`) + - `packages`: installed package versions + - `registries`: clones of registries (e.g. `Uncurated`) + +**Load path:** a stack of environments where package identities, their +dependencies, and entry-points are searched for. The load path is controlled in +Julia by the `LOAD_PATH` global variable which is populated at startup based on +the value of the `JULIA_LOAD_PATH` environment variable. The first entry is your +primary environment, often the current project, while later entries provide +additional packages one may want to use from the REPL or top-level scripts. + +**Depot path:** a stack of depot locations where the package manager, as well as +Julia's code loading mechanisms, look for registries, installed packages, named +environments, repo clones, cached compiled package images, and configuration +files. The depot path is controlled by the Julia `DEPOT_PATH` global variable +which is populated at startup based on the value of the `JULIA_DEPOT_PATH` +environment variable. The first entry is the “user depot” and should be writable +by and owned by the current user. The user depot is where: registries are +cloned, new package versions are installed, named environments are created and +updated, package repos are cloned, new compiled package image files are saved, +log files are written, development packages are checked out by default, and +global configuration data is saved. Later entries in the depot path are treated +as read-only and are appropriate for registries, packages, etc. installed and +managed by system administrators. + ## Getting Started @@ -71,7 +243,7 @@ Hello World! ### Adding packages to the project -Let's say we want to use the standard library package `Random` and the registered package `JSON` in our project. +Let’s say we want to use the standard library package `Random` and the registered package `JSON` in our project. We simply `add` these packages: ``` @@ -87,7 +259,7 @@ pkg> add Random JSON ... ``` -Both `Random` and `JSON` got added to the project's `Project.toml` file, and the resulting dependencies got added to the `Manifest.toml` file. +Both `Random` and `JSON` got added to the project’s `Project.toml` file, and the resulting dependencies got added to the `Manifest.toml` file. The resolver has installed each package with the highest possible version, while still respecting the compatibility that each package enforce on its dependencies. We can now use both `Random` and `JSON` in our project. Changing `src/HelloWorld.jl` to @@ -143,13 +315,13 @@ For unregistered packages we could have given a branch (or commit SHA) to track ## Developing packages -Let's say we found a bug in `JSON` that we want to fix. We can get the full git-repo using the `develop` command +Let’s say we found a bug in `JSON` that we want to fix. We can get the full git-repo using the `develop` command ``` pkg> develop JSON Cloning package from https://github.com/JuliaIO/JSON.jl.git Resolving package versions... - Updating "~/.julia/environments/v0.7/Project.toml" + Updating "~/Documents/HelloWorld/Project.toml" [682c06a0] + JSON v0.17.1+ [~/.julia/dev/JSON] ... ``` diff --git a/src/NEWS.md b/src/NEWS.md index e5c6265..5696c8c 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -444,6 +444,9 @@ This section lists changes that do not have deprecation warnings. * `indexin` now returns the first rather than the last matching index ([#25998](https://github.com/JuliaLang/julia/issues/25998)). + * `parse(::Type, ::Char)` now uses a default base of 10, like other number parsing + methods, instead of 36 ([#26576](https://github.com/JuliaLang/julia/issues/26576)). + Library improvements -------------------- @@ -902,6 +905,12 @@ Deprecated or removed * `map` on dictionaries previously operated on `key=>value` pairs. This behavior is deprecated, and in the future `map` will operate only on values ([#5794](https://github.com/JuliaLang/julia/issues/5794)). + * Previously, broadcast defaulted to treating its arguments as scalars if they were not + arrays. This behavior is deprecated, and in the future `broadcast` will default to + iterating over all its arguments. Wrap arguments you wish to be treated as scalars with + `Ref()` or a 1-tuple. Package developers can choose to allow a non-iterable type `T` to + always behave as a scalar by implementing `broadcastable(x::T) = Ref(x)` ([#26212](https://github.com/JuliaLang/julia/issues/26212)). + * Automatically broadcasted `+` and `-` for `array + scalar`, `scalar - array`, and so-on have been deprecated due to inconsistency with linear algebra. Use `.+` and `.-` for these operations instead ([#22880](https://github.com/JuliaLang/julia/issues/22880), [#22932](https://github.com/JuliaLang/julia/issues/22932)). diff --git a/src/stdlib/Pkg3.md b/src/stdlib/Pkg3.md index b5e8d1a..13307ef 100644 --- a/src/stdlib/Pkg3.md +++ b/src/stdlib/Pkg3.md @@ -12,7 +12,179 @@ Pages = [ ## Introduction -Pkg3 is the package manager for Julia. +Pkg3 is the standard package manager for Julia 1.0 and newer. Unlike traditional +package managers, which install and manage a single global set of packages, Pkg3 +is designed around “environments”: independent sets of packages that can be +local to an individual project or shared and selected by name. The exact set of +packages and versions in an environment is captured in a _manifest file_ which +can be checked into a project repository and tracked in version control, +significantly improving reproducibility of projects. If you’ve ever tried to run +code you haven’t used in a while only to find that you can’t get anything to +work because you’ve updated or uninstalled some of the packages your project was +using, you’ll understand the motivation for this approach. In Pkg3, since each +project maintains its own independent set of package versions, you’ll never have +this problem again. Moreover, if you check out a project on a new system, you +can simply materialize the environment described by its manifest file and +immediately be up and running with a known-good set of dependencies. + +Since environments are managed and updated independently from each other, +“dependency hell” is significantly alleviated in Pkg3. If you want to use the +latest and greatest version of some package in a new project but you’re stuck on +an older version in a different project, that’s no problem – since they have +separate environments they can just use different versions, which are both +installed at the same time in different locations on your system. The location +of each package version is canonical, so when environments use the same versions +of packages, they can share installations, avoiding unnecessary duplication of +the package. Old package versions that are no longer used by any environments +are periodically “garbage collected” by the package manager. + +Pkg3’s approach to local environments may be familiar to people who have used +Python’s `virtualenv` or Ruby’s `bundler`. In Julia, instead of hacking the +language’s code loading mechanisms to support environments, we have the benefit +that Julia natively understands them. In addition, Julia environments are +“stackable”: you can overlay one environment with another and thereby have +access to additional packages outside of the primary environment. This makes it +easy to work on a project, which provides the primary environment, while still +having access to all your usual dev tools like profilers, debuggers, and so on, +just by having an environment including these dev tools later in the load path. + +Last but not least, Pkg3 is designed to support federated package registries. +This means that it allows multiple registries managed by different parties to +interact seamlessly. In particular, this includes private registries which can +live behind corporate firewalls. You can install and update your own packages +from a private registry with exactly the same tools and workflows that you use +to install and manage official Julia packages. If you urgently need to apply a +hotfix for a public package that’s critical to your company’s product, you can +tag a private version of it in your company’s internal registry and get a fix to +your developers and ops teams quickly and easily without having to wait for an +upstream patch to be accepted and published. Once an official fix is published, +however, you can just upgrade your dependencies and you'll be back on an +official release again. + +## Glossary + +**Project:** a source tree with a standard layout, including a `src` directory +for the main body of Julia code, a `test` directory for testing the project, +`docs` for documentation files, and optionally a `build` directory for a build +script and its outputs. A project will typically also have a project file and +may optionally have a manifest file: + +- **Project file:** a file in the root directory of a project, named + `Project.toml` (or `JuliaProject.toml`) describing metadata about the project, + including its name, UUID (for packages), authors, license, and the names and + UUIDs of packages and libraries that it depends on. + +- **Manifest file:** a file in the root directory of a project, named + `Manifest.toml` (or `JuliaManifest.toml`) describing a complete dependency graph + and exact versions of each package and library used by a project. + +**Package:** a project which provides reusable functionality that can be used by +other Julia projects via `import X` or `using X`. A package should have a +project file with a `uuid` entry giving its package UUID. This UUID is used to +identify the package in projects that depend on it. + +!!! note + For legacy reasons it is possible to load a package without a project file or + UUID from the REPL or the top-level of a script. It is not possible, however, + to load a package with a project file or UUID from a project with them. Once + you've loaded from a project file, everything needs a project file and UUID. + +**Application:** a project which provides standalone functionality not intended +to be reused by other Julia projects. For example a web application or a +commmand-line utility. An application may have a UUID but does not need one. An +application may also provide global configuration options for packages it +depends on. Packages, on the other hand, may not provide global configuration +since that could conflict with the configuration of the main application. + +!!! note + **Projects _vs._ Packages _vs._ Applications:** + + 1. Project is an umbrella term: packages and applications are kinds of projects. + 2. Packages should have UUIDs, applications can have a UUIDs but don't need them. + 3. Applications can provide global configuration, whereas packages cannot. + +**Library (future work):** a compiled binary dependency (not written in Julia) +packaged to be used by a Julia project. These are currently typically built in- +place by a `deps/build.jl` script in a project’s source tree, but in the future +we plan to make libraries first-class entities directly installed and upgraded +by the package manager. + +**Environment:** the combination of the top-level name map provided by a project +file combined with the dependency graph and map from packages to their entry points +provided by a manifest file. For more detail see the manual section on code loading. + +- **Explicit environment:** an environment in the form of an explicit project + file and an optional corresponding manifest file together in a directory. If the + manifest file is absent then the implied dependency graph and location maps are + empty. + +- **Implicit environment:** an environment provided as a directory (without a + project file or manifest file) containing packages with entry points of the form + `X.jl`, `X.jl/src/X.jl` or `X/src/X.jl`. The top-level name map is implied by + these entry points. The dependency graph is implied by the existence of project + files inside of these package directories, e.g. `X.jl/Project.toml` or + `X/Project.toml`. The dependencies of the `X` package are the dependencies in + the corresponding project file if there is one. The location map is implied by + the entry points themselves. + +**Registry:** a source tree with a standard layout recording metadata about a +registered set of packages, the tagged versions of them which are available, and +which versions of packages are compatible or incompatible with each other. A +registry is indexed by package name and UUID, and has a directory for each +registered package providing the following metadata about it: + + - name – e.g. `DataFrames` + - UUID – e.g. `a93c6f00-e57d-5684-b7b6-d8193f3e46c0` + - authors – e.g. `Jane Q. Developer ` + - license – e.g. MIT, BSD3, or GPLv2 + - repository – e.g. `https://github.com/JuliaData/DataFrames.jl.git` + - description – a block of text summarizing the functionality of a package + - keywords – e.g. `data`, `tabular`, `analysis`, `statistics` + - versions – a list of all registered version tags + +For each registered version of a package, the following information is provided: + + - its semantic version number – e.g. `v1.2.3` + - its git tree SHA-1 hash – e.g. `7ffb18ea3245ef98e368b02b81e8a86543a11103` + - a map from names to UUIDs of dependencies + - which versions of other packages it is compatible/incompatible with + +Dependencies and compatiblity are stored in a compressed but human-readable +format using ranges of package verions. + +**Depot:** a directory on a system where various package-related resources live, +including: + + - `environments`: shared named environments (e.g. `v0.7`, `devtools`) + - `clones`: bare clones of package repositories + - `compiled`: cached compiled package images (`.ji` files) + - `config`: global configuration files (e.g. `startup.jl`) + - `dev`: default directory for package development + - `logs`: log files (e.g. `manifest_usage.toml`, `repl_history.jl`) + - `packages`: installed package versions + - `registries`: clones of registries (e.g. `Uncurated`) + +**Load path:** a stack of environments where package identities, their +dependencies, and entry-points are searched for. The load path is controlled in +Julia by the `LOAD_PATH` global variable which is populated at startup based on +the value of the `JULIA_LOAD_PATH` environment variable. The first entry is your +primary environment, often the current project, while later entries provide +additional packages one may want to use from the REPL or top-level scripts. + +**Depot path:** a stack of depot locations where the package manager, as well as +Julia's code loading mechanisms, look for registries, installed packages, named +environments, repo clones, cached compiled package images, and configuration +files. The depot path is controlled by the Julia `DEPOT_PATH` global variable +which is populated at startup based on the value of the `JULIA_DEPOT_PATH` +environment variable. The first entry is the “user depot” and should be writable +by and owned by the current user. The user depot is where: registries are +cloned, new package versions are installed, named environments are created and +updated, package repos are cloned, new compiled package image files are saved, +log files are written, development packages are checked out by default, and +global configuration data is saved. Later entries in the depot path are treated +as read-only and are appropriate for registries, packages, etc. installed and +managed by system administrators. + ## Getting Started @@ -71,7 +243,7 @@ Hello World! ### Adding packages to the project -Let's say we want to use the standard library package `Random` and the registered package `JSON` in our project. +Let’s say we want to use the standard library package `Random` and the registered package `JSON` in our project. We simply `add` these packages: ``` @@ -87,7 +259,7 @@ pkg> add Random JSON ... ``` -Both `Random` and `JSON` got added to the project's `Project.toml` file, and the resulting dependencies got added to the `Manifest.toml` file. +Both `Random` and `JSON` got added to the project’s `Project.toml` file, and the resulting dependencies got added to the `Manifest.toml` file. The resolver has installed each package with the highest possible version, while still respecting the compatibility that each package enforce on its dependencies. We can now use both `Random` and `JSON` in our project. Changing `src/HelloWorld.jl` to @@ -143,13 +315,13 @@ For unregistered packages we could have given a branch (or commit SHA) to track ## Developing packages -Let's say we found a bug in `JSON` that we want to fix. We can get the full git-repo using the `develop` command +Let’s say we found a bug in `JSON` that we want to fix. We can get the full git-repo using the `develop` command ``` pkg> develop JSON Cloning package from https://github.com/JuliaIO/JSON.jl.git Resolving package versions... - Updating "~/.julia/environments/v0.7/Project.toml" + Updating "~/Documents/HelloWorld/Project.toml" [682c06a0] + JSON v0.17.1+ [~/.julia/dev/JSON] ... ``` diff --git a/tools/check_codex.jl b/tools/check_codex.jl index d1438c8..5d316db 100644 --- a/tools/check_codex.jl +++ b/tools/check_codex.jl @@ -33,7 +33,7 @@ function check_src_and_codex(path1, path2) (_,_,dircolon,filename) = chunk dir = replace(dircolon, ":" => "/") # src에만 있으면 src에 있는 파일 지우기 - if contains(dir, src_path) + if occursin(src_path, dir) if endswith(filename, ".swp") continue elseif !(filename in ignore_assets) From 256d7f11fcdcf1a5a10d681fdb099d713043e73f Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Wed, 4 Apr 2018 11:34:26 +0900 Subject: [PATCH 016/153] update Julia Commit a55c280d1b --- codex/NEWS.md | 11 ++++++++++- codex/devdocs/boundscheck.md | 4 ++-- codex/devdocs/offset-arrays.md | 14 +++++++------- codex/manual/control-flow.md | 2 +- codex/manual/interfaces.md | 2 +- codex/stdlib/FileWatching.md | 2 ++ codex/stdlib/REPL.md | 8 ++++---- codex/stdlib/filewatching.md | 2 ++ src/NEWS.md | 11 ++++++++++- src/devdocs/boundscheck.md | 4 ++-- src/devdocs/offset-arrays.md | 14 +++++++------- src/manual/interfaces.md | 2 +- src/stdlib/FileWatching.md | 2 ++ src/stdlib/REPL.md | 8 ++++---- src/stdlib/filewatching.md | 2 ++ 15 files changed, 57 insertions(+), 31 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index 5652188..81e4ad2 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -667,6 +667,12 @@ Deprecated or removed Instead, reshape the array or add trailing indices so the dimensionality and number of indices match ([#14770](https://github.com/JuliaLang/julia/issues/14770), [#23628](https://github.com/JuliaLang/julia/issues/23628)). + * The use of a positional dimension argument has largely been deprecated in favor of a + `dims` keyword argument. This includes the functions `sum`, `prod`, `maximum`, + `minimum`, `all`, `any`, `findmax`, `findmin`, `mean`, `varm`, `std`, `var`, `cov`, + `cor`, `median`, `mapreducedim`, `reducedim`, `sort`, `accumulate`, `accumulate!`, + `cumsum`, `cumsum!`, `cumprod`, `cumprod!`, `flipdim`, and `squeeze` ([#25501](https://github.com/JuliaLang/julia/issues/25501)). + * `indices(a)` and `indices(a,d)` have been deprecated in favor of `axes(a)` and `axes(a, d)` ([#25057](https://github.com/JuliaLang/julia/issues/25057)). @@ -1041,7 +1047,10 @@ Deprecated or removed * `search` and `rsearch` have been deprecated in favor of `findfirst`/`findnext` and `findlast`/`findprev` respectively, in combination with curried `isequal` and `in` - predicates for some methods ([#24673](https://github.com/JuliaLang/julia/issues/24673) + predicates for some methods ([#24673](https://github.com/JuliaLang/julia/issues/24673)). + + * `search(buf::IOBuffer, delim::UInt8)` has been deprecated in favor of either `occursin(delim, buf)` + (to test containment) or `readuntil(buf, delim)` (to read data up to `delim`) ([#26600](https://github.com/JuliaLang/julia/issues/26600)). * `ismatch(regex, str)` has been deprecated in favor of `contains(str, regex)` ([#24673](https://github.com/JuliaLang/julia/issues/24673)). diff --git a/codex/devdocs/boundscheck.md b/codex/devdocs/boundscheck.md index aaf5d1a..669cb52 100644 --- a/codex/devdocs/boundscheck.md +++ b/codex/devdocs/boundscheck.md @@ -63,7 +63,7 @@ of "permitted" indices of `A`. `checkbounds(A, I...)` throws an error if the indices are invalid, whereas `checkbounds(Bool, A, I...)` returns `false` in that circumstance. `checkbounds_indices` discards any information about the -array other than its `indices` tuple, and performs a pure indices-vs-indices comparison: this +array other than its `axes` tuple, and performs a pure indices-vs-indices comparison: this allows relatively few compiled methods to serve a huge variety of array types. Indices are specified as tuples, and are usually compared in a 1-1 fashion with individual dimensions handled by calling another important function, `checkindex`: typically, @@ -78,7 +78,7 @@ so `checkindex` checks a single dimension. All of these functions, including th If you have to customize bounds checking for a specific array type, you should specialize `checkbounds(Bool, A, I...)`. However, in most cases you should be able to rely on `checkbounds_indices` as long as you supply -useful `indices` for your array type. +useful `axes` for your array type. If you have novel index types, first consider specializing `checkindex`, which handles a single index for a particular dimension of an array. If you have a custom multidimensional index type diff --git a/codex/devdocs/offset-arrays.md b/codex/devdocs/offset-arrays.md index b5a1552..97328a6 100644 --- a/codex/devdocs/offset-arrays.md +++ b/codex/devdocs/offset-arrays.md @@ -17,7 +17,7 @@ the exported interfaces of Julia. As an overview, the steps are: - * replace many uses of `size` with `indices` + * replace many uses of `size` with `axes` * replace `1:length(A)` with `eachindex(A)`, or in some cases `linearindices(A)` * replace `length(A)` with `length(linearindices(A))` * replace explicit allocations like `Array{Int}(size(B))` with `similar(Array{Int}, axes(B))` @@ -52,7 +52,7 @@ To ensure that such errors are caught, in Julia 0.5 both `length` and `size`**sh error when passed an array with non-1 indexing. This is designed to force users of such arrays to check the code, and inspect it for whether it needs to be generalized. -### Using `indices` for bounds checks and loop iteration +### Using `axes` for bounds checks and loop iteration `axes(A)` (reminiscent of `size(A)`) returns a tuple of `AbstractUnitRange` objects, specifying the range of valid indices along each dimension of `A`. When `A` has unconventional indexing, @@ -61,7 +61,7 @@ is `axes(A, d)`. Base implements a custom range type, `OneTo`, where `OneTo(n)` means the same thing as `1:n` but in a form that guarantees (via the type system) that the lower index is 1. For any new [`AbstractArray`](@ref) -type, this is the default returned by `indices`, and it indicates that this array type uses "conventional" +type, this is the default returned by `axes`, and it indicates that this array type uses "conventional" 1-based indexing. Note that if you don't want to be bothered supporting arrays with non-1 indexing, you can add the following line: @@ -83,7 +83,7 @@ For this reason, your best option may be to iterate over the array with `eachind By this definition, 1-dimensional arrays always use Cartesian indexing with the array's native indices. To help enforce this, it's worth noting that the index conversion functions will throw an error if shape indicates a 1-dimensional array with unconventional indexing (i.e., is a `Tuple{UnitRange}` rather than a tuple of `OneTo`). For arrays with conventional indexing, these functions continue to work the same as always. -Using `indices` and `linearindices`, here is one way you could rewrite `mycopy!`: +Using `axes` and `linearindices`, here is one way you could rewrite `mycopy!`: ```julia function mycopy!(dest::AbstractVector, src::AbstractVector) @@ -151,7 +151,7 @@ omit the `@boundscheck` annotation so the check always runs). ### Custom `AbstractUnitRange` types -If you're writing a non-1 indexed array type, you will want to specialize `indices` so it returns +If you're writing a non-1 indexed array type, you will want to specialize `axes` so it returns a `UnitRange`, or (perhaps better) a custom `AbstractUnitRange`. The advantage of a custom type is that it "signals" the allocation type for functions like `similar`. If we're writing an array type for which indexing will start at 0, we likely want to begin by creating a new `AbstractUnitRange`, @@ -166,9 +166,9 @@ create a `ModuleA.ZeroArray`, whereas `ModuleB.ZeroRange` indicates a `ModuleB.Z Note that the Julia package [CustomUnitRanges.jl](https://github.com/JuliaArrays/CustomUnitRanges.jl) can sometimes be used to avoid the need to write your own `ZeroRange` type. -### Specializing `indices` +### Specializing `axes` -Once you have your `AbstractUnitRange` type, then specialize `indices`: +Once you have your `AbstractUnitRange` type, then specialize `axes`: ```julia Base.axes(A::ZeroArray) = map(n->ZeroRange(n), A.size) diff --git a/codex/manual/control-flow.md b/codex/manual/control-flow.md index bc2e105..1e60152 100644 --- a/codex/manual/control-flow.md +++ b/codex/manual/control-flow.md @@ -936,7 +936,7 @@ True kernel threads are discussed under the topic of [Parallel Computing](@ref). ### Core task operations -Let us explore the low level construct [`yieldto`](@ref) to underestand how task switching works. +Let us explore the low level construct [`yieldto`](@ref) to understand how task switching works. `yieldto(task,value)` suspends the current task, switches to the specified `task`, and causes that task's last [`yieldto`](@ref) call to return the specified `value`. Notice that [`yieldto`](@ref) is the only operation required to use task-style control flow; instead of calling and returning diff --git a/codex/manual/interfaces.md b/codex/manual/interfaces.md index 9a6b064..f951e7b 100644 --- a/codex/manual/interfaces.md +++ b/codex/manual/interfaces.md @@ -399,7 +399,7 @@ julia> mean(A) ``` 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`](@ref) +something other than 1), you should specialize `axes`. 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 man-custom-indices). diff --git a/codex/stdlib/FileWatching.md b/codex/stdlib/FileWatching.md index 7c42ddc..3944f5d 100644 --- a/codex/stdlib/FileWatching.md +++ b/codex/stdlib/FileWatching.md @@ -4,4 +4,6 @@ FileWatching.poll_fd FileWatching.poll_file FileWatching.watch_file +FileWatching.watch_folder +FileWatching.unwatch_folder ``` diff --git a/codex/stdlib/REPL.md b/codex/stdlib/REPL.md index 68b3937..d9080cf 100644 --- a/codex/stdlib/REPL.md +++ b/codex/stdlib/REPL.md @@ -290,13 +290,13 @@ max(x, y) in Base at operators.jl:215 max(a, b, c, xs...) in Base at operators.jl:281 ``` -Keywords are also displayed in the suggested methods, see second line after `;` where `limit` -and `keep` are keyword arguments: +Keywords are also displayed in the suggested methods after `;`, see below line where `limit` +and `keepempty` are keyword arguments: ```julia-repl julia> split("1 1 1", [TAB] -split(str::AbstractString) in Base at strings/util.jl:302 -split(str::T, splitter; limit, keep) where T<:AbstractString in Base at strings/util.jl:277 +split(str::AbstractString; limit, keepempty) in Base at strings/util.jl:302 +split(str::T, splitter; limit, keepempty) where T<:AbstractString in Base at strings/util.jl:277 ``` The completion of the methods uses type inference and can therefore see if the arguments match diff --git a/codex/stdlib/filewatching.md b/codex/stdlib/filewatching.md index 7c42ddc..3944f5d 100644 --- a/codex/stdlib/filewatching.md +++ b/codex/stdlib/filewatching.md @@ -4,4 +4,6 @@ FileWatching.poll_fd FileWatching.poll_file FileWatching.watch_file +FileWatching.watch_folder +FileWatching.unwatch_folder ``` diff --git a/src/NEWS.md b/src/NEWS.md index 5696c8c..9eba429 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -655,6 +655,12 @@ Deprecated or removed Instead, reshape the array or add trailing indices so the dimensionality and number of indices match ([#14770](https://github.com/JuliaLang/julia/issues/14770), [#23628](https://github.com/JuliaLang/julia/issues/23628)). + * The use of a positional dimension argument has largely been deprecated in favor of a + `dims` keyword argument. This includes the functions `sum`, `prod`, `maximum`, + `minimum`, `all`, `any`, `findmax`, `findmin`, `mean`, `varm`, `std`, `var`, `cov`, + `cor`, `median`, `mapreducedim`, `reducedim`, `sort`, `accumulate`, `accumulate!`, + `cumsum`, `cumsum!`, `cumprod`, `cumprod!`, `flipdim`, and `squeeze` ([#25501](https://github.com/JuliaLang/julia/issues/25501)). + * `indices(a)` and `indices(a,d)` have been deprecated in favor of `axes(a)` and `axes(a, d)` ([#25057](https://github.com/JuliaLang/julia/issues/25057)). @@ -1029,7 +1035,10 @@ Deprecated or removed * `search` and `rsearch` have been deprecated in favor of `findfirst`/`findnext` and `findlast`/`findprev` respectively, in combination with curried `isequal` and `in` - predicates for some methods ([#24673](https://github.com/JuliaLang/julia/issues/24673) + predicates for some methods ([#24673](https://github.com/JuliaLang/julia/issues/24673)). + + * `search(buf::IOBuffer, delim::UInt8)` has been deprecated in favor of either `occursin(delim, buf)` + (to test containment) or `readuntil(buf, delim)` (to read data up to `delim`) ([#26600](https://github.com/JuliaLang/julia/issues/26600)). * `ismatch(regex, str)` has been deprecated in favor of `contains(str, regex)` ([#24673](https://github.com/JuliaLang/julia/issues/24673)). diff --git a/src/devdocs/boundscheck.md b/src/devdocs/boundscheck.md index aaf5d1a..669cb52 100644 --- a/src/devdocs/boundscheck.md +++ b/src/devdocs/boundscheck.md @@ -63,7 +63,7 @@ of "permitted" indices of `A`. `checkbounds(A, I...)` throws an error if the indices are invalid, whereas `checkbounds(Bool, A, I...)` returns `false` in that circumstance. `checkbounds_indices` discards any information about the -array other than its `indices` tuple, and performs a pure indices-vs-indices comparison: this +array other than its `axes` tuple, and performs a pure indices-vs-indices comparison: this allows relatively few compiled methods to serve a huge variety of array types. Indices are specified as tuples, and are usually compared in a 1-1 fashion with individual dimensions handled by calling another important function, `checkindex`: typically, @@ -78,7 +78,7 @@ so `checkindex` checks a single dimension. All of these functions, including th If you have to customize bounds checking for a specific array type, you should specialize `checkbounds(Bool, A, I...)`. However, in most cases you should be able to rely on `checkbounds_indices` as long as you supply -useful `indices` for your array type. +useful `axes` for your array type. If you have novel index types, first consider specializing `checkindex`, which handles a single index for a particular dimension of an array. If you have a custom multidimensional index type diff --git a/src/devdocs/offset-arrays.md b/src/devdocs/offset-arrays.md index b5a1552..97328a6 100644 --- a/src/devdocs/offset-arrays.md +++ b/src/devdocs/offset-arrays.md @@ -17,7 +17,7 @@ the exported interfaces of Julia. As an overview, the steps are: - * replace many uses of `size` with `indices` + * replace many uses of `size` with `axes` * replace `1:length(A)` with `eachindex(A)`, or in some cases `linearindices(A)` * replace `length(A)` with `length(linearindices(A))` * replace explicit allocations like `Array{Int}(size(B))` with `similar(Array{Int}, axes(B))` @@ -52,7 +52,7 @@ To ensure that such errors are caught, in Julia 0.5 both `length` and `size`**sh error when passed an array with non-1 indexing. This is designed to force users of such arrays to check the code, and inspect it for whether it needs to be generalized. -### Using `indices` for bounds checks and loop iteration +### Using `axes` for bounds checks and loop iteration `axes(A)` (reminiscent of `size(A)`) returns a tuple of `AbstractUnitRange` objects, specifying the range of valid indices along each dimension of `A`. When `A` has unconventional indexing, @@ -61,7 +61,7 @@ is `axes(A, d)`. Base implements a custom range type, `OneTo`, where `OneTo(n)` means the same thing as `1:n` but in a form that guarantees (via the type system) that the lower index is 1. For any new [`AbstractArray`](@ref) -type, this is the default returned by `indices`, and it indicates that this array type uses "conventional" +type, this is the default returned by `axes`, and it indicates that this array type uses "conventional" 1-based indexing. Note that if you don't want to be bothered supporting arrays with non-1 indexing, you can add the following line: @@ -83,7 +83,7 @@ For this reason, your best option may be to iterate over the array with `eachind By this definition, 1-dimensional arrays always use Cartesian indexing with the array's native indices. To help enforce this, it's worth noting that the index conversion functions will throw an error if shape indicates a 1-dimensional array with unconventional indexing (i.e., is a `Tuple{UnitRange}` rather than a tuple of `OneTo`). For arrays with conventional indexing, these functions continue to work the same as always. -Using `indices` and `linearindices`, here is one way you could rewrite `mycopy!`: +Using `axes` and `linearindices`, here is one way you could rewrite `mycopy!`: ```julia function mycopy!(dest::AbstractVector, src::AbstractVector) @@ -151,7 +151,7 @@ omit the `@boundscheck` annotation so the check always runs). ### Custom `AbstractUnitRange` types -If you're writing a non-1 indexed array type, you will want to specialize `indices` so it returns +If you're writing a non-1 indexed array type, you will want to specialize `axes` so it returns a `UnitRange`, or (perhaps better) a custom `AbstractUnitRange`. The advantage of a custom type is that it "signals" the allocation type for functions like `similar`. If we're writing an array type for which indexing will start at 0, we likely want to begin by creating a new `AbstractUnitRange`, @@ -166,9 +166,9 @@ create a `ModuleA.ZeroArray`, whereas `ModuleB.ZeroRange` indicates a `ModuleB.Z Note that the Julia package [CustomUnitRanges.jl](https://github.com/JuliaArrays/CustomUnitRanges.jl) can sometimes be used to avoid the need to write your own `ZeroRange` type. -### Specializing `indices` +### Specializing `axes` -Once you have your `AbstractUnitRange` type, then specialize `indices`: +Once you have your `AbstractUnitRange` type, then specialize `axes`: ```julia Base.axes(A::ZeroArray) = map(n->ZeroRange(n), A.size) diff --git a/src/manual/interfaces.md b/src/manual/interfaces.md index 9a6b064..f951e7b 100644 --- a/src/manual/interfaces.md +++ b/src/manual/interfaces.md @@ -399,7 +399,7 @@ julia> mean(A) ``` 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`](@ref) +something other than 1), you should specialize `axes`. 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 man-custom-indices). diff --git a/src/stdlib/FileWatching.md b/src/stdlib/FileWatching.md index 7c42ddc..3944f5d 100644 --- a/src/stdlib/FileWatching.md +++ b/src/stdlib/FileWatching.md @@ -4,4 +4,6 @@ FileWatching.poll_fd FileWatching.poll_file FileWatching.watch_file +FileWatching.watch_folder +FileWatching.unwatch_folder ``` diff --git a/src/stdlib/REPL.md b/src/stdlib/REPL.md index 68b3937..d9080cf 100644 --- a/src/stdlib/REPL.md +++ b/src/stdlib/REPL.md @@ -290,13 +290,13 @@ max(x, y) in Base at operators.jl:215 max(a, b, c, xs...) in Base at operators.jl:281 ``` -Keywords are also displayed in the suggested methods, see second line after `;` where `limit` -and `keep` are keyword arguments: +Keywords are also displayed in the suggested methods after `;`, see below line where `limit` +and `keepempty` are keyword arguments: ```julia-repl julia> split("1 1 1", [TAB] -split(str::AbstractString) in Base at strings/util.jl:302 -split(str::T, splitter; limit, keep) where T<:AbstractString in Base at strings/util.jl:277 +split(str::AbstractString; limit, keepempty) in Base at strings/util.jl:302 +split(str::T, splitter; limit, keepempty) where T<:AbstractString in Base at strings/util.jl:277 ``` The completion of the methods uses type inference and can therefore see if the arguments match diff --git a/src/stdlib/filewatching.md b/src/stdlib/filewatching.md index 7c42ddc..3944f5d 100644 --- a/src/stdlib/filewatching.md +++ b/src/stdlib/filewatching.md @@ -4,4 +4,6 @@ FileWatching.poll_fd FileWatching.poll_file FileWatching.watch_file +FileWatching.watch_folder +FileWatching.unwatch_folder ``` From 9bd6079b44ddbea74eebb24676cb71517722db92 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Tue, 10 Apr 2018 12:24:03 +0900 Subject: [PATCH 017/153] update Julia Commit cfe4f098bc --- codex/NEWS.md | 7 +- codex/base/arrays.md | 2 +- codex/base/c.md | 2 +- codex/devdocs/llvm.md | 17 +- codex/devdocs/ssair.md | 91 +++++++- codex/index.md | 1 + codex/manual/calling-c-and-fortran-code.md | 102 ++++++--- codex/manual/environment-variables.md | 6 - codex/manual/functions.md | 4 +- codex/manual/interfaces.md | 124 +++++++---- codex/manual/strings.md | 52 ++++- codex/stdlib/Logging.md | 246 +++++++++++++++++++++ codex/stdlib/Pkg3.md | 98 ++++---- src/NEWS.md | 6 +- src/base/arrays.md | 2 +- src/base/c.md | 2 +- src/devdocs/llvm.md | 17 +- src/devdocs/ssair.md | 91 +++++++- src/index.md | 1 + src/manual/calling-c-and-fortran-code.md | 102 ++++++--- src/manual/environment-variables.md | 6 - src/manual/functions.md | 4 +- src/manual/interfaces.md | 124 +++++++---- src/manual/strings.md | 52 ++++- src/stdlib/Logging.md | 246 +++++++++++++++++++++ src/stdlib/Pkg3.md | 98 ++++---- tools/check_codex.jl | 4 +- 27 files changed, 1185 insertions(+), 322 deletions(-) create mode 100644 codex/stdlib/Logging.md create mode 100644 src/stdlib/Logging.md diff --git a/codex/NEWS.md b/codex/NEWS.md index 81e4ad2..eedb604 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -634,8 +634,9 @@ Library improvements * `IOBuffer` can take the `sizehint` keyword argument to suggest a capacity of the buffer ([#25944](https://github.com/JuliaLang/julia/issues/25944)). - * `trunc`, `floor`, `ceil`, `round`, and `signif` specify `base` using a - keyword argument. ([#26156](https://github.com/JuliaLang/julia/issues/26156)) + * `trunc`, `floor`, `ceil`, and `round` specify `digits`, `sigdigits` and `base` using + keyword arguments. ([#26156](https://github.com/JuliaLang/julia/issues/26156), [#26670](https://github.com/JuliaLang/julia/issues/26670)) + Compiler/Runtime improvements ----------------------------- @@ -1134,6 +1135,8 @@ Deprecated or removed * `isupper`, `islower`, `ucfirst` and `lcfirst` have been deprecated in favor of `isuppercase`, `islowercase`, `uppercasefirst` and `lowercasefirst`, respectively ([#26442](https://github.com/JuliaLang/julia/issues/26442)). + * `signif` has been deprecated in favor of the `sigdigits` keyword argument to `round`. + Command-line option changes --------------------------- diff --git a/codex/base/arrays.md b/codex/base/arrays.md index 4c011a1..3357292 100644 --- a/codex/base/arrays.md +++ b/codex/base/arrays.md @@ -70,10 +70,10 @@ For specializing broadcast on custom types, see Base.BroadcastStyle Base.broadcast_similar Base.broadcast_indices -Base.Broadcast.Scalar Base.Broadcast.AbstractArrayStyle Base.Broadcast.ArrayStyle Base.Broadcast.DefaultArrayStyle +Base.Broadcast.broadcastable ``` ## Indexing and assignment diff --git a/codex/base/c.md b/codex/base/c.md index 5b46e43..a09b916 100644 --- a/codex/base/c.md +++ b/codex/base/c.md @@ -3,7 +3,7 @@ ```@docs ccall Core.Intrinsics.cglobal -Base.cfunction +Base.@cfunction Base.unsafe_convert Base.cconvert Base.unsafe_load diff --git a/codex/devdocs/llvm.md b/codex/devdocs/llvm.md index b47df84..3c38533 100644 --- a/codex/devdocs/llvm.md +++ b/codex/devdocs/llvm.md @@ -48,17 +48,22 @@ LLVM_VER = 3.5.0 Besides the LLVM release numerals, you can also use `LLVM_VER = svn` to bulid against the latest development version of LLVM. +You can also specify to build a debug version of LLVM, by setting either `LLVM_DEBUG = 1` or +`LLVM_DEBUG = Release` in your `Make.user` file. The former will be a fully unoptimized build +of LLVM and the latter will produce an optimized build of LLVM. Depending on your needs the +latter will suffice and it quite a bit faster. If you use `LLVM_DEBUG = Release` you will also +want to set `LLVM_ASSERTIONS = 1` to enable diagonstics for different passes. Only `LLVM_DEBUG = 1` +implies that option by default. + ## Passing options to LLVM -You can pass options to LLVM using *debug* builds of Julia. To create a debug build, run `make debug`. -The resulting executable is `usr/bin/julia-debug`. You can pass LLVM options to this executable -via the environment variable `JULIA_LLVM_ARGS`. Here are example settings using `bash` syntax: +You can pass options to LLVM via the environment variable `JULIA_LLVM_ARGS`. +Here are example settings using `bash` syntax: * `export JULIA_LLVM_ARGS = -print-after-all` dumps IR after each pass. * `export JULIA_LLVM_ARGS = -debug-only=loop-vectorize` dumps LLVM `DEBUG(...)` diagnostics for - loop vectorizer *if* you built Julia with `LLVM_ASSERTIONS=1`. Otherwise you will get warnings - about "Unknown command line argument". Counter-intuitively, building Julia with `LLVM_DEBUG=1` - is *not* enough to dump `DEBUG` diagnostics from a pass. + loop vectorizer. If you get warnings about "Unknown command line argument", rebuild LLVM with + `LLVM_ASSERTIONS = 1`. ## Debugging LLVM transformations in isolation diff --git a/codex/devdocs/ssair.md b/codex/devdocs/ssair.md index 5ef925e..75231ca 100644 --- a/codex/devdocs/ssair.md +++ b/codex/devdocs/ssair.md @@ -14,8 +14,12 @@ form representation, but the lack of such a representation ultimately proved pro ## New IR nodes -With the new IR representation, the compiler learned to handle two new IR nodes, Phi nodes and Pi -nodes. Phi nodes are part of generic SSA abstraction (see the link above if you're not familar with +With the new IR representation, the compiler learned to handle four new IR nodes, Phi nodes, Pi +nodes as well as PhiC nodes and Upsilon nodes (the latter two are only used for exception handling). + +### Phi nodes and Pi nodes + +Phi nodes are part of generic SSA abstraction (see the link above if you're not familar with the concept). In the Julia IR, these nodes are represented as: ``` struct PhiNode @@ -34,7 +38,7 @@ for the mapping to be incomplete, i.e. for a phi node to have missing incoming e be dynamically guaranteed that the corresponding value will not be used. PiNodes encode statically proven information that may be implicitly assumed in basic blocks dominated by a given -phi node. They are conceptually equivalent to the technique introduced in the paper +pi node. They are conceptually equivalent to the technique introduced in the paper "ABCD: Eliminating Array Bounds Checks on Demand" or the predicate info nodes in LLVM. To see how they work, consider, e.g. @@ -66,6 +70,87 @@ union split representation to a plain unboxed representation). The main usefulne from the fact that path conditions of the values can be accumulated simply by def-use chain walking that is generally done for most optimizations that care about these conditions anyway. +### PhiC nodes and Upsilon nodes + +Exception handling complicates the SSA story moderately, because exception handling +introduces additional control flow edges into the IR across which values must be tracked. +One approach to do so, which is followed by LLVM is to make calls which may throw exceptions +into basic block terminators and add an explicit control flow edge to the catch handler: + +``` +invoke @function_that_may_throw() to label %regular unwind to %catch + +regular: +# Control flow continues here + +catch: +# Exceptions go here +``` + +However, this is problematic in a language like julia where at the start of the optimization +pipeline, we do not now which calls throw. We would have to conservatively assume that every +call (which in julia is every statement) throws. This would have several negative effects. +On the one hand, it would essentially recuce the scope of every basic block to a single call, +defeating the purpose of having operations be performed at the basic block level. On the other +hand, every catch basic block would have `n*m` phi node arguments (`n`, the number of statements +in the critical region, `m` the number of live values through the catch block). To work around +this, we use a combination of `Upsilon` and `PhiC` (the C standing for `catch`, +written `φᶜ` in the IR pretty printer, because +unicode subscript c is not available) nodes. There is several ways to think of these nodes, but +perhaps the easiest is to think of each `PhiC` as a load from a unique store-many, read-once slot, +with `Upsilon` being the corresponding store operation. The `PhiC` has an operand list of all the +upsilon nodes that store to its implicit slot. The `Upsilon` nodes however, do not record which `PhiC` +node they store to. This is done for more natural integration with the rest of the SSA IR. E.g. +if there are no more uses of a `PhiC` node, it is safe to delete is and the same is true of an +`Upsilon` node. In most IR passes, `PhiC` nodes can be treated similar to `Phi` nodes. One can follow +use-def chains through them, and they can be lifted to new `PhiC` nodes and new Upsilon nodes (in the +same places as the original `Upsilon` nodes). The result of this scheme is that the number of +Upsilon nodes (and `PhiC` arguments) is proportional to the number of assigned values to a particular +variable (before SSA conversion), rather than the number of statements in the critical region. + +To see this scheme in action, consider the function + +```julia +function foo() + x = 1 + try + y = 2 + error() + catch + end + (x, y) +end +``` + +The corresponding IR (with irrelevant types stripped) is: + +``` +ir = Code +1 ─ nothing +2 ─ $(Expr(:enter, 5)) +3 ─ %3 = ϒ (#undef) +│ %4 = ϒ (1) +│ %5 = ϒ (2) +│ Main.bar() +│ %7 = ϒ (3) +└── $(Expr(:leave, 1)) +4 ─ goto 6 +5 ─ %10 = φᶜ (%3, %5) +│ %11 = φᶜ (%4, %7) +└── $(Expr(:leave, 1)) +6 ┄ %13 = φ (4 => 2, 5 => %10)::NotInferenceDontLookHere.MaybeUndef(NotInferenceDontLookHere.Const(2, false)) +│ %14 = φ (4 => 3, 5 => %11)::Int64 +│ $(Expr(:undefcheck, :y, Core.SSAValue(13))) +│ %16 = Core.tuple(%14, %13) +└── return %17 +``` + +Note in particular that every value live into the critical region gets +an upsilon node at the top of the critical region. This is because +catch blocks are considered to have an invisible control flow edge +from outside the function. As a result, no SSA value dominates the +catch blocks, and all incoming values have to come through a `φᶜ` node. + # Main SSA data structure The main `SSAIR` data structure is worthy of discussion. It draws inspiration from LLVM and Webkit's B3 IR. diff --git a/codex/index.md b/codex/index.md index 6ebcfec..1eae84b 100644 --- a/codex/index.md +++ b/codex/index.md @@ -90,6 +90,7 @@ Please read the [release notes](NEWS.md) to see what has changed since the last * [Random Numbers](@ref) * [Shared Arrays](@ref) * [Linear Algebra](@ref) + * [Logging](@ref) * [Sparse Arrays](@ref) * [Unicode](@ref) * [Unit Testing](@ref) diff --git a/codex/manual/calling-c-and-fortran-code.md b/codex/manual/calling-c-and-fortran-code.md index 07d7f2f..affc89b 100644 --- a/codex/manual/calling-c-and-fortran-code.md +++ b/codex/manual/calling-c-and-fortran-code.md @@ -155,25 +155,28 @@ It is possible to pass Julia functions to native C functions that accept functio For example, to match C prototypes of the form: ```c -typedef returntype (*functiontype)(argumenttype,...) +typedef returntype (*functiontype)(argumenttype, ...) ``` -The function [`cfunction`](@ref) generates the C-compatible function pointer for a call to a -Julia function. Arguments to [`cfunction`](@ref) are as follows: +The macro [`@cfunction`](@ref) generates the C-compatible function pointer for a call to a +Julia function. Arguments to [`@cfunction`](@ref) are as follows: 1. A Julia Function 2. Return type -3. A tuple type of input types +3. A literal tuple of input types -Only platform-default C calling convention is supported. `cfunction`-generated pointers cannot -be used in calls where WINAPI expects `stdcall` function on 32-bit windows, but can be used on WIN64 -(where `stdcall` is unified with C calling convention). +Like ccall, all of these arguments will be evaluated at compile-time, when the containing method is defined. + +Currently, only the platform-default C calling convention is supported. This means that +`@cfunction`-generated pointers cannot be used in calls where WINAPI expects `stdcall` +function on 32-bit windows, but can be used on WIN64 (where `stdcall` is unified with the +C calling convention). A classic example is the standard C library `qsort` function, declared as: ```c void qsort(void *base, size_t nmemb, size_t size, - int(*compare)(const void *a, const void *b)); + int (*compare)(const void*, const void*)); ``` The `base` argument is a pointer to an array of length `nmemb`, with elements of `size` bytes @@ -182,26 +185,26 @@ an integer less/greater than zero if `a` should appear before/after `b` (or zero is permitted). Now, suppose that we have a 1d array `A` of values in Julia that we want to sort using the `qsort` function (rather than Julia's built-in `sort` function). Before we worry about calling `qsort` and passing arguments, we need to write a comparison function that works for some -arbitrary type T: +arbitrary objects (which define `<`): ```jldoctest mycompare -julia> function mycompare(a::T, b::T) where T - return convert(Cint, a < b ? -1 : a > b ? +1 : 0)::Cint +julia> function mycompare(a, b)::Cint + return (a < b) ? -1 : ((a > b) ? +1 : 0) end mycompare (generic function with 1 method) ``` Notice that we have to be careful about the return type: `qsort` expects a function returning -a C `int`, so we must be sure to return `Cint` via a call to `convert` and a `typeassert`. +a C `int`, so we annotate the return type of the function to be sure it returns a `Cint`. -In order to pass this function to C, we obtain its address using the function `cfunction`: +In order to pass this function to C, we obtain its address using the macro `@cfunction`: ```jldoctest mycompare -julia> const mycompare_c = cfunction(mycompare, Cint, Tuple{Ref{Cdouble}, Ref{Cdouble}}); +julia> mycompare_c = @cfunction(mycompare, Cint, (Ref{Cdouble}, Ref{Cdouble})); ``` -[`cfunction`](@ref) accepts three arguments: the Julia function (`mycompare`), the return type -(`Cint`), and a tuple type of the input argument types, in this case to sort an array of `Cdouble` +[`@cfunction`](@ref) requires three arguments: the Julia function (`mycompare`), the return type +(`Cint`), and a literal tuple of the input argument types, in this case to sort an array of `Cdouble` ([`Float64`](@ref)) elements. The final call to `qsort` looks like this: @@ -227,7 +230,7 @@ julia> A As can be seen, `A` is changed to the sorted array `[-2.7, 1.3, 3.1, 4.4]`. Note that Julia knows how to convert an array into a `Ptr{Cdouble}`, how to compute the size of a type in bytes -(identical to C's `sizeof` operator), and so on. For fun, try inserting a `println("mycompare($a,$b)")` +(identical to C's `sizeof` operator), and so on. For fun, try inserting a `println("mycompare($a, $b)")` line into `mycompare`, which will allow you to see the comparisons that `qsort` is performing (and to verify that it is really calling the Julia function that you passed to it). @@ -518,16 +521,18 @@ unsafe_string(str + Core.sizeof(Cint), len) ### Type Parameters -The type arguments to `ccall` are evaluated statically, when the method containing the `ccall` is defined. -They therefore must take the form of a literal tuple, not a variable, and cannot reference local variables. +The type arguments to `ccall` and `@cfunction` are evaluated statically, +when the method containing the usage is defined. +They therefore must take the form of a literal tuple, not a variable, +and cannot reference local variables. This may sound like a strange restriction, but remember that since C is not a dynamic language like Julia, its functions can only accept argument types with a statically-known, fixed signature. -However, while the type layout must be known statically to compute the `ccall` ABI, +However, while the type layout must be known statically to compute the intended C ABI, the static parameters of the function are considered to be part of this static environment. -The static parameters of the function may be used as type parameters in the `ccall` signature, +The static parameters of the function may be used as type parameters in the call signature, as long as they don't affect the layout of the type. For example, `f(x::T) where {T} = ccall(:valid, Ptr{T}, (Ptr{T},), x)` is valid, since `Ptr` is always a word-size primitive type. @@ -603,7 +608,7 @@ Fortran subroutines, or a `T` for Fortran functions returning the type `T`. ## Mapping C Functions to Julia -### `ccall`/`cfunction` argument translation guide +### `ccall` / `@cfunction` argument translation guide For translating a C argument list to Julia: @@ -626,28 +631,27 @@ For translating a C argument list to Julia: * `Any` * argument value must be a valid Julia object - * currently unsupported by [`cfunction`](@ref) * `jl_value_t**` * `Ref{Any}` * argument value must be a valid Julia object (or `C_NULL`) - * currently unsupported by [`cfunction`](@ref) * `T*` * `Ref{T}`, where `T` is the Julia type corresponding to `T` * argument value will be copied if it is an `isbits` type otherwise, the value must be a valid Julia object - * `(T*)(...)` (e.g. a pointer to a function) + * `T (*)(...)` (e.g. a pointer to a function) - * `Ptr{Cvoid}` (you may need to use [`cfunction`](@ref) explicitly to create this pointer) + * `Ptr{Cvoid}` (you may need to use [`@cfunction`](@ref) explicitly to create this pointer) * `...` (e.g. a vararg) * `T...`, where `T` is the Julia type + * currently unsupported by `@cfunction` * `va_arg` - * not supported + * not supported by `ccall` or `@cfunction` -### `ccall`/`cfunction` return type translation guide +### `ccall` / `@cfunction` return type translation guide For translating a C return type to Julia: @@ -675,7 +679,7 @@ For translating a C return type to Julia: * argument value must be a valid Julia object * `jl_value_t**` - * `Ref{Any}` + * `Ptr{Any}` (`Ref{Any}` is invalid as a return type) * argument value must be a valid Julia object (or `C_NULL`) * `T*` @@ -683,14 +687,14 @@ For translating a C return type to Julia: * `Ref{T}`, where `T` is the Julia type corresponding to `T` * a return type of `Ref{Any}` is invalid, it should either be `Any` (corresponding to `jl_value_t*`) - or `Ptr{Any}` (corresponding to `Ptr{Any}`) + or `Ptr{Any}` (corresponding to `jl_value_t**`) * C **MUST NOT** modify the memory returned via `Ref{T}` if `T` is an `isbits` type * If the memory is owned by C: * `Ptr{T}`, where `T` is the Julia type corresponding to `T` - * `(T*)(...)` (e.g. a pointer to a function) + * `T (*)(...)` (e.g. a pointer to a function) - * `Ptr{Cvoid}` (you may need to use [`cfunction`](@ref) explicitly to create this pointer) + * `Ptr{Cvoid}` (you may need to use [`@cfunction`](@ref) explicitly to create this pointer) ### Passing Pointers for Modifying Inputs @@ -880,8 +884,10 @@ expression, which is then evaluated. Keep in mind that `eval` only operates at t so within this expression local variables will not be available (unless their values are substituted with `$`). For this reason, `eval` is typically only used to form top-level definitions, for example when wrapping libraries that contain many similar functions. +A similar example can be constructed for [`@cfunction`](@ref). -If your usage is more dynamic, use indirect calls as described in the next section. +However, doing this will also be very slow and leak memory, so you should usually avoid this and instead keep reading. +The next section discusses how to use indirect calls to efficiently accomplish a similar effect. ## Indirect Calls @@ -911,6 +917,34 @@ mylibvar = Libdl.dlopen("mylib") ccall(@dlsym("myfunc", mylibvar), Cvoid, ()) ``` +## Closure cfunctions + +The first argument to [`@cfunction`](@ref) can be marked with a `$`, in which case +the return value will instead be a `struct CFunction` which closes over the argument. +You must ensure that this return object is kept alive until all uses of it are done. +The contents and code at the cfunction pointer will be erased via a [`finalizer`](@ref) +when this reference is dropped and atexit. This is not usually needed, since this +functionality is not present in C, but can be useful for dealing with ill-designed APIs +which don't provide a separate closure environment parameter. + +```julia +function qsort(a::Vector{T}, cmp) where T + isbits(T) || throw(ArgumentError("this method can only qsort isbits arrays")) + callback = @cfunction $cmp Cint (Ref{T}, Ref{T}) + # Here, `callback` isa Base.CFunction, which will be converted to Ptr{Cvoid} + # (and protected against finalization) by the ccall + ccall(:qsort, Cvoid, (Ptr{T}, Csize_t, Csize_t, Ptr{Cvoid}), + a, length(A), Base.elsize(A), callback) + # We could instead use: + # GC.@preserve callback begin + # use(Base.unsafe_convert(Ptr{Cvoid}, callback)) + # end + # if we needed to use it outside of a `ccall` + return a +end +``` + + ## Closing a Library It is sometimes useful to close (unload) a library so that it can be reloaded. @@ -922,7 +956,7 @@ and load in the new changes. One can either restart Julia or use the ```julia lib = Libdl.dlopen("./my_lib.so") # Open the library explicitly. sym = Libdl.dlsym(lib, :my_fcn) # Get a symbol for the function to call. -ccall(sym, ...) # Use the symbol instead of the (symbol, library) tuple (remaining arguments are the same). +ccall(sym, ...) # Use the pointer `sym` instead of the (symbol, library) tuple (remaining arguments are the same). Libdl.dlclose(lib) # Close the library explicitly. ``` diff --git a/codex/manual/environment-variables.md b/codex/manual/environment-variables.md index 513b75c..79a16cd 100644 --- a/codex/manual/environment-variables.md +++ b/codex/manual/environment-variables.md @@ -314,12 +314,6 @@ event listener for just-in-time (JIT) profiling. Arguments to be passed to the LLVM backend. -!!! note - - This environment variable has an effect only if Julia was compiled with - `JL_DEBUG_BUILD` set — in particular, the `julia-debug` executable is always - compiled with this build variable. - ### `JULIA_DEBUG_LOADING` If set, then Julia prints detailed information about the cache in the loading diff --git a/codex/manual/functions.md b/codex/manual/functions.md index 5779954..c3adfd3 100644 --- a/codex/manual/functions.md +++ b/codex/manual/functions.md @@ -553,7 +553,9 @@ at runtime. The nature of keyword arguments makes it possible to specify the same argument more than once. For example, in the call `plot(x, y; options..., width=2)` it is possible that the `options` structure also contains a value for `width`. In such a case the rightmost occurrence takes precedence; in -this example, `width` is certain to have the value `2`. +this example, `width` is certain to have the value `2`. However, explicitly specifying the same keyword +argument multiple times, for example `plot(x, y, width=2, width=3)`, is not allowed and results in +a syntax error. ## Evaluation Scope of Default Values diff --git a/codex/manual/interfaces.md b/codex/manual/interfaces.md index f951e7b..d13bd75 100644 --- a/codex/manual/interfaces.md +++ b/codex/manual/interfaces.md @@ -443,7 +443,8 @@ V = view(A, [1,2,4], :) # is not strided, as the spacing between rows is not f | `Base.broadcast_similar(f, ::DestStyle, ::Type{ElType}, inds, As...)` | Allocation of output container | | **Optional methods** | | | | `Base.BroadcastStyle(::Style1, ::Style2) = Style12()` | Precedence rules for mixing styles | -| `Base.broadcast_indices(::StyleA, A)` | Declaration of the indices of `A` for broadcasting purposes (for AbstractArrays, defaults to `axes(A)`) | +| `Base.broadcast_indices(::StyleA, A)` | Declaration of the indices of `A` for broadcasting purposes (defaults to [`axes(A)`](@ref)) | +| `Base.broadcastable(x)` | Convert `x` to an object that has `axes` and supports indexing | | **Bypassing default machinery** | | | `broadcast(f, As...)` | Complete bypass of broadcasting machinery | | `broadcast(f, ::DestStyle, ::Nothing, ::Nothing, As...)` | Bypass after container type is computed | @@ -452,21 +453,43 @@ V = view(A, [1,2,4], :) # is not strided, as the spacing between rows is not f | `broadcast!(f, dest, ::BroadcastStyle, As...)` | Bypass in-place broadcast, specialization on `BroadcastStyle` | [Broadcasting](@ref) is triggered by an explicit call to `broadcast` or `broadcast!`, or implicitly by -"dot" operations like `A .+ b`. Any `AbstractArray` type supports broadcasting, -but the default result (output) type is `Array`. To specialize the result for specific input type(s), -the main task is the allocation of an appropriate result object. -(This is not an issue for `broadcast!`, where -the result object is passed as an argument.) This process is split into two stages: computation -of the behavior and type from the arguments ([`Base.BroadcastStyle`](@ref)), and allocation of the object -given the resulting type with [`Base.broadcast_similar`](@ref). - -`Base.BroadcastStyle` is an abstract type from which all styles are +"dot" operations like `A .+ b` or `f.(x, y)`. Any object that has [`axes`](@ref) and supports +indexing can participate as an argument in broadcasting, and by default the result is stored +in an `Array`. This basic framework is extensible in three major ways: + +* Ensuring that all arguments support broadcast +* Selecting an appropriate output array for the given set of arguments +* Selecting an efficient implementation for the given set of arguments + +Not all types support `axes` and indexing, but many are convenient to allow in broadcast. +The [`Base.broadcastable`](@ref) function is called on each argument to broadcast, allowing +it to return something different that supports `axes` and indexing if it does not. By +default, this is the identity function for all `AbstractArray`s and `Number`s — they already +support `axes` and indexing. For a handful of other types (including but not limited to +types themselves, functions, special singletons like `missing` and `nothing`, and dates), +`Base.broadcastable` returns the argument wrapped in a `Ref` to act as a 0-dimensional +"scalar" for the purposes of broadcasting. Custom types can similarly specialize +`Base.broadcastable` to define their shape, but they should follow the convention that +`collect(Base.broadcastable(x)) == collect(x)`. A notable exception are `AbstractString`s; +they are special-cased to behave as scalars for the purposes of broadcast even though they +are iterable collections of their characters. + +The next two steps (selecting the output array and implementation) are dependent upon +determining a single answer for a given set of arguments. Broadcast must take all the varied +types of its arguments and collapse them down to just one output array and one +implementation. Broadcast calls this single answer a "style." Every broadcastable object +each has its own preferred style, and a promotion-like system is used to combine these +styles into a single answer — the "destination style". + +### Broadcast Styles + +`Base.BroadcastStyle` is the abstract type from which all styles are derived. When used as a function it has two possible forms, unary (single-argument) and binary. The unary variant states that you intend to implement specific broadcasting behavior and/or output type, -and do not wish to rely on the default fallback ([`Broadcast.Scalar`](@ref) or [`Broadcast.DefaultArrayStyle`](@ref)). -To achieve this, you can define a custom `BroadcastStyle` for your object: +and do not wish to rely on the default fallback ([`Broadcast.DefaultArrayStyle`](@ref)). +To override these defaults, you can define a custom `BroadcastStyle` for your object: ```julia struct MyStyle <: Broadcast.BroadcastStyle end @@ -486,6 +509,8 @@ When your broadcast operation involves several arguments, individual argument st combined to determine a single `DestStyle` that controls the type of the output container. For more detail, see [below](@ref writing-binary-broadcasting-rules). +### Selecting an appropriate output array + The actual allocation of the result array is handled by `Base.broadcast_similar`: ```julia @@ -562,6 +587,8 @@ julia> a .+ [5,10] 13 14 ``` +### [Extending broadcast with custom implementations](@id extending-in-place-broadcast) + Finally, it's worth noting that sometimes it's easier simply to bypass the machinery for computing result types and container sizes, and just do everything manually. For example, you can convert a `UnitRange{Int}` `r` to a `UnitRange{BigInt}` with `big.(r)`; the definition @@ -580,7 +607,40 @@ the internal machinery to compute the container type, element type, and indices Broadcast.broadcast(::typeof(somefunction), ::MyStyle, ::Type{ElType}, inds, As...) ``` -### [Writing binary broadcasting rules](@id writing-binary-broadcasting-rules) +Extending `broadcast!` (in-place broadcast) should be done with care, as it is easy to introduce +ambiguities between packages. To avoid these ambiguities, we adhere to the following conventions. + +First, if you want to specialize on the destination type, say `DestType`, then you should +define a method with the following signature: + +```julia +broadcast!(f, dest::DestType, ::Nothing, As...) +``` + +Note that no bounds should be placed on the types of `f` and `As...`. + +Second, if specialized `broadcast!` behavior is desired depending on the input types, +you should write [binary broadcasting rules](@ref writing-binary-broadcasting-rules) to +determine a custom `BroadcastStyle` given the input types, say `MyBroadcastStyle`, and you should define a method with the following +signature: + +```julia +broadcast!(f, dest, ::MyBroadcastStyle, As...) +``` + +Note the lack of bounds on `f`, `dest`, and `As...`. + +Third, simultaneously specializing on both the type of `dest` and the `BroadcastStyle` is fine. In this case, +it is also allowed to specialize on the types of the source arguments (`As...`). For example, these method signatures are OK: + +```julia +broadcast!(f, dest::DestType, ::MyBroadcastStyle, As...) +broadcast!(f, dest::DestType, ::MyBroadcastStyle, As::AbstractArray...) +broadcast!(f, dest::DestType, ::Broadcast.DefaultArrayStyle{0}, As::Number...) +``` + + +#### [Writing binary broadcasting rules](@id writing-binary-broadcasting-rules) The precedence rules are defined by binary `BroadcastStyle` calls: @@ -592,10 +652,10 @@ where `Style12` is the `BroadcastStyle` you want to choose for outputs involving arguments of `Style1` and `Style2`. For example, ```julia -Base.BroadcastStyle(::Broadcast.Style{Tuple}, ::Broadcast.Scalar) = Broadcast.Style{Tuple}() +Base.BroadcastStyle(::Broadcast.Style{Tuple}, ::Broadcast.AbstractArrayStyle{0}) = Broadcast.Style{Tuple}() ``` -indicates that `Tuple` "wins" over scalars (the output container will be a tuple). +indicates that `Tuple` "wins" over zero-dimensional arrays (the output container will be a tuple). It is worth noting that you do not need to (and should not) define both argument orders of this call; defining one is sufficient no matter what order the user supplies the arguments in. @@ -643,37 +703,3 @@ yields another `SparseVecStyle`, that its combination with a 2-dimensional array yields a `SparseMatStyle`, and anything of higher dimensionality falls back to the dense arbitrary-dimensional framework. These rules allow broadcasting to keep the sparse representation for operations that result in one or two dimensional outputs, but produce an `Array` for any other dimensionality. - -### [Extending `broadcast!`](@id extending-in-place-broadcast) - -Extending `broadcast!` (in-place broadcast) should be done with care, as it is easy to introduce -ambiguities between packages. To avoid these ambiguities, we adhere to the following conventions. - -First, if you want to specialize on the destination type, say `DestType`, then you should -define a method with the following signature: - -```julia -broadcast!(f, dest::DestType, ::Nothing, As...) -``` - -Note that no bounds should be placed on the types of `f` and `As...`. - -Second, if specialized `broadcast!` behavior is desired depending on the input types, -you should write [binary broadcasting rules](@ref writing-binary-broadcasting-rules) to -determine a custom `BroadcastStyle` given the input types, say `MyBroadcastStyle`, and you should define a method with the following -signature: - -```julia -broadcast!(f, dest, ::MyBroadcastStyle, As...) -``` - -Note the lack of bounds on `f`, `dest`, and `As...`. - -Third, simultaneously specializing on both the type of `dest` and the `BroadcastStyle` is fine. In this case, -it is also allowed to specialize on the types of the source arguments (`As...`). For example, these method signatures are OK: - -```julia -broadcast!(f, dest::DestType, ::MyBroadcastStyle, As...) -broadcast!(f, dest::DestType, ::MyBroadcastStyle, As::AbstractArray...) -broadcast!(f, dest::DestType, ::Broadcast.Scalar, As::Number...) -``` diff --git a/codex/manual/strings.md b/codex/manual/strings.md index e03c6a9..9d49b95 100644 --- a/codex/manual/strings.md +++ b/codex/manual/strings.md @@ -452,8 +452,36 @@ I have $100 in my account. ## Triple-Quoted String Literals When strings are created using triple-quotes (`"""..."""`) they have some special behavior that -can be useful for creating longer blocks of text. First, if the opening `"""` is followed by a -newline, the newline is stripped from the resulting string. +can be useful for creating longer blocks of text. + +First, triple-quoted strings are also dedented to the level of the least-indented line. +This is useful for defining strings within code that is indented. For example: + +```jldoctest +julia> str = """ + Hello, + world. + """ +" Hello,\n world.\n" +``` + +In this case the final (empty) line before the closing `"""` sets the indentation level. + +The dedentation level is determined as the longest common starting sequence of spaces or +tabs in all lines, excluding the line following the opening `"""` and lines containing +only spaces or tabs (the line containing the closing `"""` is always included). +Then for all lines, excluding the text following the opening `"""`, the common starting +sequence is removed (including lines containing only spaces and tabs if they start with +this sequence), e.g.: +```jldoctest +julia> """ This + is + a test""" +" This\nis\n a test" +``` + +Next, if the opening `"""` is followed by a newline, +the newline is stripped from the resulting string. ```julia """hello""" @@ -474,20 +502,20 @@ but hello""" ``` -will contain a literal newline at the beginning. Trailing whitespace is left unaltered. They can -contain `"` symbols without escaping. Triple-quoted strings are also dedented to the level of -the least-indented line. This is useful for defining strings within code that is indented. For -example: +will contain a literal newline at the beginning. + +Stripping of the newline is performed after the dedentation for example: ```jldoctest -julia> str = """ - Hello, - world. - """ -" Hello,\n world.\n" +julia> """ + Hello, + world.""" +"Hello,\nworld." ``` -In this case the final (empty) line before the closing `"""` sets the indentation level. +Trailing whitespace is left unaltered. + +Triple-quoted string literals can contain `"` symbols without escaping. Note that line breaks in literal strings, whether single- or triple-quoted, result in a newline (LF) character `\n` in the string, even if your editor uses a carriage return `\r` (CR) or CRLF diff --git a/codex/stdlib/Logging.md b/codex/stdlib/Logging.md new file mode 100644 index 0000000..6c170f5 --- /dev/null +++ b/codex/stdlib/Logging.md @@ -0,0 +1,246 @@ +# Logging + +The `Logging` module provides a way to record the history and progress of a +computation as a log of events. Events are created by inserting a logging +statement into the source code, for example: + +```julia +@warn "Abandon printf debugging, all ye who enter here!" +┌ Warning: Abandon printf debugging, all ye who enter here! +└ @ Main REPL[1]:1 +``` + +The system provides several advantages over peppering your source code with +calls to `println()`. First, it allows you to control the visibility and +presentation of messages without editing the source code. For example, in +contrast to the `@warn` above + +```julia +@debug "The sum of some values $(sum(rand(100)))" +``` + +will produce no output by default. Furthermore, it's very cheap to leave debug +statements like this in the source code because the system avoids evaluating +the message if it would later be ignored. In this case `sum(rand(100))` and +the associated string processing will never be executed unless debug logging is +enabled. + +Second, the logging tools allow you to attach arbitrary data to each event as a +set of key--value pairs. This allows you to capture local variables and other +program state for later analysis. For example, to attach the local array +variable `A` and the sum of a vector `v` as the key `s` you can use + +```jldoctest +A = ones(Int, 4, 4) +v = ones(100) +@info "Some variables" A s=sum(v) + +# Output +┌ Info: Some variables +│ A = +│ 4×4 Array{Int64,2}: +│ 1 1 1 1 +│ 1 1 1 1 +│ 1 1 1 1 +│ 1 1 1 1 +└ s = 100.0 +``` + +All of the logging macros `@debug`, `@info`, `@warn` and `@error` share common +features that are described in detail in the documentation for the more +general macro [`@logmsg`](@ref). + +## Log event structure + +Each event generates several pieces of data, some provided by the user and some +automatically extracted. Let's examine the user-defined data first: + +* The *log level* is a broad category for the message that is used for early + filtering. There are several standard levels of type [`LogLevel`](@ref); + user-defined levels are also possible. + - Use `Debug` for verbose information that could be useful when debugging an + application or module. These events are disabled by default. + - Use `Info` to inform the user about the normal operation of the program. + - Use `Warn` when a potential problem is detected. + - Use `Error` to report errors where the code has enough context to recover + and continue. (When the code doesn't have enough context, an exception or + early return is more appropriate.) +* The *message* is an object describing the event. By convention + `AbstractString`s passed as messages are assumed to be in markdown format. + Other types will be displayed using `show(io,mime,obj)` according to the + display capabilities of the installed logger. +* Optional *key--value pairs* allow arbitrary data to be attached to each event. + Some keys have conventional meaning that can affect the way an event is + interpreted (see [`@logmsg`](@ref)). + +The system also generates some standard information for each event: + +* The `module` in which the logging macro was expanded. +* The `file` and `line` where the logging macro occurs in the source code. +* A message `id` that is unique for each logging macro invocation. This is + very useful as a key for caching information or actions associated with an + event. For instance, it can be used to limit the number of times a message + is presented to the user. +* A `group` for the event, which is set to the base name of the file by default, + without extension. This can be used to group messages into categories more + finely than the log level (for example, all deprecation warnings have group + `:depwarn`), or into logical groupings across or within modules. + +Notice that some useful information such as the event time is not included by +default. This is because such information can be expensive to extract and is +also *dynamically* available to the current logger. It's simple to define a +[custom logger](@ref AbstractLogger-interface) to augment event data with the +time, backtrace, values of global variables and other useful information as +required. + + +## Processing log events + +As you can see in the examples, logging statements make no mention of +where log events go or how they are processed. This is a key design feature +that makes the system composable and natural for concurrent use. It does this +by separating two different concerns: + +* *Creating* log events is the concern of the module author who needs to + decide where events are triggered and which information to include. +* *Processing* of log events — that is, display, filtering, aggregation and + recording — is the concern of the application author who needs to bring + multiple modules together into a cooperating application. + +### Loggers + +Processing of events is performed by a *logger*, which is the first piece of +user configurable code to see the event. All loggers must be subtypes of +[`AbstractLogger`](@ref). + +When an event is triggered, the appropriate logger is found by looking for a +task-local logger with the global logger as fallback. The idea here is that +the application code knows how log events should be processed and exists +somewhere at the top of the call stack. So we should look up through the call +stack to discover the logger — that is, the logger should be *dynamically +scoped*. (This is a point of contrast with logging frameworks where the +logger is *lexically scoped*; provided explicitly by the module author or as a +simple global variable. In such a system it's awkward to control logging while +composing functionality from multiple modules.) + +The global logger may be set with [`global_logger`](@ref), and task-local +loggers controlled using [`with_logger`](@ref). Newly spawned tasks inherit +the logger of the parent task. + +There are three logger types provided by the library. [`ConsoleLogger`](@ref) +is the default logger you see when starting the REPL. It displays events in a +readable text format and tries to give simple but user friendly control over +formatting and filtering. [`NullLogger`](@ref) is a convenient way to drop all +messages where necessary; it is the logging equivalent of the [`DevNull`](@ref) +stream. [`SimpleLogger`](@ref) is a very simplistic text formatting logger, +mainly useful for debugging the logging system itself. + +Custom loggers should come with overloads for the functions described in the +[reference section](@ref AbstractLogger-interface). + +### Early filtering and message handling + +When an event occurs, a few steps of early filtering occur to avoid generating +messages that will be discarded: + +1. The message log level is checked against a global minimum level (set via + [`disable_logging`](@ref)). This is a crude but extremely cheap global + setting. +2. The current logger state is looked up and the message level checked against the + logger's cached minimum level, as found by calling [`min_enabled_level`](@ref). + This behavior can be overridden via environment variables (more on this later). +3. The [`shouldlog`](@ref) function is called with the current logger, taking + some minimal information (level, module, group, id) which can be computed + statically. Most usefully, `shouldlog` is passed an event `id` which can be + used to discard events early based on a cached predicate. + +If all these checks pass, the message and key--value pairs are evaluated in full +and passed to the current logger via the [`handle_message`](@ref) function. +`handle_message()` may perform additional filtering as required and display the +event to the screen, save it to a file, etc. + +Exceptions that occur while generating the log event are captured and logged +by default. This prevents individual broken events from crashing the +application, which is helpful when enabling little-used debug events in a +production system. This behavior can be customized per logger type by +extending [`catch_exceptions`](@ref). + +## Testing log events + +Log events are a side effect of running normal code, but you might find +yourself wanting to test particular informational messages and warnings. The +`Test` module provides a [`@test_logs`](@ref) macro that can be used to +pattern match against the log event stream. + +## Environment variables + +Message filtering can be influenced through the `JULIA_DEBUG` environment +variable, and serves as an easy way to enable debug logging for a file or +module. For example, loading julia with `JULIA_DEBUG=loading` will activate +`@debug` log messages in `loading.jl`: + +``` +$ JULIA_DEBUG=loading julia -e 'using OhMyREPL' +┌ Debug: Rejecting cache file /home/user/.julia/compiled/v0.7/OhMyREPL.ji due to it containing an invalid cache header +└ @ Base loading.jl:1328 +[ Info: Recompiling stale cache file /home/user/.julia/compiled/v0.7/OhMyREPL.ji for module OhMyREPL +┌ Debug: Rejecting cache file /home/user/.julia/compiled/v0.7/Tokenize.ji due to it containing an invalid cache header +└ @ Base loading.jl:1328 +... +``` + +Similarly, the environment variable can be used to enable debug logging of +modules, such as `Pkg`, or module roots (see [`Base.moduleroot`](@ref)). To +enable all debug logging, use the special value `all`. + + +## Reference + +### Creating events + +```@docs +Logging.@logmsg +Logging.LogLevel +``` + +### [Processing events with AbstractLogger](@id AbstractLogger-interface) + +Event processing is controlled by overriding functions associated with +`AbstractLogger`: + +| Methods to implement |   | Brief description | +|:----------------------------- |:---------------------- |:---------------------------------------- | +| [`handle_message`](@ref) | | Handle a log event | +| [`shouldlog`](@ref) | | Early filtering of events | +| [`min_enabled_level`](@ref) | | Lower bound for log level of accepted events | +| **Optional methods** | **Default definition** | **Brief description** | +| [`catch_exceptions`](@ref) | `true` | Catch exceptions during event evaluation | + + +```@docs +Logging.AbstractLogger +Logging.handle_message +Logging.shouldlog +Logging.min_enabled_level +Logging.catch_exceptions +Logging.disable_logging +``` + +### Using Loggers + +Logger installation and inspection: + +```@docs +Logging.global_logger +Logging.with_logger +Logging.current_logger +``` + +Loggers that are supplied with the system: + +```@docs +Logging.NullLogger +Logging.ConsoleLogger +Logging.SimpleLogger +``` + diff --git a/codex/stdlib/Pkg3.md b/codex/stdlib/Pkg3.md index 13307ef..289511f 100644 --- a/codex/stdlib/Pkg3.md +++ b/codex/stdlib/Pkg3.md @@ -86,7 +86,7 @@ identify the package in projects that depend on it. !!! note For legacy reasons it is possible to load a package without a project file or UUID from the REPL or the top-level of a script. It is not possible, however, - to load a package with a project file or UUID from a project with them. Once + to load a package without a project file or UUID from a project with them. Once you've loaded from a project file, everything needs a project file and UUID. **Application:** a project which provides standalone functionality not intended @@ -133,36 +133,36 @@ which versions of packages are compatible or incompatible with each other. A registry is indexed by package name and UUID, and has a directory for each registered package providing the following metadata about it: - - name – e.g. `DataFrames` - - UUID – e.g. `a93c6f00-e57d-5684-b7b6-d8193f3e46c0` - - authors – e.g. `Jane Q. Developer ` - - license – e.g. MIT, BSD3, or GPLv2 - - repository – e.g. `https://github.com/JuliaData/DataFrames.jl.git` - - description – a block of text summarizing the functionality of a package - - keywords – e.g. `data`, `tabular`, `analysis`, `statistics` - - versions – a list of all registered version tags +- name – e.g. `DataFrames` +- UUID – e.g. `a93c6f00-e57d-5684-b7b6-d8193f3e46c0` +- authors – e.g. `Jane Q. Developer ` +- license – e.g. MIT, BSD3, or GPLv2 +- repository – e.g. `https://github.com/JuliaData/DataFrames.jl.git` +- description – a block of text summarizing the functionality of a package +- keywords – e.g. `data`, `tabular`, `analysis`, `statistics` +- versions – a list of all registered version tags For each registered version of a package, the following information is provided: - - its semantic version number – e.g. `v1.2.3` - - its git tree SHA-1 hash – e.g. `7ffb18ea3245ef98e368b02b81e8a86543a11103` - - a map from names to UUIDs of dependencies - - which versions of other packages it is compatible/incompatible with +- its semantic version number – e.g. `v1.2.3` +- its git tree SHA-1 hash – e.g. `7ffb18ea3245ef98e368b02b81e8a86543a11103` +- a map from names to UUIDs of dependencies +- which versions of other packages it is compatible/incompatible with -Dependencies and compatiblity are stored in a compressed but human-readable -format using ranges of package verions. +Dependencies and compatibility are stored in a compressed but human-readable +format using ranges of package versions. **Depot:** a directory on a system where various package-related resources live, including: - - `environments`: shared named environments (e.g. `v0.7`, `devtools`) - - `clones`: bare clones of package repositories - - `compiled`: cached compiled package images (`.ji` files) - - `config`: global configuration files (e.g. `startup.jl`) - - `dev`: default directory for package development - - `logs`: log files (e.g. `manifest_usage.toml`, `repl_history.jl`) - - `packages`: installed package versions - - `registries`: clones of registries (e.g. `Uncurated`) +- `environments`: shared named environments (e.g. `v0.7`, `devtools`) +- `clones`: bare clones of package repositories +- `compiled`: cached compiled package images (`.ji` files) +- `config`: global configuration files (e.g. `startup.jl`) +- `dev`: default directory for package development +- `logs`: log files (e.g. `manifest_usage.toml`, `repl_history.jl`) +- `packages`: installed package versions +- `registries`: clones of registries (e.g. `Uncurated`) **Load path:** a stack of environments where package identities, their dependencies, and entry-points are searched for. The load path is controlled in @@ -185,17 +185,25 @@ global configuration data is saved. Later entries in the depot path are treated as read-only and are appropriate for registries, packages, etc. installed and managed by system administrators. - ## Getting Started -The Pkg REPL-mode is entered using from the Julia REPL using the key `]`. +The Pkg REPL-mode is entered from the Julia REPL using the key `]`. + +``` +(v0.7) pkg> +``` + +The part inside the parenthesis of the prompt shows the name of the current project. +Since we haven't created our own project yet, we are in the default project, located at `~/.julia/environments/v0.7` +(or whatever version of Julia you happen to run). + To return to the `julia>` prompt, either press backspace when the input line is empty or press Ctrl+C. Help is available by calling `pkg> help`. To generate files for a new project, use `pkg> generate`. ``` -pkg> generate HelloWorld +(v0.7) pkg> generate HelloWorld ``` This creates a new project `HelloWorld` with the following files (visualized with the external [`tree` command](https://linux.die.net/man/1/tree)): @@ -244,10 +252,11 @@ Hello World! ### Adding packages to the project Let’s say we want to use the standard library package `Random` and the registered package `JSON` in our project. -We simply `add` these packages: +We simply `add` these packages (note how the prompt now shows the name of the newly generated project, +since we are inside the `HelloWorld` project directory): ``` -pkg> add Random JSON +(HelloWorld) pkg> add Random JSON Resolving package versions... Updating "~/Documents/HelloWorld/Project.toml" [682c06a0] + JSON v0.17.1 @@ -287,7 +296,7 @@ Sometimes we might want to use the very latest, unreleased version of a package, git repository. We can use e.g. the `master` branch of `JSON` by specifying the branch after a `#` when adding the package: ``` -pkg> add JSON#master +(HelloWorld) pkg> add JSON#master Cloning package from https://github.com/JuliaIO/JSON.jl.git Resolving package versions... Updating "~/Documents/HelloWorld/Project.toml" @@ -299,7 +308,7 @@ pkg> add JSON#master If we want to use a package that has not been registered in a registry, we can `add` its git repository url: ``` -pkg> add https://github.com/fredrikekre/ImportMacros.jl +(HelloWorld) pkg> add https://github.com/fredrikekre/ImportMacros.jl Cloning package from https://github.com/fredrikekre/ImportMacros.jl Resolving package versions... Downloaded MacroTools ─ v0.4.0 @@ -315,10 +324,10 @@ For unregistered packages we could have given a branch (or commit SHA) to track ## Developing packages -Let’s say we found a bug in `JSON` that we want to fix. We can get the full git-repo using the `develop` command +Let’s say we found a bug in one of our dependencies, e.g. `JSON` that we want to fix. We can get the full git-repo using the `develop` command ``` -pkg> develop JSON +(HelloWorld) pkg> develop JSON Cloning package from https://github.com/JuliaIO/JSON.jl.git Resolving package versions... Updating "~/Documents/HelloWorld/Project.toml" @@ -327,11 +336,11 @@ pkg> develop JSON ``` By default, the package get cloned to the `~/.julia/dev` folder but can also be set by the `JULIA_PKG_DEVDIR` environment variable. -When we have fixed the bug and checked that `JSON` now works correctly with out project, we can make a PR to the `JSON` repository. -When a new release of `JSON` is made, we can go back to using the versioned `JSON` using the command `free` and `update` (see next section): +When we have fixed the bug and checked that `JSON` now works correctly with our project, we can make a PR to the `JSON` repository. +When the PR has been merged we can go over to track the master branch and finally, when a new release of `JSON` is made, we can go back to using the versioned `JSON` using the command `free` and `update` (see next section): ``` -pkg> free JSON +(HelloWorld) pkg> free JSON Resolving package versions... Updating "~/Documents/HelloWorld/Project.toml" [682c06a0] ~ JSON v0.17.1+ #master ⇒ v0.17.1 @@ -341,20 +350,20 @@ pkg> free JSON It is also possible to give a local path as the argument to `develop` which will not clone anything but simply use that directory for the package. -Developing a non registered package is done by giving the git-repo url as an argument to `develop`. +Overriding the dependency path for a non registered package is done by giving the git-repo url as an argument to `develop`. ### Updating dependencies When new versions of packages the project is using are released, it is a good idea to update. Simply calling `up` will try to update *all* the dependencies of the project. Sometimes this is not what you want. You can specify a subset of the dependencies to upgrade by giving them as arguments to `up`, e.g: ``` -pkg> up JSON +(HelloWorld) pkg> up JSON ``` -The version of all other dependencies will stay the same. If you only want to update the minor version of packages, to reduce the risk that your project breaks, you can give the `--minor` flag, e.g: +The version of all other direct dependencies will stay the same. If you only want to update the minor version of packages, to reduce the risk that your project breaks, you can give the `--minor` flag, e.g: ``` -pkg> up --minor JSON +(HelloWorld) pkg> up --minor JSON ``` Packages that track a branch are not updated when a minor upgrade is done. @@ -363,7 +372,7 @@ Developed packages are never touched by the package manager. If you just want install the packages that are given by the current `Manifest.toml` use ``` -pkg> up --manifest --fixed +(HelloWorld) pkg> up --manifest --fixed ``` ### Preview mode @@ -372,25 +381,24 @@ If you just want to see the effects of running a command, but not change your st For example: ``` -pkg> preview add Plot +(HelloWorld) pkg> preview add Plots ``` or ``` -pkg> preview up +(HelloWorld) pkg> preview up ``` will show you the effects adding `Plots`, or doing a full upgrade, respectively, would have on your project. However, nothing would be installed and your `Project.toml` and `Manfiest.toml` are untouched. - -### Using someone elses project. +### Using someone elses project Simple clone their project using e.g. `git clone`, `cd` to the project directory and call ``` -pkg> up --manifest --fixed +(SomeProject) pkg> up --manifest --fixed ``` This will install the packages at the same state that the project you cloned was using. diff --git a/src/NEWS.md b/src/NEWS.md index 9eba429..784e1ee 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -622,8 +622,8 @@ Library improvements * `IOBuffer` can take the `sizehint` keyword argument to suggest a capacity of the buffer ([#25944](https://github.com/JuliaLang/julia/issues/25944)). - * `trunc`, `floor`, `ceil`, `round`, and `signif` specify `base` using a - keyword argument. ([#26156](https://github.com/JuliaLang/julia/issues/26156)) + * `trunc`, `floor`, `ceil`, and `round` specify `digits`, `sigdigits` and `base` using + keyword arguments. ([#26156](https://github.com/JuliaLang/julia/issues/26156), [#26670](https://github.com/JuliaLang/julia/issues/26670)) Compiler/Runtime improvements ----------------------------- @@ -1122,6 +1122,8 @@ Deprecated or removed * `isupper`, `islower`, `ucfirst` and `lcfirst` have been deprecated in favor of `isuppercase`, `islowercase`, `uppercasefirst` and `lowercasefirst`, respectively ([#26442](https://github.com/JuliaLang/julia/issues/26442)). + * `signif` has been deprecated in favor of the `sigdigits` keyword argument to `round`. + Command-line option changes --------------------------- diff --git a/src/base/arrays.md b/src/base/arrays.md index 4c011a1..3357292 100644 --- a/src/base/arrays.md +++ b/src/base/arrays.md @@ -70,10 +70,10 @@ For specializing broadcast on custom types, see Base.BroadcastStyle Base.broadcast_similar Base.broadcast_indices -Base.Broadcast.Scalar Base.Broadcast.AbstractArrayStyle Base.Broadcast.ArrayStyle Base.Broadcast.DefaultArrayStyle +Base.Broadcast.broadcastable ``` ## Indexing and assignment diff --git a/src/base/c.md b/src/base/c.md index 5b46e43..a09b916 100644 --- a/src/base/c.md +++ b/src/base/c.md @@ -3,7 +3,7 @@ ```@docs ccall Core.Intrinsics.cglobal -Base.cfunction +Base.@cfunction Base.unsafe_convert Base.cconvert Base.unsafe_load diff --git a/src/devdocs/llvm.md b/src/devdocs/llvm.md index b47df84..3c38533 100644 --- a/src/devdocs/llvm.md +++ b/src/devdocs/llvm.md @@ -48,17 +48,22 @@ LLVM_VER = 3.5.0 Besides the LLVM release numerals, you can also use `LLVM_VER = svn` to bulid against the latest development version of LLVM. +You can also specify to build a debug version of LLVM, by setting either `LLVM_DEBUG = 1` or +`LLVM_DEBUG = Release` in your `Make.user` file. The former will be a fully unoptimized build +of LLVM and the latter will produce an optimized build of LLVM. Depending on your needs the +latter will suffice and it quite a bit faster. If you use `LLVM_DEBUG = Release` you will also +want to set `LLVM_ASSERTIONS = 1` to enable diagonstics for different passes. Only `LLVM_DEBUG = 1` +implies that option by default. + ## Passing options to LLVM -You can pass options to LLVM using *debug* builds of Julia. To create a debug build, run `make debug`. -The resulting executable is `usr/bin/julia-debug`. You can pass LLVM options to this executable -via the environment variable `JULIA_LLVM_ARGS`. Here are example settings using `bash` syntax: +You can pass options to LLVM via the environment variable `JULIA_LLVM_ARGS`. +Here are example settings using `bash` syntax: * `export JULIA_LLVM_ARGS = -print-after-all` dumps IR after each pass. * `export JULIA_LLVM_ARGS = -debug-only=loop-vectorize` dumps LLVM `DEBUG(...)` diagnostics for - loop vectorizer *if* you built Julia with `LLVM_ASSERTIONS=1`. Otherwise you will get warnings - about "Unknown command line argument". Counter-intuitively, building Julia with `LLVM_DEBUG=1` - is *not* enough to dump `DEBUG` diagnostics from a pass. + loop vectorizer. If you get warnings about "Unknown command line argument", rebuild LLVM with + `LLVM_ASSERTIONS = 1`. ## Debugging LLVM transformations in isolation diff --git a/src/devdocs/ssair.md b/src/devdocs/ssair.md index 5ef925e..75231ca 100644 --- a/src/devdocs/ssair.md +++ b/src/devdocs/ssair.md @@ -14,8 +14,12 @@ form representation, but the lack of such a representation ultimately proved pro ## New IR nodes -With the new IR representation, the compiler learned to handle two new IR nodes, Phi nodes and Pi -nodes. Phi nodes are part of generic SSA abstraction (see the link above if you're not familar with +With the new IR representation, the compiler learned to handle four new IR nodes, Phi nodes, Pi +nodes as well as PhiC nodes and Upsilon nodes (the latter two are only used for exception handling). + +### Phi nodes and Pi nodes + +Phi nodes are part of generic SSA abstraction (see the link above if you're not familar with the concept). In the Julia IR, these nodes are represented as: ``` struct PhiNode @@ -34,7 +38,7 @@ for the mapping to be incomplete, i.e. for a phi node to have missing incoming e be dynamically guaranteed that the corresponding value will not be used. PiNodes encode statically proven information that may be implicitly assumed in basic blocks dominated by a given -phi node. They are conceptually equivalent to the technique introduced in the paper +pi node. They are conceptually equivalent to the technique introduced in the paper "ABCD: Eliminating Array Bounds Checks on Demand" or the predicate info nodes in LLVM. To see how they work, consider, e.g. @@ -66,6 +70,87 @@ union split representation to a plain unboxed representation). The main usefulne from the fact that path conditions of the values can be accumulated simply by def-use chain walking that is generally done for most optimizations that care about these conditions anyway. +### PhiC nodes and Upsilon nodes + +Exception handling complicates the SSA story moderately, because exception handling +introduces additional control flow edges into the IR across which values must be tracked. +One approach to do so, which is followed by LLVM is to make calls which may throw exceptions +into basic block terminators and add an explicit control flow edge to the catch handler: + +``` +invoke @function_that_may_throw() to label %regular unwind to %catch + +regular: +# Control flow continues here + +catch: +# Exceptions go here +``` + +However, this is problematic in a language like julia where at the start of the optimization +pipeline, we do not now which calls throw. We would have to conservatively assume that every +call (which in julia is every statement) throws. This would have several negative effects. +On the one hand, it would essentially recuce the scope of every basic block to a single call, +defeating the purpose of having operations be performed at the basic block level. On the other +hand, every catch basic block would have `n*m` phi node arguments (`n`, the number of statements +in the critical region, `m` the number of live values through the catch block). To work around +this, we use a combination of `Upsilon` and `PhiC` (the C standing for `catch`, +written `φᶜ` in the IR pretty printer, because +unicode subscript c is not available) nodes. There is several ways to think of these nodes, but +perhaps the easiest is to think of each `PhiC` as a load from a unique store-many, read-once slot, +with `Upsilon` being the corresponding store operation. The `PhiC` has an operand list of all the +upsilon nodes that store to its implicit slot. The `Upsilon` nodes however, do not record which `PhiC` +node they store to. This is done for more natural integration with the rest of the SSA IR. E.g. +if there are no more uses of a `PhiC` node, it is safe to delete is and the same is true of an +`Upsilon` node. In most IR passes, `PhiC` nodes can be treated similar to `Phi` nodes. One can follow +use-def chains through them, and they can be lifted to new `PhiC` nodes and new Upsilon nodes (in the +same places as the original `Upsilon` nodes). The result of this scheme is that the number of +Upsilon nodes (and `PhiC` arguments) is proportional to the number of assigned values to a particular +variable (before SSA conversion), rather than the number of statements in the critical region. + +To see this scheme in action, consider the function + +```julia +function foo() + x = 1 + try + y = 2 + error() + catch + end + (x, y) +end +``` + +The corresponding IR (with irrelevant types stripped) is: + +``` +ir = Code +1 ─ nothing +2 ─ $(Expr(:enter, 5)) +3 ─ %3 = ϒ (#undef) +│ %4 = ϒ (1) +│ %5 = ϒ (2) +│ Main.bar() +│ %7 = ϒ (3) +└── $(Expr(:leave, 1)) +4 ─ goto 6 +5 ─ %10 = φᶜ (%3, %5) +│ %11 = φᶜ (%4, %7) +└── $(Expr(:leave, 1)) +6 ┄ %13 = φ (4 => 2, 5 => %10)::NotInferenceDontLookHere.MaybeUndef(NotInferenceDontLookHere.Const(2, false)) +│ %14 = φ (4 => 3, 5 => %11)::Int64 +│ $(Expr(:undefcheck, :y, Core.SSAValue(13))) +│ %16 = Core.tuple(%14, %13) +└── return %17 +``` + +Note in particular that every value live into the critical region gets +an upsilon node at the top of the critical region. This is because +catch blocks are considered to have an invisible control flow edge +from outside the function. As a result, no SSA value dominates the +catch blocks, and all incoming values have to come through a `φᶜ` node. + # Main SSA data structure The main `SSAIR` data structure is worthy of discussion. It draws inspiration from LLVM and Webkit's B3 IR. diff --git a/src/index.md b/src/index.md index 1d77748..b1b6913 100644 --- a/src/index.md +++ b/src/index.md @@ -92,6 +92,7 @@ * [Random Numbers](@ref) * [Shared Arrays](@ref) * [Linear Algebra](@ref) + * [Logging](@ref) * [Sparse Arrays](@ref) * [Unicode](@ref) * [Unit Testing](@ref) diff --git a/src/manual/calling-c-and-fortran-code.md b/src/manual/calling-c-and-fortran-code.md index 07d7f2f..affc89b 100644 --- a/src/manual/calling-c-and-fortran-code.md +++ b/src/manual/calling-c-and-fortran-code.md @@ -155,25 +155,28 @@ It is possible to pass Julia functions to native C functions that accept functio For example, to match C prototypes of the form: ```c -typedef returntype (*functiontype)(argumenttype,...) +typedef returntype (*functiontype)(argumenttype, ...) ``` -The function [`cfunction`](@ref) generates the C-compatible function pointer for a call to a -Julia function. Arguments to [`cfunction`](@ref) are as follows: +The macro [`@cfunction`](@ref) generates the C-compatible function pointer for a call to a +Julia function. Arguments to [`@cfunction`](@ref) are as follows: 1. A Julia Function 2. Return type -3. A tuple type of input types +3. A literal tuple of input types -Only platform-default C calling convention is supported. `cfunction`-generated pointers cannot -be used in calls where WINAPI expects `stdcall` function on 32-bit windows, but can be used on WIN64 -(where `stdcall` is unified with C calling convention). +Like ccall, all of these arguments will be evaluated at compile-time, when the containing method is defined. + +Currently, only the platform-default C calling convention is supported. This means that +`@cfunction`-generated pointers cannot be used in calls where WINAPI expects `stdcall` +function on 32-bit windows, but can be used on WIN64 (where `stdcall` is unified with the +C calling convention). A classic example is the standard C library `qsort` function, declared as: ```c void qsort(void *base, size_t nmemb, size_t size, - int(*compare)(const void *a, const void *b)); + int (*compare)(const void*, const void*)); ``` The `base` argument is a pointer to an array of length `nmemb`, with elements of `size` bytes @@ -182,26 +185,26 @@ an integer less/greater than zero if `a` should appear before/after `b` (or zero is permitted). Now, suppose that we have a 1d array `A` of values in Julia that we want to sort using the `qsort` function (rather than Julia's built-in `sort` function). Before we worry about calling `qsort` and passing arguments, we need to write a comparison function that works for some -arbitrary type T: +arbitrary objects (which define `<`): ```jldoctest mycompare -julia> function mycompare(a::T, b::T) where T - return convert(Cint, a < b ? -1 : a > b ? +1 : 0)::Cint +julia> function mycompare(a, b)::Cint + return (a < b) ? -1 : ((a > b) ? +1 : 0) end mycompare (generic function with 1 method) ``` Notice that we have to be careful about the return type: `qsort` expects a function returning -a C `int`, so we must be sure to return `Cint` via a call to `convert` and a `typeassert`. +a C `int`, so we annotate the return type of the function to be sure it returns a `Cint`. -In order to pass this function to C, we obtain its address using the function `cfunction`: +In order to pass this function to C, we obtain its address using the macro `@cfunction`: ```jldoctest mycompare -julia> const mycompare_c = cfunction(mycompare, Cint, Tuple{Ref{Cdouble}, Ref{Cdouble}}); +julia> mycompare_c = @cfunction(mycompare, Cint, (Ref{Cdouble}, Ref{Cdouble})); ``` -[`cfunction`](@ref) accepts three arguments: the Julia function (`mycompare`), the return type -(`Cint`), and a tuple type of the input argument types, in this case to sort an array of `Cdouble` +[`@cfunction`](@ref) requires three arguments: the Julia function (`mycompare`), the return type +(`Cint`), and a literal tuple of the input argument types, in this case to sort an array of `Cdouble` ([`Float64`](@ref)) elements. The final call to `qsort` looks like this: @@ -227,7 +230,7 @@ julia> A As can be seen, `A` is changed to the sorted array `[-2.7, 1.3, 3.1, 4.4]`. Note that Julia knows how to convert an array into a `Ptr{Cdouble}`, how to compute the size of a type in bytes -(identical to C's `sizeof` operator), and so on. For fun, try inserting a `println("mycompare($a,$b)")` +(identical to C's `sizeof` operator), and so on. For fun, try inserting a `println("mycompare($a, $b)")` line into `mycompare`, which will allow you to see the comparisons that `qsort` is performing (and to verify that it is really calling the Julia function that you passed to it). @@ -518,16 +521,18 @@ unsafe_string(str + Core.sizeof(Cint), len) ### Type Parameters -The type arguments to `ccall` are evaluated statically, when the method containing the `ccall` is defined. -They therefore must take the form of a literal tuple, not a variable, and cannot reference local variables. +The type arguments to `ccall` and `@cfunction` are evaluated statically, +when the method containing the usage is defined. +They therefore must take the form of a literal tuple, not a variable, +and cannot reference local variables. This may sound like a strange restriction, but remember that since C is not a dynamic language like Julia, its functions can only accept argument types with a statically-known, fixed signature. -However, while the type layout must be known statically to compute the `ccall` ABI, +However, while the type layout must be known statically to compute the intended C ABI, the static parameters of the function are considered to be part of this static environment. -The static parameters of the function may be used as type parameters in the `ccall` signature, +The static parameters of the function may be used as type parameters in the call signature, as long as they don't affect the layout of the type. For example, `f(x::T) where {T} = ccall(:valid, Ptr{T}, (Ptr{T},), x)` is valid, since `Ptr` is always a word-size primitive type. @@ -603,7 +608,7 @@ Fortran subroutines, or a `T` for Fortran functions returning the type `T`. ## Mapping C Functions to Julia -### `ccall`/`cfunction` argument translation guide +### `ccall` / `@cfunction` argument translation guide For translating a C argument list to Julia: @@ -626,28 +631,27 @@ For translating a C argument list to Julia: * `Any` * argument value must be a valid Julia object - * currently unsupported by [`cfunction`](@ref) * `jl_value_t**` * `Ref{Any}` * argument value must be a valid Julia object (or `C_NULL`) - * currently unsupported by [`cfunction`](@ref) * `T*` * `Ref{T}`, where `T` is the Julia type corresponding to `T` * argument value will be copied if it is an `isbits` type otherwise, the value must be a valid Julia object - * `(T*)(...)` (e.g. a pointer to a function) + * `T (*)(...)` (e.g. a pointer to a function) - * `Ptr{Cvoid}` (you may need to use [`cfunction`](@ref) explicitly to create this pointer) + * `Ptr{Cvoid}` (you may need to use [`@cfunction`](@ref) explicitly to create this pointer) * `...` (e.g. a vararg) * `T...`, where `T` is the Julia type + * currently unsupported by `@cfunction` * `va_arg` - * not supported + * not supported by `ccall` or `@cfunction` -### `ccall`/`cfunction` return type translation guide +### `ccall` / `@cfunction` return type translation guide For translating a C return type to Julia: @@ -675,7 +679,7 @@ For translating a C return type to Julia: * argument value must be a valid Julia object * `jl_value_t**` - * `Ref{Any}` + * `Ptr{Any}` (`Ref{Any}` is invalid as a return type) * argument value must be a valid Julia object (or `C_NULL`) * `T*` @@ -683,14 +687,14 @@ For translating a C return type to Julia: * `Ref{T}`, where `T` is the Julia type corresponding to `T` * a return type of `Ref{Any}` is invalid, it should either be `Any` (corresponding to `jl_value_t*`) - or `Ptr{Any}` (corresponding to `Ptr{Any}`) + or `Ptr{Any}` (corresponding to `jl_value_t**`) * C **MUST NOT** modify the memory returned via `Ref{T}` if `T` is an `isbits` type * If the memory is owned by C: * `Ptr{T}`, where `T` is the Julia type corresponding to `T` - * `(T*)(...)` (e.g. a pointer to a function) + * `T (*)(...)` (e.g. a pointer to a function) - * `Ptr{Cvoid}` (you may need to use [`cfunction`](@ref) explicitly to create this pointer) + * `Ptr{Cvoid}` (you may need to use [`@cfunction`](@ref) explicitly to create this pointer) ### Passing Pointers for Modifying Inputs @@ -880,8 +884,10 @@ expression, which is then evaluated. Keep in mind that `eval` only operates at t so within this expression local variables will not be available (unless their values are substituted with `$`). For this reason, `eval` is typically only used to form top-level definitions, for example when wrapping libraries that contain many similar functions. +A similar example can be constructed for [`@cfunction`](@ref). -If your usage is more dynamic, use indirect calls as described in the next section. +However, doing this will also be very slow and leak memory, so you should usually avoid this and instead keep reading. +The next section discusses how to use indirect calls to efficiently accomplish a similar effect. ## Indirect Calls @@ -911,6 +917,34 @@ mylibvar = Libdl.dlopen("mylib") ccall(@dlsym("myfunc", mylibvar), Cvoid, ()) ``` +## Closure cfunctions + +The first argument to [`@cfunction`](@ref) can be marked with a `$`, in which case +the return value will instead be a `struct CFunction` which closes over the argument. +You must ensure that this return object is kept alive until all uses of it are done. +The contents and code at the cfunction pointer will be erased via a [`finalizer`](@ref) +when this reference is dropped and atexit. This is not usually needed, since this +functionality is not present in C, but can be useful for dealing with ill-designed APIs +which don't provide a separate closure environment parameter. + +```julia +function qsort(a::Vector{T}, cmp) where T + isbits(T) || throw(ArgumentError("this method can only qsort isbits arrays")) + callback = @cfunction $cmp Cint (Ref{T}, Ref{T}) + # Here, `callback` isa Base.CFunction, which will be converted to Ptr{Cvoid} + # (and protected against finalization) by the ccall + ccall(:qsort, Cvoid, (Ptr{T}, Csize_t, Csize_t, Ptr{Cvoid}), + a, length(A), Base.elsize(A), callback) + # We could instead use: + # GC.@preserve callback begin + # use(Base.unsafe_convert(Ptr{Cvoid}, callback)) + # end + # if we needed to use it outside of a `ccall` + return a +end +``` + + ## Closing a Library It is sometimes useful to close (unload) a library so that it can be reloaded. @@ -922,7 +956,7 @@ and load in the new changes. One can either restart Julia or use the ```julia lib = Libdl.dlopen("./my_lib.so") # Open the library explicitly. sym = Libdl.dlsym(lib, :my_fcn) # Get a symbol for the function to call. -ccall(sym, ...) # Use the symbol instead of the (symbol, library) tuple (remaining arguments are the same). +ccall(sym, ...) # Use the pointer `sym` instead of the (symbol, library) tuple (remaining arguments are the same). Libdl.dlclose(lib) # Close the library explicitly. ``` diff --git a/src/manual/environment-variables.md b/src/manual/environment-variables.md index 513b75c..79a16cd 100644 --- a/src/manual/environment-variables.md +++ b/src/manual/environment-variables.md @@ -314,12 +314,6 @@ event listener for just-in-time (JIT) profiling. Arguments to be passed to the LLVM backend. -!!! note - - This environment variable has an effect only if Julia was compiled with - `JL_DEBUG_BUILD` set — in particular, the `julia-debug` executable is always - compiled with this build variable. - ### `JULIA_DEBUG_LOADING` If set, then Julia prints detailed information about the cache in the loading diff --git a/src/manual/functions.md b/src/manual/functions.md index 5779954..c3adfd3 100644 --- a/src/manual/functions.md +++ b/src/manual/functions.md @@ -553,7 +553,9 @@ at runtime. The nature of keyword arguments makes it possible to specify the same argument more than once. For example, in the call `plot(x, y; options..., width=2)` it is possible that the `options` structure also contains a value for `width`. In such a case the rightmost occurrence takes precedence; in -this example, `width` is certain to have the value `2`. +this example, `width` is certain to have the value `2`. However, explicitly specifying the same keyword +argument multiple times, for example `plot(x, y, width=2, width=3)`, is not allowed and results in +a syntax error. ## Evaluation Scope of Default Values diff --git a/src/manual/interfaces.md b/src/manual/interfaces.md index f951e7b..d13bd75 100644 --- a/src/manual/interfaces.md +++ b/src/manual/interfaces.md @@ -443,7 +443,8 @@ V = view(A, [1,2,4], :) # is not strided, as the spacing between rows is not f | `Base.broadcast_similar(f, ::DestStyle, ::Type{ElType}, inds, As...)` | Allocation of output container | | **Optional methods** | | | | `Base.BroadcastStyle(::Style1, ::Style2) = Style12()` | Precedence rules for mixing styles | -| `Base.broadcast_indices(::StyleA, A)` | Declaration of the indices of `A` for broadcasting purposes (for AbstractArrays, defaults to `axes(A)`) | +| `Base.broadcast_indices(::StyleA, A)` | Declaration of the indices of `A` for broadcasting purposes (defaults to [`axes(A)`](@ref)) | +| `Base.broadcastable(x)` | Convert `x` to an object that has `axes` and supports indexing | | **Bypassing default machinery** | | | `broadcast(f, As...)` | Complete bypass of broadcasting machinery | | `broadcast(f, ::DestStyle, ::Nothing, ::Nothing, As...)` | Bypass after container type is computed | @@ -452,21 +453,43 @@ V = view(A, [1,2,4], :) # is not strided, as the spacing between rows is not f | `broadcast!(f, dest, ::BroadcastStyle, As...)` | Bypass in-place broadcast, specialization on `BroadcastStyle` | [Broadcasting](@ref) is triggered by an explicit call to `broadcast` or `broadcast!`, or implicitly by -"dot" operations like `A .+ b`. Any `AbstractArray` type supports broadcasting, -but the default result (output) type is `Array`. To specialize the result for specific input type(s), -the main task is the allocation of an appropriate result object. -(This is not an issue for `broadcast!`, where -the result object is passed as an argument.) This process is split into two stages: computation -of the behavior and type from the arguments ([`Base.BroadcastStyle`](@ref)), and allocation of the object -given the resulting type with [`Base.broadcast_similar`](@ref). - -`Base.BroadcastStyle` is an abstract type from which all styles are +"dot" operations like `A .+ b` or `f.(x, y)`. Any object that has [`axes`](@ref) and supports +indexing can participate as an argument in broadcasting, and by default the result is stored +in an `Array`. This basic framework is extensible in three major ways: + +* Ensuring that all arguments support broadcast +* Selecting an appropriate output array for the given set of arguments +* Selecting an efficient implementation for the given set of arguments + +Not all types support `axes` and indexing, but many are convenient to allow in broadcast. +The [`Base.broadcastable`](@ref) function is called on each argument to broadcast, allowing +it to return something different that supports `axes` and indexing if it does not. By +default, this is the identity function for all `AbstractArray`s and `Number`s — they already +support `axes` and indexing. For a handful of other types (including but not limited to +types themselves, functions, special singletons like `missing` and `nothing`, and dates), +`Base.broadcastable` returns the argument wrapped in a `Ref` to act as a 0-dimensional +"scalar" for the purposes of broadcasting. Custom types can similarly specialize +`Base.broadcastable` to define their shape, but they should follow the convention that +`collect(Base.broadcastable(x)) == collect(x)`. A notable exception are `AbstractString`s; +they are special-cased to behave as scalars for the purposes of broadcast even though they +are iterable collections of their characters. + +The next two steps (selecting the output array and implementation) are dependent upon +determining a single answer for a given set of arguments. Broadcast must take all the varied +types of its arguments and collapse them down to just one output array and one +implementation. Broadcast calls this single answer a "style." Every broadcastable object +each has its own preferred style, and a promotion-like system is used to combine these +styles into a single answer — the "destination style". + +### Broadcast Styles + +`Base.BroadcastStyle` is the abstract type from which all styles are derived. When used as a function it has two possible forms, unary (single-argument) and binary. The unary variant states that you intend to implement specific broadcasting behavior and/or output type, -and do not wish to rely on the default fallback ([`Broadcast.Scalar`](@ref) or [`Broadcast.DefaultArrayStyle`](@ref)). -To achieve this, you can define a custom `BroadcastStyle` for your object: +and do not wish to rely on the default fallback ([`Broadcast.DefaultArrayStyle`](@ref)). +To override these defaults, you can define a custom `BroadcastStyle` for your object: ```julia struct MyStyle <: Broadcast.BroadcastStyle end @@ -486,6 +509,8 @@ When your broadcast operation involves several arguments, individual argument st combined to determine a single `DestStyle` that controls the type of the output container. For more detail, see [below](@ref writing-binary-broadcasting-rules). +### Selecting an appropriate output array + The actual allocation of the result array is handled by `Base.broadcast_similar`: ```julia @@ -562,6 +587,8 @@ julia> a .+ [5,10] 13 14 ``` +### [Extending broadcast with custom implementations](@id extending-in-place-broadcast) + Finally, it's worth noting that sometimes it's easier simply to bypass the machinery for computing result types and container sizes, and just do everything manually. For example, you can convert a `UnitRange{Int}` `r` to a `UnitRange{BigInt}` with `big.(r)`; the definition @@ -580,7 +607,40 @@ the internal machinery to compute the container type, element type, and indices Broadcast.broadcast(::typeof(somefunction), ::MyStyle, ::Type{ElType}, inds, As...) ``` -### [Writing binary broadcasting rules](@id writing-binary-broadcasting-rules) +Extending `broadcast!` (in-place broadcast) should be done with care, as it is easy to introduce +ambiguities between packages. To avoid these ambiguities, we adhere to the following conventions. + +First, if you want to specialize on the destination type, say `DestType`, then you should +define a method with the following signature: + +```julia +broadcast!(f, dest::DestType, ::Nothing, As...) +``` + +Note that no bounds should be placed on the types of `f` and `As...`. + +Second, if specialized `broadcast!` behavior is desired depending on the input types, +you should write [binary broadcasting rules](@ref writing-binary-broadcasting-rules) to +determine a custom `BroadcastStyle` given the input types, say `MyBroadcastStyle`, and you should define a method with the following +signature: + +```julia +broadcast!(f, dest, ::MyBroadcastStyle, As...) +``` + +Note the lack of bounds on `f`, `dest`, and `As...`. + +Third, simultaneously specializing on both the type of `dest` and the `BroadcastStyle` is fine. In this case, +it is also allowed to specialize on the types of the source arguments (`As...`). For example, these method signatures are OK: + +```julia +broadcast!(f, dest::DestType, ::MyBroadcastStyle, As...) +broadcast!(f, dest::DestType, ::MyBroadcastStyle, As::AbstractArray...) +broadcast!(f, dest::DestType, ::Broadcast.DefaultArrayStyle{0}, As::Number...) +``` + + +#### [Writing binary broadcasting rules](@id writing-binary-broadcasting-rules) The precedence rules are defined by binary `BroadcastStyle` calls: @@ -592,10 +652,10 @@ where `Style12` is the `BroadcastStyle` you want to choose for outputs involving arguments of `Style1` and `Style2`. For example, ```julia -Base.BroadcastStyle(::Broadcast.Style{Tuple}, ::Broadcast.Scalar) = Broadcast.Style{Tuple}() +Base.BroadcastStyle(::Broadcast.Style{Tuple}, ::Broadcast.AbstractArrayStyle{0}) = Broadcast.Style{Tuple}() ``` -indicates that `Tuple` "wins" over scalars (the output container will be a tuple). +indicates that `Tuple` "wins" over zero-dimensional arrays (the output container will be a tuple). It is worth noting that you do not need to (and should not) define both argument orders of this call; defining one is sufficient no matter what order the user supplies the arguments in. @@ -643,37 +703,3 @@ yields another `SparseVecStyle`, that its combination with a 2-dimensional array yields a `SparseMatStyle`, and anything of higher dimensionality falls back to the dense arbitrary-dimensional framework. These rules allow broadcasting to keep the sparse representation for operations that result in one or two dimensional outputs, but produce an `Array` for any other dimensionality. - -### [Extending `broadcast!`](@id extending-in-place-broadcast) - -Extending `broadcast!` (in-place broadcast) should be done with care, as it is easy to introduce -ambiguities between packages. To avoid these ambiguities, we adhere to the following conventions. - -First, if you want to specialize on the destination type, say `DestType`, then you should -define a method with the following signature: - -```julia -broadcast!(f, dest::DestType, ::Nothing, As...) -``` - -Note that no bounds should be placed on the types of `f` and `As...`. - -Second, if specialized `broadcast!` behavior is desired depending on the input types, -you should write [binary broadcasting rules](@ref writing-binary-broadcasting-rules) to -determine a custom `BroadcastStyle` given the input types, say `MyBroadcastStyle`, and you should define a method with the following -signature: - -```julia -broadcast!(f, dest, ::MyBroadcastStyle, As...) -``` - -Note the lack of bounds on `f`, `dest`, and `As...`. - -Third, simultaneously specializing on both the type of `dest` and the `BroadcastStyle` is fine. In this case, -it is also allowed to specialize on the types of the source arguments (`As...`). For example, these method signatures are OK: - -```julia -broadcast!(f, dest::DestType, ::MyBroadcastStyle, As...) -broadcast!(f, dest::DestType, ::MyBroadcastStyle, As::AbstractArray...) -broadcast!(f, dest::DestType, ::Broadcast.Scalar, As::Number...) -``` diff --git a/src/manual/strings.md b/src/manual/strings.md index e03c6a9..9d49b95 100644 --- a/src/manual/strings.md +++ b/src/manual/strings.md @@ -452,8 +452,36 @@ I have $100 in my account. ## Triple-Quoted String Literals When strings are created using triple-quotes (`"""..."""`) they have some special behavior that -can be useful for creating longer blocks of text. First, if the opening `"""` is followed by a -newline, the newline is stripped from the resulting string. +can be useful for creating longer blocks of text. + +First, triple-quoted strings are also dedented to the level of the least-indented line. +This is useful for defining strings within code that is indented. For example: + +```jldoctest +julia> str = """ + Hello, + world. + """ +" Hello,\n world.\n" +``` + +In this case the final (empty) line before the closing `"""` sets the indentation level. + +The dedentation level is determined as the longest common starting sequence of spaces or +tabs in all lines, excluding the line following the opening `"""` and lines containing +only spaces or tabs (the line containing the closing `"""` is always included). +Then for all lines, excluding the text following the opening `"""`, the common starting +sequence is removed (including lines containing only spaces and tabs if they start with +this sequence), e.g.: +```jldoctest +julia> """ This + is + a test""" +" This\nis\n a test" +``` + +Next, if the opening `"""` is followed by a newline, +the newline is stripped from the resulting string. ```julia """hello""" @@ -474,20 +502,20 @@ but hello""" ``` -will contain a literal newline at the beginning. Trailing whitespace is left unaltered. They can -contain `"` symbols without escaping. Triple-quoted strings are also dedented to the level of -the least-indented line. This is useful for defining strings within code that is indented. For -example: +will contain a literal newline at the beginning. + +Stripping of the newline is performed after the dedentation for example: ```jldoctest -julia> str = """ - Hello, - world. - """ -" Hello,\n world.\n" +julia> """ + Hello, + world.""" +"Hello,\nworld." ``` -In this case the final (empty) line before the closing `"""` sets the indentation level. +Trailing whitespace is left unaltered. + +Triple-quoted string literals can contain `"` symbols without escaping. Note that line breaks in literal strings, whether single- or triple-quoted, result in a newline (LF) character `\n` in the string, even if your editor uses a carriage return `\r` (CR) or CRLF diff --git a/src/stdlib/Logging.md b/src/stdlib/Logging.md new file mode 100644 index 0000000..6c170f5 --- /dev/null +++ b/src/stdlib/Logging.md @@ -0,0 +1,246 @@ +# Logging + +The `Logging` module provides a way to record the history and progress of a +computation as a log of events. Events are created by inserting a logging +statement into the source code, for example: + +```julia +@warn "Abandon printf debugging, all ye who enter here!" +┌ Warning: Abandon printf debugging, all ye who enter here! +└ @ Main REPL[1]:1 +``` + +The system provides several advantages over peppering your source code with +calls to `println()`. First, it allows you to control the visibility and +presentation of messages without editing the source code. For example, in +contrast to the `@warn` above + +```julia +@debug "The sum of some values $(sum(rand(100)))" +``` + +will produce no output by default. Furthermore, it's very cheap to leave debug +statements like this in the source code because the system avoids evaluating +the message if it would later be ignored. In this case `sum(rand(100))` and +the associated string processing will never be executed unless debug logging is +enabled. + +Second, the logging tools allow you to attach arbitrary data to each event as a +set of key--value pairs. This allows you to capture local variables and other +program state for later analysis. For example, to attach the local array +variable `A` and the sum of a vector `v` as the key `s` you can use + +```jldoctest +A = ones(Int, 4, 4) +v = ones(100) +@info "Some variables" A s=sum(v) + +# Output +┌ Info: Some variables +│ A = +│ 4×4 Array{Int64,2}: +│ 1 1 1 1 +│ 1 1 1 1 +│ 1 1 1 1 +│ 1 1 1 1 +└ s = 100.0 +``` + +All of the logging macros `@debug`, `@info`, `@warn` and `@error` share common +features that are described in detail in the documentation for the more +general macro [`@logmsg`](@ref). + +## Log event structure + +Each event generates several pieces of data, some provided by the user and some +automatically extracted. Let's examine the user-defined data first: + +* The *log level* is a broad category for the message that is used for early + filtering. There are several standard levels of type [`LogLevel`](@ref); + user-defined levels are also possible. + - Use `Debug` for verbose information that could be useful when debugging an + application or module. These events are disabled by default. + - Use `Info` to inform the user about the normal operation of the program. + - Use `Warn` when a potential problem is detected. + - Use `Error` to report errors where the code has enough context to recover + and continue. (When the code doesn't have enough context, an exception or + early return is more appropriate.) +* The *message* is an object describing the event. By convention + `AbstractString`s passed as messages are assumed to be in markdown format. + Other types will be displayed using `show(io,mime,obj)` according to the + display capabilities of the installed logger. +* Optional *key--value pairs* allow arbitrary data to be attached to each event. + Some keys have conventional meaning that can affect the way an event is + interpreted (see [`@logmsg`](@ref)). + +The system also generates some standard information for each event: + +* The `module` in which the logging macro was expanded. +* The `file` and `line` where the logging macro occurs in the source code. +* A message `id` that is unique for each logging macro invocation. This is + very useful as a key for caching information or actions associated with an + event. For instance, it can be used to limit the number of times a message + is presented to the user. +* A `group` for the event, which is set to the base name of the file by default, + without extension. This can be used to group messages into categories more + finely than the log level (for example, all deprecation warnings have group + `:depwarn`), or into logical groupings across or within modules. + +Notice that some useful information such as the event time is not included by +default. This is because such information can be expensive to extract and is +also *dynamically* available to the current logger. It's simple to define a +[custom logger](@ref AbstractLogger-interface) to augment event data with the +time, backtrace, values of global variables and other useful information as +required. + + +## Processing log events + +As you can see in the examples, logging statements make no mention of +where log events go or how they are processed. This is a key design feature +that makes the system composable and natural for concurrent use. It does this +by separating two different concerns: + +* *Creating* log events is the concern of the module author who needs to + decide where events are triggered and which information to include. +* *Processing* of log events — that is, display, filtering, aggregation and + recording — is the concern of the application author who needs to bring + multiple modules together into a cooperating application. + +### Loggers + +Processing of events is performed by a *logger*, which is the first piece of +user configurable code to see the event. All loggers must be subtypes of +[`AbstractLogger`](@ref). + +When an event is triggered, the appropriate logger is found by looking for a +task-local logger with the global logger as fallback. The idea here is that +the application code knows how log events should be processed and exists +somewhere at the top of the call stack. So we should look up through the call +stack to discover the logger — that is, the logger should be *dynamically +scoped*. (This is a point of contrast with logging frameworks where the +logger is *lexically scoped*; provided explicitly by the module author or as a +simple global variable. In such a system it's awkward to control logging while +composing functionality from multiple modules.) + +The global logger may be set with [`global_logger`](@ref), and task-local +loggers controlled using [`with_logger`](@ref). Newly spawned tasks inherit +the logger of the parent task. + +There are three logger types provided by the library. [`ConsoleLogger`](@ref) +is the default logger you see when starting the REPL. It displays events in a +readable text format and tries to give simple but user friendly control over +formatting and filtering. [`NullLogger`](@ref) is a convenient way to drop all +messages where necessary; it is the logging equivalent of the [`DevNull`](@ref) +stream. [`SimpleLogger`](@ref) is a very simplistic text formatting logger, +mainly useful for debugging the logging system itself. + +Custom loggers should come with overloads for the functions described in the +[reference section](@ref AbstractLogger-interface). + +### Early filtering and message handling + +When an event occurs, a few steps of early filtering occur to avoid generating +messages that will be discarded: + +1. The message log level is checked against a global minimum level (set via + [`disable_logging`](@ref)). This is a crude but extremely cheap global + setting. +2. The current logger state is looked up and the message level checked against the + logger's cached minimum level, as found by calling [`min_enabled_level`](@ref). + This behavior can be overridden via environment variables (more on this later). +3. The [`shouldlog`](@ref) function is called with the current logger, taking + some minimal information (level, module, group, id) which can be computed + statically. Most usefully, `shouldlog` is passed an event `id` which can be + used to discard events early based on a cached predicate. + +If all these checks pass, the message and key--value pairs are evaluated in full +and passed to the current logger via the [`handle_message`](@ref) function. +`handle_message()` may perform additional filtering as required and display the +event to the screen, save it to a file, etc. + +Exceptions that occur while generating the log event are captured and logged +by default. This prevents individual broken events from crashing the +application, which is helpful when enabling little-used debug events in a +production system. This behavior can be customized per logger type by +extending [`catch_exceptions`](@ref). + +## Testing log events + +Log events are a side effect of running normal code, but you might find +yourself wanting to test particular informational messages and warnings. The +`Test` module provides a [`@test_logs`](@ref) macro that can be used to +pattern match against the log event stream. + +## Environment variables + +Message filtering can be influenced through the `JULIA_DEBUG` environment +variable, and serves as an easy way to enable debug logging for a file or +module. For example, loading julia with `JULIA_DEBUG=loading` will activate +`@debug` log messages in `loading.jl`: + +``` +$ JULIA_DEBUG=loading julia -e 'using OhMyREPL' +┌ Debug: Rejecting cache file /home/user/.julia/compiled/v0.7/OhMyREPL.ji due to it containing an invalid cache header +└ @ Base loading.jl:1328 +[ Info: Recompiling stale cache file /home/user/.julia/compiled/v0.7/OhMyREPL.ji for module OhMyREPL +┌ Debug: Rejecting cache file /home/user/.julia/compiled/v0.7/Tokenize.ji due to it containing an invalid cache header +└ @ Base loading.jl:1328 +... +``` + +Similarly, the environment variable can be used to enable debug logging of +modules, such as `Pkg`, or module roots (see [`Base.moduleroot`](@ref)). To +enable all debug logging, use the special value `all`. + + +## Reference + +### Creating events + +```@docs +Logging.@logmsg +Logging.LogLevel +``` + +### [Processing events with AbstractLogger](@id AbstractLogger-interface) + +Event processing is controlled by overriding functions associated with +`AbstractLogger`: + +| Methods to implement |   | Brief description | +|:----------------------------- |:---------------------- |:---------------------------------------- | +| [`handle_message`](@ref) | | Handle a log event | +| [`shouldlog`](@ref) | | Early filtering of events | +| [`min_enabled_level`](@ref) | | Lower bound for log level of accepted events | +| **Optional methods** | **Default definition** | **Brief description** | +| [`catch_exceptions`](@ref) | `true` | Catch exceptions during event evaluation | + + +```@docs +Logging.AbstractLogger +Logging.handle_message +Logging.shouldlog +Logging.min_enabled_level +Logging.catch_exceptions +Logging.disable_logging +``` + +### Using Loggers + +Logger installation and inspection: + +```@docs +Logging.global_logger +Logging.with_logger +Logging.current_logger +``` + +Loggers that are supplied with the system: + +```@docs +Logging.NullLogger +Logging.ConsoleLogger +Logging.SimpleLogger +``` + diff --git a/src/stdlib/Pkg3.md b/src/stdlib/Pkg3.md index 13307ef..289511f 100644 --- a/src/stdlib/Pkg3.md +++ b/src/stdlib/Pkg3.md @@ -86,7 +86,7 @@ identify the package in projects that depend on it. !!! note For legacy reasons it is possible to load a package without a project file or UUID from the REPL or the top-level of a script. It is not possible, however, - to load a package with a project file or UUID from a project with them. Once + to load a package without a project file or UUID from a project with them. Once you've loaded from a project file, everything needs a project file and UUID. **Application:** a project which provides standalone functionality not intended @@ -133,36 +133,36 @@ which versions of packages are compatible or incompatible with each other. A registry is indexed by package name and UUID, and has a directory for each registered package providing the following metadata about it: - - name – e.g. `DataFrames` - - UUID – e.g. `a93c6f00-e57d-5684-b7b6-d8193f3e46c0` - - authors – e.g. `Jane Q. Developer ` - - license – e.g. MIT, BSD3, or GPLv2 - - repository – e.g. `https://github.com/JuliaData/DataFrames.jl.git` - - description – a block of text summarizing the functionality of a package - - keywords – e.g. `data`, `tabular`, `analysis`, `statistics` - - versions – a list of all registered version tags +- name – e.g. `DataFrames` +- UUID – e.g. `a93c6f00-e57d-5684-b7b6-d8193f3e46c0` +- authors – e.g. `Jane Q. Developer ` +- license – e.g. MIT, BSD3, or GPLv2 +- repository – e.g. `https://github.com/JuliaData/DataFrames.jl.git` +- description – a block of text summarizing the functionality of a package +- keywords – e.g. `data`, `tabular`, `analysis`, `statistics` +- versions – a list of all registered version tags For each registered version of a package, the following information is provided: - - its semantic version number – e.g. `v1.2.3` - - its git tree SHA-1 hash – e.g. `7ffb18ea3245ef98e368b02b81e8a86543a11103` - - a map from names to UUIDs of dependencies - - which versions of other packages it is compatible/incompatible with +- its semantic version number – e.g. `v1.2.3` +- its git tree SHA-1 hash – e.g. `7ffb18ea3245ef98e368b02b81e8a86543a11103` +- a map from names to UUIDs of dependencies +- which versions of other packages it is compatible/incompatible with -Dependencies and compatiblity are stored in a compressed but human-readable -format using ranges of package verions. +Dependencies and compatibility are stored in a compressed but human-readable +format using ranges of package versions. **Depot:** a directory on a system where various package-related resources live, including: - - `environments`: shared named environments (e.g. `v0.7`, `devtools`) - - `clones`: bare clones of package repositories - - `compiled`: cached compiled package images (`.ji` files) - - `config`: global configuration files (e.g. `startup.jl`) - - `dev`: default directory for package development - - `logs`: log files (e.g. `manifest_usage.toml`, `repl_history.jl`) - - `packages`: installed package versions - - `registries`: clones of registries (e.g. `Uncurated`) +- `environments`: shared named environments (e.g. `v0.7`, `devtools`) +- `clones`: bare clones of package repositories +- `compiled`: cached compiled package images (`.ji` files) +- `config`: global configuration files (e.g. `startup.jl`) +- `dev`: default directory for package development +- `logs`: log files (e.g. `manifest_usage.toml`, `repl_history.jl`) +- `packages`: installed package versions +- `registries`: clones of registries (e.g. `Uncurated`) **Load path:** a stack of environments where package identities, their dependencies, and entry-points are searched for. The load path is controlled in @@ -185,17 +185,25 @@ global configuration data is saved. Later entries in the depot path are treated as read-only and are appropriate for registries, packages, etc. installed and managed by system administrators. - ## Getting Started -The Pkg REPL-mode is entered using from the Julia REPL using the key `]`. +The Pkg REPL-mode is entered from the Julia REPL using the key `]`. + +``` +(v0.7) pkg> +``` + +The part inside the parenthesis of the prompt shows the name of the current project. +Since we haven't created our own project yet, we are in the default project, located at `~/.julia/environments/v0.7` +(or whatever version of Julia you happen to run). + To return to the `julia>` prompt, either press backspace when the input line is empty or press Ctrl+C. Help is available by calling `pkg> help`. To generate files for a new project, use `pkg> generate`. ``` -pkg> generate HelloWorld +(v0.7) pkg> generate HelloWorld ``` This creates a new project `HelloWorld` with the following files (visualized with the external [`tree` command](https://linux.die.net/man/1/tree)): @@ -244,10 +252,11 @@ Hello World! ### Adding packages to the project Let’s say we want to use the standard library package `Random` and the registered package `JSON` in our project. -We simply `add` these packages: +We simply `add` these packages (note how the prompt now shows the name of the newly generated project, +since we are inside the `HelloWorld` project directory): ``` -pkg> add Random JSON +(HelloWorld) pkg> add Random JSON Resolving package versions... Updating "~/Documents/HelloWorld/Project.toml" [682c06a0] + JSON v0.17.1 @@ -287,7 +296,7 @@ Sometimes we might want to use the very latest, unreleased version of a package, git repository. We can use e.g. the `master` branch of `JSON` by specifying the branch after a `#` when adding the package: ``` -pkg> add JSON#master +(HelloWorld) pkg> add JSON#master Cloning package from https://github.com/JuliaIO/JSON.jl.git Resolving package versions... Updating "~/Documents/HelloWorld/Project.toml" @@ -299,7 +308,7 @@ pkg> add JSON#master If we want to use a package that has not been registered in a registry, we can `add` its git repository url: ``` -pkg> add https://github.com/fredrikekre/ImportMacros.jl +(HelloWorld) pkg> add https://github.com/fredrikekre/ImportMacros.jl Cloning package from https://github.com/fredrikekre/ImportMacros.jl Resolving package versions... Downloaded MacroTools ─ v0.4.0 @@ -315,10 +324,10 @@ For unregistered packages we could have given a branch (or commit SHA) to track ## Developing packages -Let’s say we found a bug in `JSON` that we want to fix. We can get the full git-repo using the `develop` command +Let’s say we found a bug in one of our dependencies, e.g. `JSON` that we want to fix. We can get the full git-repo using the `develop` command ``` -pkg> develop JSON +(HelloWorld) pkg> develop JSON Cloning package from https://github.com/JuliaIO/JSON.jl.git Resolving package versions... Updating "~/Documents/HelloWorld/Project.toml" @@ -327,11 +336,11 @@ pkg> develop JSON ``` By default, the package get cloned to the `~/.julia/dev` folder but can also be set by the `JULIA_PKG_DEVDIR` environment variable. -When we have fixed the bug and checked that `JSON` now works correctly with out project, we can make a PR to the `JSON` repository. -When a new release of `JSON` is made, we can go back to using the versioned `JSON` using the command `free` and `update` (see next section): +When we have fixed the bug and checked that `JSON` now works correctly with our project, we can make a PR to the `JSON` repository. +When the PR has been merged we can go over to track the master branch and finally, when a new release of `JSON` is made, we can go back to using the versioned `JSON` using the command `free` and `update` (see next section): ``` -pkg> free JSON +(HelloWorld) pkg> free JSON Resolving package versions... Updating "~/Documents/HelloWorld/Project.toml" [682c06a0] ~ JSON v0.17.1+ #master ⇒ v0.17.1 @@ -341,20 +350,20 @@ pkg> free JSON It is also possible to give a local path as the argument to `develop` which will not clone anything but simply use that directory for the package. -Developing a non registered package is done by giving the git-repo url as an argument to `develop`. +Overriding the dependency path for a non registered package is done by giving the git-repo url as an argument to `develop`. ### Updating dependencies When new versions of packages the project is using are released, it is a good idea to update. Simply calling `up` will try to update *all* the dependencies of the project. Sometimes this is not what you want. You can specify a subset of the dependencies to upgrade by giving them as arguments to `up`, e.g: ``` -pkg> up JSON +(HelloWorld) pkg> up JSON ``` -The version of all other dependencies will stay the same. If you only want to update the minor version of packages, to reduce the risk that your project breaks, you can give the `--minor` flag, e.g: +The version of all other direct dependencies will stay the same. If you only want to update the minor version of packages, to reduce the risk that your project breaks, you can give the `--minor` flag, e.g: ``` -pkg> up --minor JSON +(HelloWorld) pkg> up --minor JSON ``` Packages that track a branch are not updated when a minor upgrade is done. @@ -363,7 +372,7 @@ Developed packages are never touched by the package manager. If you just want install the packages that are given by the current `Manifest.toml` use ``` -pkg> up --manifest --fixed +(HelloWorld) pkg> up --manifest --fixed ``` ### Preview mode @@ -372,25 +381,24 @@ If you just want to see the effects of running a command, but not change your st For example: ``` -pkg> preview add Plot +(HelloWorld) pkg> preview add Plots ``` or ``` -pkg> preview up +(HelloWorld) pkg> preview up ``` will show you the effects adding `Plots`, or doing a full upgrade, respectively, would have on your project. However, nothing would be installed and your `Project.toml` and `Manfiest.toml` are untouched. - -### Using someone elses project. +### Using someone elses project Simple clone their project using e.g. `git clone`, `cd` to the project directory and call ``` -pkg> up --manifest --fixed +(SomeProject) pkg> up --manifest --fixed ``` This will install the packages at the same state that the project you cloned was using. diff --git a/tools/check_codex.jl b/tools/check_codex.jl index 5d316db..cd371a6 100644 --- a/tools/check_codex.jl +++ b/tools/check_codex.jl @@ -108,7 +108,7 @@ function check_julia_doc_src_and_codex(path1, path2) end dir = replace(dircolon, ":" => "/") # codex에만 있으면 codex, src에 있는 파일 지우기 - if contains(dir, codex_path) + if occursin(codex_path, dir) for d in (dir, replace(dir, codex_path => src_path)) #print_with_color(:red, "rm ") #print_with_color(:white, d) @@ -117,7 +117,7 @@ function check_julia_doc_src_and_codex(path1, path2) println() end # julia_doc_src에만 있으면 codex, src에 복사 - elseif contains(dir, julia_doc_src_path) + elseif occursin(julia_doc_src_path, dir) copy_julia_doc_src_to_codex_and_src(dir, filename) end end From 3dc2a838ac9a5a3e2394c40bebf1a8312835c082 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Sat, 14 Apr 2018 14:36:38 +0900 Subject: [PATCH 018/153] update Julia Commit b6d81e36bb --- codex/NEWS.md | 12 +- codex/base/base.md | 1 + codex/manual/code-loading.md | 330 +++++++++++++++++++++++++ codex/manual/control-flow.md | 6 +- codex/manual/functions.md | 35 ++- codex/manual/networking-and-streams.md | 12 +- codex/manual/strings.md | 45 +++- codex/manual/types.md | 4 +- codex/manual/variables-and-scoping.md | 84 ++++++- codex/stdlib/LibGit2.md | 168 +++++++++++++ make.jl | 1 + src/NEWS.md | 12 +- src/base/base.md | 1 + src/manual/code-loading.md | 330 +++++++++++++++++++++++++ src/manual/control-flow.md | 2 +- src/manual/functions.md | 35 ++- src/manual/networking-and-streams.md | 12 +- src/manual/strings.md | 45 +++- src/manual/types.md | 4 +- src/manual/variables-and-scoping.md | 84 ++++++- src/stdlib/LibGit2.md | 168 +++++++++++++ 21 files changed, 1325 insertions(+), 66 deletions(-) create mode 100644 codex/manual/code-loading.md create mode 100644 codex/stdlib/LibGit2.md create mode 100644 src/manual/code-loading.md create mode 100644 src/stdlib/LibGit2.md diff --git a/codex/NEWS.md b/codex/NEWS.md index eedb604..fe5f7b2 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -230,7 +230,7 @@ This section lists changes that do not have deprecation warnings. * `countlines` now always counts the last non-empty line even if it does not end with EOL, matching the behavior of `eachline` and `readlines` ([#25845](https://github.com/JuliaLang/julia/issues/25845)). - * `getindex(s::String, r::UnitRange{Int})` now throws `UnicodeError` if `last(r)` + * `getindex(s::String, r::UnitRange{Int})` now throws `StringIndexError` if `last(r)` is not a valid index into `s` ([#22572](https://github.com/JuliaLang/julia/issues/22572)). * `ntuple(f, n::Integer)` throws `ArgumentError` if `n` is negative. @@ -758,6 +758,16 @@ Deprecated or removed necessary, consider `fill!(similar(A[, opts...]), {one(eltype(A)) | zero(eltype(A))})`. For an algebraic multiplicative identity, consider `one(A)` ([#24656](https://github.com/JuliaLang/julia/issues/24656)). + * The `similar(dims->f(..., dims...), [T], axes...)` method to add offset array support + to a function `f` that would otherwise create a non-offset array has been deprecated. + Instead, call `f(..., axes...)` directly and, if needed, the offset array implementation + should add offset axis support to the function `f` directly ([#26733](https://github.com/JuliaLang/julia/issues/26733)). + + * The functions `ones` and `zeros` used to accept any objects as dimensional arguments, + implicitly converting them to `Int`s. This is now deprecated; only `Integer`s or + `AbstractUnitRange`s are accepted as arguments. Instead, convert the arguments before + calling `ones` or `zeros` ([#26733](https://github.com/JuliaLang/julia/issues/26733)). + * The `Operators` module is deprecated. Instead, import required operators explicitly from `Base`, e.g. `import Base: +, -, *, /` ([#22251](https://github.com/JuliaLang/julia/issues/22251)). diff --git a/codex/base/base.md b/codex/base/base.md index f9a8354..1839bb8 100644 --- a/codex/base/base.md +++ b/codex/base/base.md @@ -295,6 +295,7 @@ Core.TypeError Core.UndefKeywordError Core.UndefRefError Core.UndefVarError +Base.StringIndexError Base.InitError Base.retry Base.ExponentialBackOff diff --git a/codex/manual/code-loading.md b/codex/manual/code-loading.md new file mode 100644 index 0000000..216e05e --- /dev/null +++ b/codex/manual/code-loading.md @@ -0,0 +1,330 @@ +# Code Loading + +Julia has two mechanisms for loading code: + +1. **Code inclusion:** e.g. `include("source.jl")`. Inclusion allows you to split a single program across multiple source files. The expression `include("source.jl")` causes the contents of the file `source.jl` to be evaluated inside of the module where the `include` call occurs. If `include("source.jl")` is called multiple times, `source.jl` is evaluated multiple times. The included path, `source.jl`, is interpreted relative to the file where the `include` call occurs. This makes it simple to relocate a subtree of source files. In the REPL, included paths are interpreted relative to the current working directory, `pwd()`. +2. **Package loading:** e.g. `import X` or `using X`. The import mechanism allows you to load a package—i.e. an independent, reusable collection of Julia code, wrapped in a module—and makes the resulting module available by the name `X` inside of the importing module. If the same `X` package is imported multiple times in the same Julia session, it is only loaded the first time—on subsequent imports, the importing module gets a reference to the same module. It should be noted, however, that `import X` can load different packages in different contexts: `X` can refer to one package named `X` in the main project but potentially different packages named `X` in each dependency. More on this below. + +Code inclusion is quite straightforward: it simply parses and evaluates a source file in the context of the caller. Package loading is built on top of code inclusion and is quite a bit more complex. The rest of this chapter, therefore, focuses on the behavior and mechanics of package loading. + +!!! note + You only need to read this chapter if you want to understand the technical details of package loading in Julia. If you just want to install and use packages, simply use Julia's built-in package manager to add packages to your environment and write `import X` or `using X` in your code to load packages that you've added. + +A *package* is a source tree with a standard layout providing functionality that can be reused by other Julia projects. A package is loaded by `import X` or `using X` statements. These statements also make the module named `X`, which results from loading the package code, available within the module where the import statement occurs. The meaning of `X` in `import X` is context-dependent: which `X` package is loaded depends on what code the statement occurs in. The effect of `import X` depends on two questions: + +1. **What** package is `X` in this context? +2. **Where** can that `X` package be found? + +Understanding how Julia answers these questions is key to understanding package loading. + +## Federation of packages + +Julia supports federated management of packages. This means that multiple independent parties can maintain both public and private packages and registries of them, and that projects can depend on a mix of public and private packages from different registries. Packages from various registries are installed and managed using a common set of tools and workflows. The Pkg3 next-generation package manager [[docs](https://julialang.org/Pkg3.jl/latest/), [repo](https://github.com/JuliaLang/Pkg3.jl)] ships with Julia 0.7/1.0 and lets you install and manage dependencies of your projects, by creating and manipulating project files, which describe what your project depends on, and manifest files that snapshot exact versions of your project's complete dependency graph. + +One consequence of federation is that there cannot be a central authority for package naming. Different entities may use the same name to refer to unrelated packages. This possibility is unavoidable since these entities do not coordinate and may not even know about each other. Because of the lack of a central naming authority, a single project can quite possibly end up depending on different packages with the same name. Julia's package loading mechanism handles this by not requiring package names to be globally unique, even within the dependency graph of a single project. Instead, packages are identified by [universally unique identifiers](https://en.wikipedia.org/wiki/Universally_unique_identifier) (UUIDs) which are assigned to them before they are registered. The question *"what is `X`?"* is answered by determining the UUID of `X`. + +Since the decentralized naming problem is somewhat abstract, it may help to walk through a concrete scenario to understand the issue. Suppose you're developing an application called `App`, which uses two packages: `Pub` and `Priv`. `Priv` is a private package that you created, whereas `Pub` is a public package that you use but don't control. When you created `Priv`, there was no public package by that name. Subsequently, however, an unrelated package also named `Priv` has been published and become popular. In fact, the `Pub` package has started to use it. Therefore, when you next upgrade `Pub` to get the latest bug fixes and features, `App` will end up—through no action of yours other than upgrading—depending on two different packages named `Priv`. `App` has a direct dependency on your private `Priv` package, and an indirect dependency, through `Pub`, on the new public `Priv` package. Since these two `Priv` packages are different but both required for `App` to continue working correctly, the expression `import Priv` must refer to different `Priv` packages depending on whether it occurs in `App`'s code or in `Pub`'s code. Julia's package loading mechanism allows this by distinguishing the two `Priv` packages by context and UUID. How this distinction works is determined by environments, as explained in the following sections. + +## Environments + +An *environment* determines what `import X` and `using X` mean in various code contexts and what files these statements cause to be loaded. Julia understands three kinds of environments: + +1. **A project environment** is a directory with a project file and an optional manifest file. The project file determines what the names and identities of the direct dependencies of a project are. The manifest file, if present, gives a complete dependency graph, including all direct and indirect dependencies, exact versions of each dependency, and sufficient information to locate and load the correct version. +2. **A package directory** is a directory containing the source trees of a set of packages as subdirectories. This kind of environment was the only kind that existed in Julia 0.6 and earlier. If `X` is a subdirectory of a package directory and `X/src/X.jl` exists, then the package `X` is available in the package directory environment and `X/src/X.jl` is the source file by which it is loaded. +3. **A stacked environment** is an ordered set of project environments and package directories, overlaid to make a single composite environment in which all the packages available in its constituent environments are available. Julia's load path is a stacked environment, for example. + +These three kinds of environment each serve a different purpose: + +* Project environments provide **reproducibility.** By checking a project environment into version control—i.e. a git repository—along with the rest of the project's source code, you can reproduce the exact state of the project _and_ all of its dependencies since the manifest file captures the exact version of every dependency and can be rematerialized easily. +* Package directories provide low-overhead **convenience** when a project environment would be overkill: are handy when you have a set of packages and just want to put them somewhere and use them as they are without having to create and maintain a project environment for them. +* Stacked environments allow for **augmentation** of the primary environment with additional tools. You can push an environment including development tools onto the stack and they will be available from the REPL and scripts but not from inside of packages. + +As an abstraction, an environment provides three maps: `roots`, `graph` and `paths`. When resolving the meaning of `import X`, `roots` and `graph` are used to determine the identity of `X` and answer the question *"what is `X`?"*, while the `paths` map is used to locate the source code of `X` and answer the question *"where is `X`?"* The specific roles of the three maps are: + +- **roots:** `name::Symbol` ⟶ `uuid::UUID` + + An environment's `roots` map assigns package names to UUIDs for all the top-level dependencies that the environment makes available to the main project (i.e. the ones that can be loaded in `Main`). When Julia encounters `import X` in the main project, it looks up the identity of `X` as `roots[:X]`. + +- **graph:** `context::UUID` ⟶ `name::Symbol` ⟶ `uuid::UUID` + + An environment's `graph` is a multilevel map which assigns, for each `context` UUID, a map from names to UUIDs, similar to the `roots` map but specific to that `context`. When Julia sees `import X` in the code of the package whose UUID is `context`, it looks up the identity of `X` as `graph[context][:X]`. In particular, this means that `import X` can refer to different packages depending on `context`. + +- **paths:** `uuid::UUID` × `name::Symbol` ⟶ `path::String` + + The `paths` map assigns to each package UUID-name pair, the location of the entry-point source file of that package. After the identity of `X` in `import X` has been resolved to a UUID via `roots` or `graph` (depending on whether it is loaded from the main project or an dependency), Julia determines what file to load to acquire `X` by looking up `paths[uuid,:X]` in the environment. Including this file should create a module named `X`. After the first time this package is loaded, any import resolving to the same `uuid` will simply create a new binding to the same already-loaded package module. + +Each kind of environment defines these three maps differently, as detailed in the following sections. + +!!! note + For clarity of exposition, the examples throughout this chapter include fully materialized data structures for `roots`, `graph` and `paths`. However, these maps are really only abstractions—for efficiency, Julia's package loading code does not actually materialize them. Instead, it queries them through internal APIs and lazily computes only as much of each structure as is necessary to load a given package. + +### Project environments + +A project environment is determined by a directory containing a project file, `Project.toml`, and optionally a manifest file, `Manifest.toml`. These files can also be named `JuliaProject.toml` and `JuliaManifest.toml`, in which case `Project.toml` and `Manifest.toml` are ignored; this allows for coexistence with other tools that might consider files named `Project.toml` and `Manifest.toml` significant. For pure Julia projects, however, the names `Project.toml` and `Manifest.toml` should be preferred. The `roots`, `graph` and `paths` maps of a project environment are defined as follows. + +**The roots map** of the environment is determined by the contents of the project file, specifically, its top-level `name` and `uuid` entries and its `[deps]` section (all optional). Consider the following example project file for the hypothetical application, `App`, as described above: + +```toml +name = "App" +uuid = "8f986787-14fe-4607-ba5d-fbff2944afa9" + +[deps] +Priv = "ba13f791-ae1d-465a-978b-69c3ad90f72b" +Pub = "c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1" +``` + +This project file implies the following `roots` map, if it were materialized as a Julia dictionary: + +```julia +roots = Dict( + :App => UUID("8f986787-14fe-4607-ba5d-fbff2944afa9"), + :Priv => UUID("ba13f791-ae1d-465a-978b-69c3ad90f72b"), + :Pub => UUID("c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1"), +) +``` + +Given this `roots` map, in the code of `App` the statement `import Priv` will cause Julia to look up `roots[:Priv]`, which yields `ba13f791-ae1d-465a-978b-69c3ad90f72b`, the UUID of the `Priv` package that is to be loaded in that context. This UUID identifies which `Priv` package to load and use when the main application evaluates `import Priv`. + +**The dependency graph** of a project environment is determined by the contents of the manifest file, if present, or if there is no manifest file, `graph` is empty. A manifest file contains a stanza for each direct or indirect dependency of a project, including for each one, its UUID and exact version information and optionally an explicit path to its source code. Consider the following example manifest file for `App`: + +```toml +[[Priv]] # the private one +deps = ["Pub", "Zebra"] +uuid = "ba13f791-ae1d-465a-978b-69c3ad90f72b" +path = "deps/Priv" + +[[Priv]] # the public one +uuid = "2d15fe94-a1f7-436c-a4d8-07a9a496e01c" +git-tree-sha1 = "1bf63d3be994fe83456a03b874b409cfd59a6373" +version = "0.1.5" + +[[Pub]] +uuid = "ba13f791-ae1d-465a-978b-69c3ad90f72b" +git-tree-sha1 = "9ebd50e2b0dd1e110e842df3b433cb5869b0dd38" +version = "2.1.4" + + [Pub.deps] + Priv = "2d15fe94-a1f7-436c-a4d8-07a9a496e01c" + Zebra = "f7a24cb4-21fc-4002-ac70-f0e3a0dd3f62" + +[[Zebra]] +uuid = "f7a24cb4-21fc-4002-ac70-f0e3a0dd3f62" +git-tree-sha1 = "e808e36a5d7173974b90a15a353b564f3494092f" +version = "3.4.2" +``` + +This manifest file describes a possible complete dependency graph for the `App` project: + +- There are two different `Priv` packages that the application needs—a private one which is a direct dependency and a public one which is an indirect dependency through `Pub`: + * The private `Priv` depends on the `Pub` and `Zebra` packages. + * The public `Priv` has no dependencies. +- The application also depends on the `Pub` package, which in turn depends on the public `Priv ` and the same `Zebra` package which the private `Priv` package depends on. + +A materialized representation of this dependency `graph` looks like this: + +```julia +graph = Dict{UUID,Dict{Symbol,UUID}}( + # Priv – the private one: + UUID("ba13f791-ae1d-465a-978b-69c3ad90f72b") => Dict{Symbol,UUID}( + :Zebra => UUID("f7a24cb4-21fc-4002-ac70-f0e3a0dd3f62"), + ), + # Priv – the public one: + UUID("2d15fe94-a1f7-436c-a4d8-07a9a496e01c") => Dict{Symbol,UUID}(), + # Pub: + UUID("ba13f791-ae1d-465a-978b-69c3ad90f72b") => Dict{Symbol,UUID}( + :Priv => UUID("2d15fe94-a1f7-436c-a4d8-07a9a496e01c"), + :Zebra => UUID("f7a24cb4-21fc-4002-ac70-f0e3a0dd3f62"), + ), + # Zebra: + UUID("f7a24cb4-21fc-4002-ac70-f0e3a0dd3f62") => Dict{Symbol,UUID}(), +) +``` + +Given this dependency `graph`, when Julia sees `import Priv` in the `Pub` package—which has UUID `ba13f791-ae1d-465a-978b-69c3ad90f72b`—it looks up: + +```julia +graph[UUID("ba13f791-ae1d-465a-978b-69c3ad90f72b")][:Priv] +``` + +and gets `2d15fe94-a1f7-436c-a4d8-07a9a496e01c` , which indicates that in the context of the `Pub` package, `import Priv` refers to the public `Priv` package, rather than the private one which the app depends on directly. This is how the name `Priv` can refer to different packages in the main project than it does in one of the packages dependencies, which allows for name collisions in the package ecosystem. + +What happens if `import Zebra` is evaluated in the main `App` code base? Since `Zebra` does not appear in the project file, the import will fail even though `Zebra` *does* appear in the manifest file. Moreover, if `import Zebra` occurs in the public `Priv` package—the one with UUID `2d15fe94-a1f7-436c-a4d8-07a9a496e01c`—then that would also fail since that `Priv` package has no declared dependencies in the manifest file and therefore cannot load any packages. The `Zebra` package can only be loaded by packages for which it appear as an explicit dependency in the manifest file: the `Pub` package and one of the `Priv` packages. + +**The paths map** of a project environment is also determined by the manifest file if present and is empty if there is no manifest. The path of a package `uuid` named `X` is determined by these two rules: + +1. If the manifest stanza matching `uuid` has a `path` entry, use that path relative to the manifest file. +2. Otherwise, if the manifest stanza matching `uuid` has a `git-tree-sha1` entry, compute a deterministic hash function of `uuid` and `git-tree-sha1`—call it `slug`—and look for `packages/X/$slug` in each directory in the Julia `DEPOT_PATH` global array. Use the first such directory that exists. + +If applying these rules doesn't find a loadable path, the package should be considered not installed and the system should raise an error or prompt the user to install the appropriate package version. + +In the example manifest file above, to find the path of the first `Priv` package—the one with UUID `ba13f791-ae1d-465a-978b-69c3ad90f72b`—Julia looks for its stanza in the manifest file, sees that it has a `path` entry, looks at `deps/Priv` relative to the `App` project directory—let's suppose the `App` code lives in `/home/me/projects/App`—sees that `/home/me/projects/App/deps/Priv` exists and therefore loads `Priv` from there. + +If, on the other hand, Julia was loading the *other* `Priv` package—the one with UUID `2d15fe94-a1f7-436c-a4d8-07a9a496e01c`—it finds its stanza in the manifest, see that it does *not* have a `path` entry, but that it does have a `git-tree-sha1` entry. It then computes the `slug` for this UUID/SHA-1 pair, which is `HDkr` (the exact details of this computation aren't important, but it is consistent and deterministic). This means that the path to this `Priv` package will be `packages/Priv/HDkr/src/Priv.jl` in one of the package depots. Suppose the contents of `DEPOT_PATH` is `["/users/me/.julia", "/usr/local/julia"]`; then Julia will look at the following paths to see if they exist: + +1. `/home/me/.julia/packages/Priv/HDkr/src/Priv.jl` +2. `/usr/local/julia/packages/Priv/HDkr/src/Priv.jl` + +Julia uses the first of these that exists to load the public `Priv` package. + +Here is a materialized `paths` map for the `App` project environment: + +```julia +paths = Dict{Tuple{UUID,Symbol},String}( + # Priv – the private one: + (UUID("ba13f791-ae1d-465a-978b-69c3ad90f72b"), :Priv) => + # relative entry-point inside `App` repo: + "/home/me/projects/App/deps/Priv/src/Priv.jl", + # Priv – the public one: + (UUID("2d15fe94-a1f7-436c-a4d8-07a9a496e01c"), :Priv) => + # package installed in the user depot: + "/usr/local/julia/packages/Priv/HDkr/src/Priv.jl", + # Pub: + (UUID("ba13f791-ae1d-465a-978b-69c3ad90f72b"), :Pub) => + # package installed in the system depot: + "/home/me/.julia/packages/Pub/oKpw/src/Pub.jl", + # Zebra: + (UUID("f7a24cb4-21fc-4002-ac70-f0e3a0dd3f62"), :Zebra) => + # package installed in the user depot: + "/usr/local/julia/packages/Zebra/me9k/src/Zebra.jl", +) +``` + +This example map includes three different kinds of package locations: + +1. The private `Priv` package is "[vendored](https://stackoverflow.com/a/35109534/659248)" inside of `App` repository. +2. The public `Priv` and `Zebra` packages are in the system depot, where packages installed and managed by the system administrator live. These are available to all users on the system. +3. The `Pub` package is in the user depot, where packages installed by the user live. These are only available to the user who installed them. + +### Package directories + +Package directories provide a kind of environment that approximates package loading in Julia 0.6 and earlier, and which resembles package loading in many other dynamic languages. The set of packages available in a package directory corresponds to the set of subdirectories it contains that look like packages: if `X/src/X.jl` is a file in a package directory, then `X` is considered to be a package and `X/src/X.jl` is the file you load to get `X`. Which packages can "see" each other as dependencies depends on whether they contain project files or not and what appears in the `[deps]` sections of those project files. + +**The roots map** is determined by the subdirectories of a package directory for which `X/src/X.jl` exists and whether `X/Project.toml` exists and has a top-level `uuid` entry. Specifically `:X => uuid` goes in `roots` for each such `X` where `uuid` is defined as: + +1. If `X/Project.toml` exists and has a `uuid` entry, then `uuid` is that value. +2. If `X/Project.toml` exists and but does *not* have a top-level UUID entry, `uuid` is a dummy UUID generated by hashing the canonical path of `X/Project.toml`. +3. If `X/Project.toml` does not exist, then `uuid` is the all-zero [nil UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Nil_UUID). + +**The dependency graph** of a project directory is determined by the presence and contents of project files in the subdirectory of each package. The rules are: + +- If a package subdirectory has no project file, then it is omitted from `graph` and import statements in its code are treated as top-level, the same as the main project and REPL. +- If a package subdirectory has a project file, then the `graph` entry for its UUID is the `[deps]` map of the project file, which is considered to be empty if the section is absent. + +As an example, suppose a package directory has the following structure and content: + +``` +Aardvark/ + src/Aardvark.jl: + import Bobcat + import Cobra + +Bobcat/ + Project.toml: + [deps] + Cobra = "4725e24d-f727-424b-bca0-c4307a3456fa" + Dingo = "7a7925be-828c-4418-bbeb-bac8dfc843bc" + + src/Bobcat.jl: + import Cobra + import Dingo + +Cobra/ + Project.toml: + uuid = "4725e24d-f727-424b-bca0-c4307a3456fa" + [deps] + Dingo = "7a7925be-828c-4418-bbeb-bac8dfc843bc" + + src/Cobra.jl: + import Dingo + +Dingo/ + Project.toml: + uuid = "7a7925be-828c-4418-bbeb-bac8dfc843bc" + + src/Dingo.jl: + # no imports +``` + +Here is a corresponding `roots` structure, materialized as a dictionary: + +```julia +roots = Dict{Symbol,UUID}( + :Aardvark => UUID("00000000-0000-0000-0000-000000000000"), # no project file, nil UUID + :Bobcat => UUID("85ad11c7-31f6-5d08-84db-0a4914d4cadf"), # dummy UUID based on path + :Cobra => UUID("4725e24d-f727-424b-bca0-c4307a3456fa"), # UUID from project file + :Dingo => UUID("7a7925be-828c-4418-bbeb-bac8dfc843bc"), # UUID from project file +) +``` + +Here is the corresponding `graph` structure, materialized as a dictionary: + +```julia +graph = Dict{UUID,Dict{Symbol,UUID}}( + # Bobcat: + UUID("85ad11c7-31f6-5d08-84db-0a4914d4cadf") => Dict{Symbol,UUID}( + :Cobra => UUID("4725e24d-f727-424b-bca0-c4307a3456fa"), + :Dingo => UUID("7a7925be-828c-4418-bbeb-bac8dfc843bc"), + ), + # Cobra: + UUID("4725e24d-f727-424b-bca0-c4307a3456fa") => Dict{Symbol,UUID}( + :Dingo => UUID("7a7925be-828c-4418-bbeb-bac8dfc843bc"), + ), + # Dingo: + UUID("7a7925be-828c-4418-bbeb-bac8dfc843bc") => Dict{Symbol,UUID}(), +) +``` + +A few general rules to note: + +1. A package without a project file can depend on any top-level dependency, and since every package in a package directory is available at the top-level, it can import all packages in the environment. +2. A package with a project file cannot depend on one without a project file since packages with project files can only load packages in `graph` and packages without project files do not appear in `graph`. +3. A package with a project file but no explicit UUID can only be depended on by packages without project files since dummy UUIDs assigned to these packages are strictly internal. + +Observe the following specific instances of these rules in our example: + +* `Aardvark` can import on any of `Bobcat`, `Cobra` or `Dingo`; it does import `Bobcat` and `Cobra`. +* `Bobcat` can and does import both `Cobra` and `Dingo`, which both have project files with UUIDs and are declared as dependencies in `Bobcat`'s `[deps]` section. +* `Bobcat` cannot possibly depend on `Aardvark` since `Aardvark` does not have a project file. +* `Cobra` can and does import `Dingo`, which has a project file and UUID, and is declared as a dependency in `Cobra`'s `[deps]` section. +* `Cobra` cannot depend on `Aardvark` or `Bobcat` since neither have real UUIDs. +* `Dingo` cannot import anything because it has a project file without a `[deps]` section. + +**The paths map** in a package directory is simple: it maps subdirectory names to their corresponding entry-point paths. In other words, if the path to our example project directory is `/home/me/animals` then the `paths` map would be materialized as this dictionary: + +```julia +paths = Dict{Tuple{UUID,Symbol},String}( + (UUID("00000000-0000-0000-0000-000000000000"), :Aardvark) => + "/home/me/AnimalPackages/Aardvark/src/Aardvark.jl", + (UUID("85ad11c7-31f6-5d08-84db-0a4914d4cadf"), :Bobcat) => + "/home/me/AnimalPackages/Bobcat/src/Bobcat.jl", + (UUID("4725e24d-f727-424b-bca0-c4307a3456fa"), :Cobra) => + "/home/me/AnimalPackages/Cobra/src/Cobra.jl", + (UUID("7a7925be-828c-4418-bbeb-bac8dfc843bc"), :Dingo) => + "/home/me/AnimalPackages/Dingo/src/Dingo.jl", +) +``` + +Since all packages in a package directory environment are, by definition, subdirectories with the expected entry-point files, their `paths` map entries always have this form. + +### Environment stacks + +The third and final kind of environment is one that combines other environments by overlaying several of them, making the packages in each available in a single composite environment. These composite environments are called *environment stacks*. The Julia `LOAD_PATH` global defines an environment stack—the environment in which the Julia process operates. If you want your Julia process to have access only to the packages in one project or package directory, make it the only entry in `LOAD_PATH`. It is often quite useful, however, to have access to some of your favorite tools—standard libraries, profilers, debuggers, personal utilities, etc.—even if they are not dependencies of the project you're working on. By pushing an environment containing these tools onto the load path, you immediately have access to them in top-level code without needing to add them to your project. + +The mechanism for combining the `roots`, `graph` and `paths` data structures of the components of an environment stack is simple: they are simply merged as dictionaries, favoring earlier entries over later ones in the case of key collisions. In other words, if we have `stack = [env₁, env₂, …]` then we have: + +```julia +roots = reduce(merge, reverse([roots₁, roots₂, …])) +graph = reduce(merge, reverse([graph₁, graph₂, …])) +paths = reduce(merge, reverse([paths₁, paths₂, …])) +``` + +The subscripted `rootsᵢ`, `graphᵢ` and `pathsᵢ` variables correspond to the subscripted environments, `envᵢ`, contained `stack`. The `reverse` is present because `merge` favors the last argument rather than first when there are collisions between keys in its argument dictionaries. That's all there is to stacked environments. There are a couple of noteworthy features of this design: + +1. The *primary environment*—i.e.the first environment in a stack—is faithfully embedded in a stacked environment. The full dependency graph of the first environment in a stack is guaranteed to be included intact in the stacked environment including the same versions of all dependencies. +2. Packages in non-primary environments can end up using incompatible versions of their dependencies even if their own environments are entirely compatible. This can happen when one of their dependencies is shadowed by a version in an earlier environment in the stack. + +Since the primary environment is typically the environment of a project you're working on, while environments later in the stack contain additional tools, this is the right tradeoff: it's better to break your dev tools but keep the project working. When such incompatibilities occur, you'll typically want to upgrade your dev tools to versions that are compatible with the main project. + +## Conclusion + +Federated package management and precise software reproducibility are difficult but worthy goals in a package system. In combination, these goals lead to a more complex package loading mechanism than most dynamic languages have, but it also yields scalability and reproducibility that is more commonly associated with static languages. Fortunately, most Julia users can remain oblivious to the technical details of code loading and simply use the built-in package manager to add a package `X` to the appropriate project and manifest files and then write `import X` to load `X` without a further thought. diff --git a/codex/manual/control-flow.md b/codex/manual/control-flow.md index 1e60152..1da1ecd 100644 --- a/codex/manual/control-flow.md +++ b/codex/manual/control-flow.md @@ -584,7 +584,7 @@ below all interrupt the normal flow of control. | [`TypeError`](@ref) | | [`UndefRefError`](@ref) | | [`UndefVarError`](@ref) | -| `UnicodeError` | +| [`StringIndexError`](@ref) | For example, the [`sqrt`](@ref) function throws a [`DomainError`](@ref) if applied to a negative real value: @@ -739,8 +739,8 @@ julia> f(-1) It is important to note that in real code computing this function, one would compare `x` to zero instead of catching an exception. The exception is much slower than simply comparing and branching. -`try/catch` statements also allow the `Exception` to be saved in a variable. In this contrived -example, the following example calculates the square root of the second element of `x` if `x` +`try/catch` statements also allow the `Exception` to be saved in a variable. The following +contrived example calculates the square root of the second element of `x` if `x` is indexable, otherwise assumes `x` is a real number and returns its square root: ```jldoctest diff --git a/codex/manual/functions.md b/codex/manual/functions.md index c3adfd3..599a118 100644 --- a/codex/manual/functions.md +++ b/codex/manual/functions.md @@ -460,32 +460,41 @@ call will fail, just as it would if too many arguments were given explicitly. ## Optional Arguments In many cases, function arguments have sensible default values and therefore might not need to -be passed explicitly in every call. For example, the library function [`parse(T, num, base = base)`](@ref) -interprets a string as a number in some base. The `base` argument defaults to `10`. This behavior -can be expressed concisely as: +be passed explicitly in every call. For example, the function [`Date(y, [m, d])`](@ref) +from `Dates` module constructs a `Date` type for a given year `y`, month `m` and day `d`. +However, `m` and `d` arguments are optional and their default value is `1`. +This behavior can be expressed concisely as: ```julia -function parse(T, num; base = 10) - ### +function Date(y::Int64, m::Int64=1, d::Int64=1) + err = validargs(Date, y, m, d) + err === nothing || throw(err) + return Date(UTD(totaldays(y, m, d))) end ``` -With this definition, the function can be called with either two or three arguments, and `10` -is automatically passed when a third argument is not specified: +Observe, that this definition calls another method of `Date` function that takes one argument +of `UTInstant{Day}` type. + +With this definition, the function can be called with either one, two or three arguments, and +`1` is automatically passed when any of the arguments is not specified: ```jldoctest -julia> parse(Int, "12", base = 10) -12 +julia> using Dates -julia> parse(Int, "12", base = 3) -5 +julia> Date(2000, 12, 12) +2000-12-12 + +julia> Date(2000, 12) +2000-12-01 -julia> parse(Int, "12") -12 +julia> Date(2000) +2000-01-01 ``` Optional arguments are actually just a convenient syntax for writing multiple method definitions with different numbers of arguments (see [Note on Optional and keyword Arguments](@ref)). +This can be checked for our `Date` function example by calling `methods` function. ## Keyword Arguments diff --git a/codex/manual/networking-and-streams.md b/codex/manual/networking-and-streams.md index 51b6912..bb86c3b 100644 --- a/codex/manual/networking-and-streams.md +++ b/codex/manual/networking-and-streams.md @@ -186,9 +186,13 @@ julia> open("hello.txt") do f ## A simple TCP example -Let's jump right in with a simple example involving TCP sockets. Let's first create a simple server: +Let's jump right in with a simple example involving TCP sockets. +This functionality is in a standard library package called `Sockets`. +Let's first create a simple server: ```julia-repl +julia> using Sockets + julia> @async begin server = listen(2000) while true @@ -266,7 +270,7 @@ julia> @async begin while true sock = accept(server) @async while isopen(sock) - write(sock,readline(sock)) + write(sock, readline(sock, keep=true)) end end end @@ -275,8 +279,8 @@ Task (runnable) @0x00007fd31dc12e60 julia> clientside = connect(2001) TCPSocket(RawFD(28) open, 0 bytes waiting) -julia> @async while true - write(stdout,readline(clientside)) +julia> @async while isopen(clientside) + write(stdout, readline(clientside, keep=true)) end Task (runnable) @0x00007fd31dc11870 diff --git a/codex/manual/strings.md b/codex/manual/strings.md index 9d49b95..b4c9930 100644 --- a/codex/manual/strings.md +++ b/codex/manual/strings.md @@ -46,7 +46,8 @@ An `Char` value represents a single character: it is just a 32-bit primitive typ representation and appropriate arithmetic behaviors, and which can be converted to a numeric value representing a [Unicode code point](https://en.wikipedia.org/wiki/Code_point). (Julia packages may define - other subtypes of `AbstractChar`, e.g. to optimize operations for other [text encodings](https://en.wikipedia.org/wiki/Character_encoding).) Here is how `Char` values are +other subtypes of `AbstractChar`, e.g. to optimize operations for other +[text encodings](https://en.wikipedia.org/wiki/Character_encoding).) Here is how `Char` values are input and shown: ```jldoctest @@ -599,6 +600,8 @@ Some other useful functions include: * [`lastindex(str)`](@ref) gives the maximal (byte) index that can be used to index into `str`. * [`length(str)`](@ref) the number of characters in `str`. * [`length(str, i, j)`](@ref) the number of valid character indices in `str` from `i` to `j`. + * [`ncodeunits(str)`](@ref) number of [code units](https://en.wikipedia.org/wiki/Character_encoding#Terminology) in a string. + * [`codeunit(str, i)`](@ref) gives the code unit value in the string `str` at index `i`. * [`i = start(str)`](@ref start) gives the first valid index at which a character can be found in `str` (typically 1). * [`c, j = next(str,i)`](@ref next) returns next character at or after the index `i` and the next valid @@ -839,9 +842,10 @@ for regular expressions containing quotation marks or newlines). ## [Byte Array Literals](@id man-byte-array-literals) -Another useful non-standard string literal is the byte-array string literal: `b"..."`. This form -lets you use string notation to express literal byte arrays -- i.e. arrays of -[`UInt8`](@ref) values. The rules for byte array literals are the following: +Another useful non-standard string literal is the byte-array string literal: `b"..."`. This +form lets you use string notation to express read only literal byte arrays -- i.e. arrays of +[`UInt8`](@ref) values. The type of those objects is `CodeUnits{UInt8, String}`. +The rules for byte array literals are the following: * ASCII characters and ASCII escapes produce a single byte. * `\x` and octal escape sequences produce the *byte* corresponding to the escape value. @@ -867,12 +871,35 @@ julia> b"DATA\xff\u2200" The ASCII string "DATA" corresponds to the bytes 68, 65, 84, 65. `\xff` produces the single byte 255. The Unicode escape `\u2200` is encoded in UTF-8 as the three bytes 226, 136, 128. Note that the -resulting byte array does not correspond to a valid UTF-8 string -- if you try to use this as -a regular string literal, you will get a syntax error: +resulting byte array does not correspond to a valid UTF-8 string: -```julia-repl -julia> "DATA\xff\u2200" -ERROR: syntax: invalid UTF-8 sequence +```jldoctest +julia> isvalid("DATA\xff\u2200") +false +``` + +As it was mentioned `CodeUnits{UInt8,String}` type behaves like read only array of `UInt8` and +if you need a standard vector you can convert it using `Vector{UInt8}`: + +```jldoctest +julia> x = b"123" +3-element Base.CodeUnits{UInt8,String}: + 0x31 + 0x32 + 0x33 + +julia> x[1] +0x31 + +julia> x[1] = 0x32 +ERROR: setindex! not defined for Base.CodeUnits{UInt8,String} +[...] + +julia> Vector{UInt8}(x) +3-element Array{UInt8,1}: + 0x31 + 0x32 + 0x33 ``` Also observe the significant distinction between `\xff` and `\uff`: the former escape sequence diff --git a/codex/manual/types.md b/codex/manual/types.md index 1a7d849..3527f19 100644 --- a/codex/manual/types.md +++ b/codex/manual/types.md @@ -622,8 +622,8 @@ function norm(p::Point{<:Real}) end ``` -(Equivalently, one could define `function norm{T<:Real}(p::Point{T})` or -`function norm(p::Point{T} where T<:Real)`; see [UnionAll Types](@ref).) +(Equivalently, one could define `function norm(p::Point{T} where T<:Real)` or +`function norm(p::Point{T}) where T<:Real`; see [UnionAll Types](@ref).) More examples will be discussed later in [Methods](@ref). diff --git a/codex/manual/variables-and-scoping.md b/codex/manual/variables-and-scoping.md index 5e769ca..45a150f 100644 --- a/codex/manual/variables-and-scoping.md +++ b/codex/manual/variables-and-scoping.md @@ -489,5 +489,85 @@ not supported. Special top-level assignments, such as those performed by the `function` and `struct` keywords, are constant by default. -Note that `const` only affects the variable binding; the variable may be bound to a mutable object -(such as an array), and that object may still be modified. +Note that `const` only affects the variable binding; the variable may be bound to a mutable +object (such as an array), and that object may still be modified. Additionally when one tries +to assign a value a variable that is declared constant the following scenarios are possible: + +* if a new value has a different type than the type of the constant then an error is thrown: +```jldoctest +julia> const x = 1.0 +1.0 + +julia> x = 1 +ERROR: invalid redefinition of constant x +``` +* if a new value has the same type as the constant then a warning is printed: +```jldoctest +julia> const y = 1.0 +1.0 + +julia> y = 2.0 +WARNING: redefining constant y +2.0 +``` +* if an assignment would not result in the change of variable value no message is given: +```jldoctest +julia> const z = 100 +100 + +julia> z = 100 +100 +``` +The last rule applies for immutable objects even if the vairable binding would change, e.g.: +```julia-repl +julia> const s1 = "1" +"1" + +julia> s2 = "1" +"1" + +julia> pointer.([s1, s2], 1) +2-element Array{Ptr{UInt8},1}: + Ptr{UInt8} @0x00000000132c9638 + Ptr{UInt8} @0x0000000013dd3d18 + +julia> s1 = s2 +"1" + +julia> pointer.([s1, s2], 1) +2-element Array{Ptr{UInt8},1}: + Ptr{UInt8} @0x0000000013dd3d18 + Ptr{UInt8} @0x0000000013dd3d18 +``` +However, for mutable objects the warning is printed as expected: +```jldoctest +julia> const a = [1] +1-element Array{Int64,1}: + 1 + +julia> a = [1] +WARNING: redefining constant a +1-element Array{Int64,1}: + 1 +``` + +Note that although possible, changing the value of a variable that is declared as constant +is strongly discouraged. For instance, if a method references a constant and is already +compiled before the constant is changed then it might keep using the old value: +```jldoctest +julia> const x = 1 +1 + +julia> f() = x +f (generic function with 1 method) + +julia> f() +1 + +julia> x = 2 +WARNING: redefining constant x +2 + +julia> f() +1 +``` diff --git a/codex/stdlib/LibGit2.md b/codex/stdlib/LibGit2.md new file mode 100644 index 0000000..20fd2b4 --- /dev/null +++ b/codex/stdlib/LibGit2.md @@ -0,0 +1,168 @@ +# LibGit2 + +```@meta +DocTestSetup = :(using LibGit2) +``` + +The LibGit2 module provides bindings to [libgit2](https://libgit2.github.com/), a portable C library that +implements core functionality for the [Git](https://git-scm.com/) version control system. +These bindings are currently used to power Julia's package manager. +It is expected that this module will eventually be moved into a separate package. + +### Functionality + +Some of this documentation assumes some prior knowledge of the libgit2 API. +For more information on some of the objects and methods referenced here, consult the upstream +[libgit2 API reference](https://libgit2.github.com/libgit2/#v0.25.1). + +```@docs +LibGit2.Buffer +LibGit2.CheckoutOptions +LibGit2.CloneOptions +LibGit2.DescribeOptions +LibGit2.DescribeFormatOptions +LibGit2.DiffDelta +LibGit2.DiffFile +LibGit2.DiffOptionsStruct +LibGit2.FetchHead +LibGit2.FetchOptions +LibGit2.GitAnnotated +LibGit2.GitBlame +LibGit2.GitBlob +LibGit2.GitCommit +LibGit2.GitHash +LibGit2.GitObject +LibGit2.GitRemote +LibGit2.GitRemoteAnon +LibGit2.GitRepo +LibGit2.GitRepoExt +LibGit2.GitRevWalker +LibGit2.GitShortHash +LibGit2.GitSignature +LibGit2.GitStatus +LibGit2.GitTag +LibGit2.GitTree +LibGit2.IndexEntry +LibGit2.IndexTime +LibGit2.BlameOptions +LibGit2.MergeOptions +LibGit2.ProxyOptions +LibGit2.PushOptions +LibGit2.RebaseOperation +LibGit2.RebaseOptions +LibGit2.RemoteCallbacks +LibGit2.SignatureStruct +LibGit2.StatusEntry +LibGit2.StatusOptions +LibGit2.StrArrayStruct +LibGit2.TimeStruct +LibGit2.add! +LibGit2.add_fetch! +LibGit2.add_push! +LibGit2.addblob! +LibGit2.author +LibGit2.authors +LibGit2.branch +LibGit2.branch! +LibGit2.checkout! +LibGit2.clone +LibGit2.commit +LibGit2.committer +LibGit2.count(::Function, ::LibGit2.GitRevWalker; ::LibGit2.GitHash, ::Cint, ::Bool) +LibGit2.counthunks +LibGit2.create_branch +LibGit2.credentials_callback +LibGit2.credentials_cb +LibGit2.default_signature +LibGit2.delete_branch +LibGit2.diff_files +LibGit2.entryid +LibGit2.entrytype +LibGit2.fetch +LibGit2.fetchheads +LibGit2.fetch_refspecs +LibGit2.fetchhead_foreach_cb +LibGit2.merge_base +LibGit2.merge!(::LibGit2.GitRepo; ::Any...) +LibGit2.merge!(::LibGit2.GitRepo, ::Vector{LibGit2.GitAnnotated}; ::LibGit2.MergeOptions, ::LibGit2.CheckoutOptions) +LibGit2.merge!(::LibGit2.GitRepo, ::Vector{LibGit2.GitAnnotated}, ::Bool; ::LibGit2.MergeOptions, ::LibGit2.CheckoutOptions) +LibGit2.ffmerge! +LibGit2.fullname +LibGit2.features +LibGit2.filename +LibGit2.filemode +LibGit2.gitdir +LibGit2.git_url +LibGit2.@githash_str +LibGit2.head +LibGit2.head! +LibGit2.head_oid +LibGit2.headname +LibGit2.init +LibGit2.is_ancestor_of +LibGit2.isbinary +LibGit2.iscommit +LibGit2.isdiff +LibGit2.isdirty +LibGit2.isorphan +LibGit2.isset +LibGit2.iszero +LibGit2.lookup_branch +LibGit2.map(::Function, ::LibGit2.GitRevWalker; ::LibGit2.GitHash, ::AbstractString, ::Cint, ::Bool) +LibGit2.mirror_callback +LibGit2.mirror_cb +LibGit2.message +LibGit2.merge_analysis +LibGit2.name +LibGit2.need_update +LibGit2.objtype +LibGit2.path +LibGit2.peel +LibGit2.posixpath +LibGit2.push +LibGit2.push!(::LibGit2.GitRevWalker, ::LibGit2.GitHash) +LibGit2.push_head! +LibGit2.push_refspecs +LibGit2.raw +LibGit2.read_tree! +LibGit2.rebase! +LibGit2.ref_list +LibGit2.reftype +LibGit2.remotes +LibGit2.remove! +LibGit2.reset +LibGit2.reset! +LibGit2.restore +LibGit2.revcount +LibGit2.set_remote_url +LibGit2.shortname +LibGit2.snapshot +LibGit2.status +LibGit2.stage +LibGit2.tag_create +LibGit2.tag_delete +LibGit2.tag_list +LibGit2.target +LibGit2.toggle +LibGit2.transact +LibGit2.treewalk +LibGit2.upstream +LibGit2.update! +LibGit2.url +LibGit2.version +LibGit2.with +LibGit2.with_warn +LibGit2.workdir +LibGit2.GitObject(::LibGit2.GitTreeEntry) +LibGit2.UserPasswordCredential +LibGit2.SSHCredential +LibGit2.isfilled +LibGit2.CachedCredentials +LibGit2.CredentialPayload +LibGit2.approve +LibGit2.reject +``` + +```@meta +DocTestSetup = nothing +``` diff --git a/make.jl b/make.jl index 52f9be4..28f5bfa 100644 --- a/make.jl +++ b/make.jl @@ -63,6 +63,7 @@ const PAGES = [ "manual/environment-variables.md", "manual/embedding.md", "manual/packages.md", + "manual/code-loading.md", "manual/profile.md", "manual/stacktraces.md", "manual/performance-tips.md", diff --git a/src/NEWS.md b/src/NEWS.md index 784e1ee..c2bafec 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -218,7 +218,7 @@ This section lists changes that do not have deprecation warnings. * `countlines` now always counts the last non-empty line even if it does not end with EOL, matching the behavior of `eachline` and `readlines` ([#25845](https://github.com/JuliaLang/julia/issues/25845)). - * `getindex(s::String, r::UnitRange{Int})` now throws `UnicodeError` if `last(r)` + * `getindex(s::String, r::UnitRange{Int})` now throws `StringIndexError` if `last(r)` is not a valid index into `s` ([#22572](https://github.com/JuliaLang/julia/issues/22572)). * `ntuple(f, n::Integer)` throws `ArgumentError` if `n` is negative. @@ -745,6 +745,16 @@ Deprecated or removed necessary, consider `fill!(similar(A[, opts...]), {one(eltype(A)) | zero(eltype(A))})`. For an algebraic multiplicative identity, consider `one(A)` ([#24656](https://github.com/JuliaLang/julia/issues/24656)). + * The `similar(dims->f(..., dims...), [T], axes...)` method to add offset array support + to a function `f` that would otherwise create a non-offset array has been deprecated. + Instead, call `f(..., axes...)` directly and, if needed, the offset array implementation + should add offset axis support to the function `f` directly ([#26733](https://github.com/JuliaLang/julia/issues/26733)). + + * The functions `ones` and `zeros` used to accept any objects as dimensional arguments, + implicitly converting them to `Int`s. This is now deprecated; only `Integer`s or + `AbstractUnitRange`s are accepted as arguments. Instead, convert the arguments before + calling `ones` or `zeros` ([#26733](https://github.com/JuliaLang/julia/issues/26733)). + * The `Operators` module is deprecated. Instead, import required operators explicitly from `Base`, e.g. `import Base: +, -, *, /` ([#22251](https://github.com/JuliaLang/julia/issues/22251)). diff --git a/src/base/base.md b/src/base/base.md index f9a8354..1839bb8 100644 --- a/src/base/base.md +++ b/src/base/base.md @@ -295,6 +295,7 @@ Core.TypeError Core.UndefKeywordError Core.UndefRefError Core.UndefVarError +Base.StringIndexError Base.InitError Base.retry Base.ExponentialBackOff diff --git a/src/manual/code-loading.md b/src/manual/code-loading.md new file mode 100644 index 0000000..216e05e --- /dev/null +++ b/src/manual/code-loading.md @@ -0,0 +1,330 @@ +# Code Loading + +Julia has two mechanisms for loading code: + +1. **Code inclusion:** e.g. `include("source.jl")`. Inclusion allows you to split a single program across multiple source files. The expression `include("source.jl")` causes the contents of the file `source.jl` to be evaluated inside of the module where the `include` call occurs. If `include("source.jl")` is called multiple times, `source.jl` is evaluated multiple times. The included path, `source.jl`, is interpreted relative to the file where the `include` call occurs. This makes it simple to relocate a subtree of source files. In the REPL, included paths are interpreted relative to the current working directory, `pwd()`. +2. **Package loading:** e.g. `import X` or `using X`. The import mechanism allows you to load a package—i.e. an independent, reusable collection of Julia code, wrapped in a module—and makes the resulting module available by the name `X` inside of the importing module. If the same `X` package is imported multiple times in the same Julia session, it is only loaded the first time—on subsequent imports, the importing module gets a reference to the same module. It should be noted, however, that `import X` can load different packages in different contexts: `X` can refer to one package named `X` in the main project but potentially different packages named `X` in each dependency. More on this below. + +Code inclusion is quite straightforward: it simply parses and evaluates a source file in the context of the caller. Package loading is built on top of code inclusion and is quite a bit more complex. The rest of this chapter, therefore, focuses on the behavior and mechanics of package loading. + +!!! note + You only need to read this chapter if you want to understand the technical details of package loading in Julia. If you just want to install and use packages, simply use Julia's built-in package manager to add packages to your environment and write `import X` or `using X` in your code to load packages that you've added. + +A *package* is a source tree with a standard layout providing functionality that can be reused by other Julia projects. A package is loaded by `import X` or `using X` statements. These statements also make the module named `X`, which results from loading the package code, available within the module where the import statement occurs. The meaning of `X` in `import X` is context-dependent: which `X` package is loaded depends on what code the statement occurs in. The effect of `import X` depends on two questions: + +1. **What** package is `X` in this context? +2. **Where** can that `X` package be found? + +Understanding how Julia answers these questions is key to understanding package loading. + +## Federation of packages + +Julia supports federated management of packages. This means that multiple independent parties can maintain both public and private packages and registries of them, and that projects can depend on a mix of public and private packages from different registries. Packages from various registries are installed and managed using a common set of tools and workflows. The Pkg3 next-generation package manager [[docs](https://julialang.org/Pkg3.jl/latest/), [repo](https://github.com/JuliaLang/Pkg3.jl)] ships with Julia 0.7/1.0 and lets you install and manage dependencies of your projects, by creating and manipulating project files, which describe what your project depends on, and manifest files that snapshot exact versions of your project's complete dependency graph. + +One consequence of federation is that there cannot be a central authority for package naming. Different entities may use the same name to refer to unrelated packages. This possibility is unavoidable since these entities do not coordinate and may not even know about each other. Because of the lack of a central naming authority, a single project can quite possibly end up depending on different packages with the same name. Julia's package loading mechanism handles this by not requiring package names to be globally unique, even within the dependency graph of a single project. Instead, packages are identified by [universally unique identifiers](https://en.wikipedia.org/wiki/Universally_unique_identifier) (UUIDs) which are assigned to them before they are registered. The question *"what is `X`?"* is answered by determining the UUID of `X`. + +Since the decentralized naming problem is somewhat abstract, it may help to walk through a concrete scenario to understand the issue. Suppose you're developing an application called `App`, which uses two packages: `Pub` and `Priv`. `Priv` is a private package that you created, whereas `Pub` is a public package that you use but don't control. When you created `Priv`, there was no public package by that name. Subsequently, however, an unrelated package also named `Priv` has been published and become popular. In fact, the `Pub` package has started to use it. Therefore, when you next upgrade `Pub` to get the latest bug fixes and features, `App` will end up—through no action of yours other than upgrading—depending on two different packages named `Priv`. `App` has a direct dependency on your private `Priv` package, and an indirect dependency, through `Pub`, on the new public `Priv` package. Since these two `Priv` packages are different but both required for `App` to continue working correctly, the expression `import Priv` must refer to different `Priv` packages depending on whether it occurs in `App`'s code or in `Pub`'s code. Julia's package loading mechanism allows this by distinguishing the two `Priv` packages by context and UUID. How this distinction works is determined by environments, as explained in the following sections. + +## Environments + +An *environment* determines what `import X` and `using X` mean in various code contexts and what files these statements cause to be loaded. Julia understands three kinds of environments: + +1. **A project environment** is a directory with a project file and an optional manifest file. The project file determines what the names and identities of the direct dependencies of a project are. The manifest file, if present, gives a complete dependency graph, including all direct and indirect dependencies, exact versions of each dependency, and sufficient information to locate and load the correct version. +2. **A package directory** is a directory containing the source trees of a set of packages as subdirectories. This kind of environment was the only kind that existed in Julia 0.6 and earlier. If `X` is a subdirectory of a package directory and `X/src/X.jl` exists, then the package `X` is available in the package directory environment and `X/src/X.jl` is the source file by which it is loaded. +3. **A stacked environment** is an ordered set of project environments and package directories, overlaid to make a single composite environment in which all the packages available in its constituent environments are available. Julia's load path is a stacked environment, for example. + +These three kinds of environment each serve a different purpose: + +* Project environments provide **reproducibility.** By checking a project environment into version control—i.e. a git repository—along with the rest of the project's source code, you can reproduce the exact state of the project _and_ all of its dependencies since the manifest file captures the exact version of every dependency and can be rematerialized easily. +* Package directories provide low-overhead **convenience** when a project environment would be overkill: are handy when you have a set of packages and just want to put them somewhere and use them as they are without having to create and maintain a project environment for them. +* Stacked environments allow for **augmentation** of the primary environment with additional tools. You can push an environment including development tools onto the stack and they will be available from the REPL and scripts but not from inside of packages. + +As an abstraction, an environment provides three maps: `roots`, `graph` and `paths`. When resolving the meaning of `import X`, `roots` and `graph` are used to determine the identity of `X` and answer the question *"what is `X`?"*, while the `paths` map is used to locate the source code of `X` and answer the question *"where is `X`?"* The specific roles of the three maps are: + +- **roots:** `name::Symbol` ⟶ `uuid::UUID` + + An environment's `roots` map assigns package names to UUIDs for all the top-level dependencies that the environment makes available to the main project (i.e. the ones that can be loaded in `Main`). When Julia encounters `import X` in the main project, it looks up the identity of `X` as `roots[:X]`. + +- **graph:** `context::UUID` ⟶ `name::Symbol` ⟶ `uuid::UUID` + + An environment's `graph` is a multilevel map which assigns, for each `context` UUID, a map from names to UUIDs, similar to the `roots` map but specific to that `context`. When Julia sees `import X` in the code of the package whose UUID is `context`, it looks up the identity of `X` as `graph[context][:X]`. In particular, this means that `import X` can refer to different packages depending on `context`. + +- **paths:** `uuid::UUID` × `name::Symbol` ⟶ `path::String` + + The `paths` map assigns to each package UUID-name pair, the location of the entry-point source file of that package. After the identity of `X` in `import X` has been resolved to a UUID via `roots` or `graph` (depending on whether it is loaded from the main project or an dependency), Julia determines what file to load to acquire `X` by looking up `paths[uuid,:X]` in the environment. Including this file should create a module named `X`. After the first time this package is loaded, any import resolving to the same `uuid` will simply create a new binding to the same already-loaded package module. + +Each kind of environment defines these three maps differently, as detailed in the following sections. + +!!! note + For clarity of exposition, the examples throughout this chapter include fully materialized data structures for `roots`, `graph` and `paths`. However, these maps are really only abstractions—for efficiency, Julia's package loading code does not actually materialize them. Instead, it queries them through internal APIs and lazily computes only as much of each structure as is necessary to load a given package. + +### Project environments + +A project environment is determined by a directory containing a project file, `Project.toml`, and optionally a manifest file, `Manifest.toml`. These files can also be named `JuliaProject.toml` and `JuliaManifest.toml`, in which case `Project.toml` and `Manifest.toml` are ignored; this allows for coexistence with other tools that might consider files named `Project.toml` and `Manifest.toml` significant. For pure Julia projects, however, the names `Project.toml` and `Manifest.toml` should be preferred. The `roots`, `graph` and `paths` maps of a project environment are defined as follows. + +**The roots map** of the environment is determined by the contents of the project file, specifically, its top-level `name` and `uuid` entries and its `[deps]` section (all optional). Consider the following example project file for the hypothetical application, `App`, as described above: + +```toml +name = "App" +uuid = "8f986787-14fe-4607-ba5d-fbff2944afa9" + +[deps] +Priv = "ba13f791-ae1d-465a-978b-69c3ad90f72b" +Pub = "c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1" +``` + +This project file implies the following `roots` map, if it were materialized as a Julia dictionary: + +```julia +roots = Dict( + :App => UUID("8f986787-14fe-4607-ba5d-fbff2944afa9"), + :Priv => UUID("ba13f791-ae1d-465a-978b-69c3ad90f72b"), + :Pub => UUID("c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1"), +) +``` + +Given this `roots` map, in the code of `App` the statement `import Priv` will cause Julia to look up `roots[:Priv]`, which yields `ba13f791-ae1d-465a-978b-69c3ad90f72b`, the UUID of the `Priv` package that is to be loaded in that context. This UUID identifies which `Priv` package to load and use when the main application evaluates `import Priv`. + +**The dependency graph** of a project environment is determined by the contents of the manifest file, if present, or if there is no manifest file, `graph` is empty. A manifest file contains a stanza for each direct or indirect dependency of a project, including for each one, its UUID and exact version information and optionally an explicit path to its source code. Consider the following example manifest file for `App`: + +```toml +[[Priv]] # the private one +deps = ["Pub", "Zebra"] +uuid = "ba13f791-ae1d-465a-978b-69c3ad90f72b" +path = "deps/Priv" + +[[Priv]] # the public one +uuid = "2d15fe94-a1f7-436c-a4d8-07a9a496e01c" +git-tree-sha1 = "1bf63d3be994fe83456a03b874b409cfd59a6373" +version = "0.1.5" + +[[Pub]] +uuid = "ba13f791-ae1d-465a-978b-69c3ad90f72b" +git-tree-sha1 = "9ebd50e2b0dd1e110e842df3b433cb5869b0dd38" +version = "2.1.4" + + [Pub.deps] + Priv = "2d15fe94-a1f7-436c-a4d8-07a9a496e01c" + Zebra = "f7a24cb4-21fc-4002-ac70-f0e3a0dd3f62" + +[[Zebra]] +uuid = "f7a24cb4-21fc-4002-ac70-f0e3a0dd3f62" +git-tree-sha1 = "e808e36a5d7173974b90a15a353b564f3494092f" +version = "3.4.2" +``` + +This manifest file describes a possible complete dependency graph for the `App` project: + +- There are two different `Priv` packages that the application needs—a private one which is a direct dependency and a public one which is an indirect dependency through `Pub`: + * The private `Priv` depends on the `Pub` and `Zebra` packages. + * The public `Priv` has no dependencies. +- The application also depends on the `Pub` package, which in turn depends on the public `Priv ` and the same `Zebra` package which the private `Priv` package depends on. + +A materialized representation of this dependency `graph` looks like this: + +```julia +graph = Dict{UUID,Dict{Symbol,UUID}}( + # Priv – the private one: + UUID("ba13f791-ae1d-465a-978b-69c3ad90f72b") => Dict{Symbol,UUID}( + :Zebra => UUID("f7a24cb4-21fc-4002-ac70-f0e3a0dd3f62"), + ), + # Priv – the public one: + UUID("2d15fe94-a1f7-436c-a4d8-07a9a496e01c") => Dict{Symbol,UUID}(), + # Pub: + UUID("ba13f791-ae1d-465a-978b-69c3ad90f72b") => Dict{Symbol,UUID}( + :Priv => UUID("2d15fe94-a1f7-436c-a4d8-07a9a496e01c"), + :Zebra => UUID("f7a24cb4-21fc-4002-ac70-f0e3a0dd3f62"), + ), + # Zebra: + UUID("f7a24cb4-21fc-4002-ac70-f0e3a0dd3f62") => Dict{Symbol,UUID}(), +) +``` + +Given this dependency `graph`, when Julia sees `import Priv` in the `Pub` package—which has UUID `ba13f791-ae1d-465a-978b-69c3ad90f72b`—it looks up: + +```julia +graph[UUID("ba13f791-ae1d-465a-978b-69c3ad90f72b")][:Priv] +``` + +and gets `2d15fe94-a1f7-436c-a4d8-07a9a496e01c` , which indicates that in the context of the `Pub` package, `import Priv` refers to the public `Priv` package, rather than the private one which the app depends on directly. This is how the name `Priv` can refer to different packages in the main project than it does in one of the packages dependencies, which allows for name collisions in the package ecosystem. + +What happens if `import Zebra` is evaluated in the main `App` code base? Since `Zebra` does not appear in the project file, the import will fail even though `Zebra` *does* appear in the manifest file. Moreover, if `import Zebra` occurs in the public `Priv` package—the one with UUID `2d15fe94-a1f7-436c-a4d8-07a9a496e01c`—then that would also fail since that `Priv` package has no declared dependencies in the manifest file and therefore cannot load any packages. The `Zebra` package can only be loaded by packages for which it appear as an explicit dependency in the manifest file: the `Pub` package and one of the `Priv` packages. + +**The paths map** of a project environment is also determined by the manifest file if present and is empty if there is no manifest. The path of a package `uuid` named `X` is determined by these two rules: + +1. If the manifest stanza matching `uuid` has a `path` entry, use that path relative to the manifest file. +2. Otherwise, if the manifest stanza matching `uuid` has a `git-tree-sha1` entry, compute a deterministic hash function of `uuid` and `git-tree-sha1`—call it `slug`—and look for `packages/X/$slug` in each directory in the Julia `DEPOT_PATH` global array. Use the first such directory that exists. + +If applying these rules doesn't find a loadable path, the package should be considered not installed and the system should raise an error or prompt the user to install the appropriate package version. + +In the example manifest file above, to find the path of the first `Priv` package—the one with UUID `ba13f791-ae1d-465a-978b-69c3ad90f72b`—Julia looks for its stanza in the manifest file, sees that it has a `path` entry, looks at `deps/Priv` relative to the `App` project directory—let's suppose the `App` code lives in `/home/me/projects/App`—sees that `/home/me/projects/App/deps/Priv` exists and therefore loads `Priv` from there. + +If, on the other hand, Julia was loading the *other* `Priv` package—the one with UUID `2d15fe94-a1f7-436c-a4d8-07a9a496e01c`—it finds its stanza in the manifest, see that it does *not* have a `path` entry, but that it does have a `git-tree-sha1` entry. It then computes the `slug` for this UUID/SHA-1 pair, which is `HDkr` (the exact details of this computation aren't important, but it is consistent and deterministic). This means that the path to this `Priv` package will be `packages/Priv/HDkr/src/Priv.jl` in one of the package depots. Suppose the contents of `DEPOT_PATH` is `["/users/me/.julia", "/usr/local/julia"]`; then Julia will look at the following paths to see if they exist: + +1. `/home/me/.julia/packages/Priv/HDkr/src/Priv.jl` +2. `/usr/local/julia/packages/Priv/HDkr/src/Priv.jl` + +Julia uses the first of these that exists to load the public `Priv` package. + +Here is a materialized `paths` map for the `App` project environment: + +```julia +paths = Dict{Tuple{UUID,Symbol},String}( + # Priv – the private one: + (UUID("ba13f791-ae1d-465a-978b-69c3ad90f72b"), :Priv) => + # relative entry-point inside `App` repo: + "/home/me/projects/App/deps/Priv/src/Priv.jl", + # Priv – the public one: + (UUID("2d15fe94-a1f7-436c-a4d8-07a9a496e01c"), :Priv) => + # package installed in the user depot: + "/usr/local/julia/packages/Priv/HDkr/src/Priv.jl", + # Pub: + (UUID("ba13f791-ae1d-465a-978b-69c3ad90f72b"), :Pub) => + # package installed in the system depot: + "/home/me/.julia/packages/Pub/oKpw/src/Pub.jl", + # Zebra: + (UUID("f7a24cb4-21fc-4002-ac70-f0e3a0dd3f62"), :Zebra) => + # package installed in the user depot: + "/usr/local/julia/packages/Zebra/me9k/src/Zebra.jl", +) +``` + +This example map includes three different kinds of package locations: + +1. The private `Priv` package is "[vendored](https://stackoverflow.com/a/35109534/659248)" inside of `App` repository. +2. The public `Priv` and `Zebra` packages are in the system depot, where packages installed and managed by the system administrator live. These are available to all users on the system. +3. The `Pub` package is in the user depot, where packages installed by the user live. These are only available to the user who installed them. + +### Package directories + +Package directories provide a kind of environment that approximates package loading in Julia 0.6 and earlier, and which resembles package loading in many other dynamic languages. The set of packages available in a package directory corresponds to the set of subdirectories it contains that look like packages: if `X/src/X.jl` is a file in a package directory, then `X` is considered to be a package and `X/src/X.jl` is the file you load to get `X`. Which packages can "see" each other as dependencies depends on whether they contain project files or not and what appears in the `[deps]` sections of those project files. + +**The roots map** is determined by the subdirectories of a package directory for which `X/src/X.jl` exists and whether `X/Project.toml` exists and has a top-level `uuid` entry. Specifically `:X => uuid` goes in `roots` for each such `X` where `uuid` is defined as: + +1. If `X/Project.toml` exists and has a `uuid` entry, then `uuid` is that value. +2. If `X/Project.toml` exists and but does *not* have a top-level UUID entry, `uuid` is a dummy UUID generated by hashing the canonical path of `X/Project.toml`. +3. If `X/Project.toml` does not exist, then `uuid` is the all-zero [nil UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Nil_UUID). + +**The dependency graph** of a project directory is determined by the presence and contents of project files in the subdirectory of each package. The rules are: + +- If a package subdirectory has no project file, then it is omitted from `graph` and import statements in its code are treated as top-level, the same as the main project and REPL. +- If a package subdirectory has a project file, then the `graph` entry for its UUID is the `[deps]` map of the project file, which is considered to be empty if the section is absent. + +As an example, suppose a package directory has the following structure and content: + +``` +Aardvark/ + src/Aardvark.jl: + import Bobcat + import Cobra + +Bobcat/ + Project.toml: + [deps] + Cobra = "4725e24d-f727-424b-bca0-c4307a3456fa" + Dingo = "7a7925be-828c-4418-bbeb-bac8dfc843bc" + + src/Bobcat.jl: + import Cobra + import Dingo + +Cobra/ + Project.toml: + uuid = "4725e24d-f727-424b-bca0-c4307a3456fa" + [deps] + Dingo = "7a7925be-828c-4418-bbeb-bac8dfc843bc" + + src/Cobra.jl: + import Dingo + +Dingo/ + Project.toml: + uuid = "7a7925be-828c-4418-bbeb-bac8dfc843bc" + + src/Dingo.jl: + # no imports +``` + +Here is a corresponding `roots` structure, materialized as a dictionary: + +```julia +roots = Dict{Symbol,UUID}( + :Aardvark => UUID("00000000-0000-0000-0000-000000000000"), # no project file, nil UUID + :Bobcat => UUID("85ad11c7-31f6-5d08-84db-0a4914d4cadf"), # dummy UUID based on path + :Cobra => UUID("4725e24d-f727-424b-bca0-c4307a3456fa"), # UUID from project file + :Dingo => UUID("7a7925be-828c-4418-bbeb-bac8dfc843bc"), # UUID from project file +) +``` + +Here is the corresponding `graph` structure, materialized as a dictionary: + +```julia +graph = Dict{UUID,Dict{Symbol,UUID}}( + # Bobcat: + UUID("85ad11c7-31f6-5d08-84db-0a4914d4cadf") => Dict{Symbol,UUID}( + :Cobra => UUID("4725e24d-f727-424b-bca0-c4307a3456fa"), + :Dingo => UUID("7a7925be-828c-4418-bbeb-bac8dfc843bc"), + ), + # Cobra: + UUID("4725e24d-f727-424b-bca0-c4307a3456fa") => Dict{Symbol,UUID}( + :Dingo => UUID("7a7925be-828c-4418-bbeb-bac8dfc843bc"), + ), + # Dingo: + UUID("7a7925be-828c-4418-bbeb-bac8dfc843bc") => Dict{Symbol,UUID}(), +) +``` + +A few general rules to note: + +1. A package without a project file can depend on any top-level dependency, and since every package in a package directory is available at the top-level, it can import all packages in the environment. +2. A package with a project file cannot depend on one without a project file since packages with project files can only load packages in `graph` and packages without project files do not appear in `graph`. +3. A package with a project file but no explicit UUID can only be depended on by packages without project files since dummy UUIDs assigned to these packages are strictly internal. + +Observe the following specific instances of these rules in our example: + +* `Aardvark` can import on any of `Bobcat`, `Cobra` or `Dingo`; it does import `Bobcat` and `Cobra`. +* `Bobcat` can and does import both `Cobra` and `Dingo`, which both have project files with UUIDs and are declared as dependencies in `Bobcat`'s `[deps]` section. +* `Bobcat` cannot possibly depend on `Aardvark` since `Aardvark` does not have a project file. +* `Cobra` can and does import `Dingo`, which has a project file and UUID, and is declared as a dependency in `Cobra`'s `[deps]` section. +* `Cobra` cannot depend on `Aardvark` or `Bobcat` since neither have real UUIDs. +* `Dingo` cannot import anything because it has a project file without a `[deps]` section. + +**The paths map** in a package directory is simple: it maps subdirectory names to their corresponding entry-point paths. In other words, if the path to our example project directory is `/home/me/animals` then the `paths` map would be materialized as this dictionary: + +```julia +paths = Dict{Tuple{UUID,Symbol},String}( + (UUID("00000000-0000-0000-0000-000000000000"), :Aardvark) => + "/home/me/AnimalPackages/Aardvark/src/Aardvark.jl", + (UUID("85ad11c7-31f6-5d08-84db-0a4914d4cadf"), :Bobcat) => + "/home/me/AnimalPackages/Bobcat/src/Bobcat.jl", + (UUID("4725e24d-f727-424b-bca0-c4307a3456fa"), :Cobra) => + "/home/me/AnimalPackages/Cobra/src/Cobra.jl", + (UUID("7a7925be-828c-4418-bbeb-bac8dfc843bc"), :Dingo) => + "/home/me/AnimalPackages/Dingo/src/Dingo.jl", +) +``` + +Since all packages in a package directory environment are, by definition, subdirectories with the expected entry-point files, their `paths` map entries always have this form. + +### Environment stacks + +The third and final kind of environment is one that combines other environments by overlaying several of them, making the packages in each available in a single composite environment. These composite environments are called *environment stacks*. The Julia `LOAD_PATH` global defines an environment stack—the environment in which the Julia process operates. If you want your Julia process to have access only to the packages in one project or package directory, make it the only entry in `LOAD_PATH`. It is often quite useful, however, to have access to some of your favorite tools—standard libraries, profilers, debuggers, personal utilities, etc.—even if they are not dependencies of the project you're working on. By pushing an environment containing these tools onto the load path, you immediately have access to them in top-level code without needing to add them to your project. + +The mechanism for combining the `roots`, `graph` and `paths` data structures of the components of an environment stack is simple: they are simply merged as dictionaries, favoring earlier entries over later ones in the case of key collisions. In other words, if we have `stack = [env₁, env₂, …]` then we have: + +```julia +roots = reduce(merge, reverse([roots₁, roots₂, …])) +graph = reduce(merge, reverse([graph₁, graph₂, …])) +paths = reduce(merge, reverse([paths₁, paths₂, …])) +``` + +The subscripted `rootsᵢ`, `graphᵢ` and `pathsᵢ` variables correspond to the subscripted environments, `envᵢ`, contained `stack`. The `reverse` is present because `merge` favors the last argument rather than first when there are collisions between keys in its argument dictionaries. That's all there is to stacked environments. There are a couple of noteworthy features of this design: + +1. The *primary environment*—i.e.the first environment in a stack—is faithfully embedded in a stacked environment. The full dependency graph of the first environment in a stack is guaranteed to be included intact in the stacked environment including the same versions of all dependencies. +2. Packages in non-primary environments can end up using incompatible versions of their dependencies even if their own environments are entirely compatible. This can happen when one of their dependencies is shadowed by a version in an earlier environment in the stack. + +Since the primary environment is typically the environment of a project you're working on, while environments later in the stack contain additional tools, this is the right tradeoff: it's better to break your dev tools but keep the project working. When such incompatibilities occur, you'll typically want to upgrade your dev tools to versions that are compatible with the main project. + +## Conclusion + +Federated package management and precise software reproducibility are difficult but worthy goals in a package system. In combination, these goals lead to a more complex package loading mechanism than most dynamic languages have, but it also yields scalability and reproducibility that is more commonly associated with static languages. Fortunately, most Julia users can remain oblivious to the technical details of code loading and simply use the built-in package manager to add a package `X` to the appropriate project and manifest files and then write `import X` to load `X` without a further thought. diff --git a/src/manual/control-flow.md b/src/manual/control-flow.md index 64adefc..7a4b75a 100644 --- a/src/manual/control-flow.md +++ b/src/manual/control-flow.md @@ -504,7 +504,7 @@ be different: the second and fourth values would contain `0`. | [`TypeError`](@ref) | | [`UndefRefError`](@ref) | | [`UndefVarError`](@ref) | -| `UnicodeError` | +| [`StringIndexError`](@ref) | 예를 들어, 음의 실수 값에 적용된 `sqrt` 함수는 `DomainError`를 throw합니다. diff --git a/src/manual/functions.md b/src/manual/functions.md index c3adfd3..599a118 100644 --- a/src/manual/functions.md +++ b/src/manual/functions.md @@ -460,32 +460,41 @@ call will fail, just as it would if too many arguments were given explicitly. ## Optional Arguments In many cases, function arguments have sensible default values and therefore might not need to -be passed explicitly in every call. For example, the library function [`parse(T, num, base = base)`](@ref) -interprets a string as a number in some base. The `base` argument defaults to `10`. This behavior -can be expressed concisely as: +be passed explicitly in every call. For example, the function [`Date(y, [m, d])`](@ref) +from `Dates` module constructs a `Date` type for a given year `y`, month `m` and day `d`. +However, `m` and `d` arguments are optional and their default value is `1`. +This behavior can be expressed concisely as: ```julia -function parse(T, num; base = 10) - ### +function Date(y::Int64, m::Int64=1, d::Int64=1) + err = validargs(Date, y, m, d) + err === nothing || throw(err) + return Date(UTD(totaldays(y, m, d))) end ``` -With this definition, the function can be called with either two or three arguments, and `10` -is automatically passed when a third argument is not specified: +Observe, that this definition calls another method of `Date` function that takes one argument +of `UTInstant{Day}` type. + +With this definition, the function can be called with either one, two or three arguments, and +`1` is automatically passed when any of the arguments is not specified: ```jldoctest -julia> parse(Int, "12", base = 10) -12 +julia> using Dates -julia> parse(Int, "12", base = 3) -5 +julia> Date(2000, 12, 12) +2000-12-12 + +julia> Date(2000, 12) +2000-12-01 -julia> parse(Int, "12") -12 +julia> Date(2000) +2000-01-01 ``` Optional arguments are actually just a convenient syntax for writing multiple method definitions with different numbers of arguments (see [Note on Optional and keyword Arguments](@ref)). +This can be checked for our `Date` function example by calling `methods` function. ## Keyword Arguments diff --git a/src/manual/networking-and-streams.md b/src/manual/networking-and-streams.md index 51b6912..bb86c3b 100644 --- a/src/manual/networking-and-streams.md +++ b/src/manual/networking-and-streams.md @@ -186,9 +186,13 @@ julia> open("hello.txt") do f ## A simple TCP example -Let's jump right in with a simple example involving TCP sockets. Let's first create a simple server: +Let's jump right in with a simple example involving TCP sockets. +This functionality is in a standard library package called `Sockets`. +Let's first create a simple server: ```julia-repl +julia> using Sockets + julia> @async begin server = listen(2000) while true @@ -266,7 +270,7 @@ julia> @async begin while true sock = accept(server) @async while isopen(sock) - write(sock,readline(sock)) + write(sock, readline(sock, keep=true)) end end end @@ -275,8 +279,8 @@ Task (runnable) @0x00007fd31dc12e60 julia> clientside = connect(2001) TCPSocket(RawFD(28) open, 0 bytes waiting) -julia> @async while true - write(stdout,readline(clientside)) +julia> @async while isopen(clientside) + write(stdout, readline(clientside, keep=true)) end Task (runnable) @0x00007fd31dc11870 diff --git a/src/manual/strings.md b/src/manual/strings.md index 9d49b95..b4c9930 100644 --- a/src/manual/strings.md +++ b/src/manual/strings.md @@ -46,7 +46,8 @@ An `Char` value represents a single character: it is just a 32-bit primitive typ representation and appropriate arithmetic behaviors, and which can be converted to a numeric value representing a [Unicode code point](https://en.wikipedia.org/wiki/Code_point). (Julia packages may define - other subtypes of `AbstractChar`, e.g. to optimize operations for other [text encodings](https://en.wikipedia.org/wiki/Character_encoding).) Here is how `Char` values are +other subtypes of `AbstractChar`, e.g. to optimize operations for other +[text encodings](https://en.wikipedia.org/wiki/Character_encoding).) Here is how `Char` values are input and shown: ```jldoctest @@ -599,6 +600,8 @@ Some other useful functions include: * [`lastindex(str)`](@ref) gives the maximal (byte) index that can be used to index into `str`. * [`length(str)`](@ref) the number of characters in `str`. * [`length(str, i, j)`](@ref) the number of valid character indices in `str` from `i` to `j`. + * [`ncodeunits(str)`](@ref) number of [code units](https://en.wikipedia.org/wiki/Character_encoding#Terminology) in a string. + * [`codeunit(str, i)`](@ref) gives the code unit value in the string `str` at index `i`. * [`i = start(str)`](@ref start) gives the first valid index at which a character can be found in `str` (typically 1). * [`c, j = next(str,i)`](@ref next) returns next character at or after the index `i` and the next valid @@ -839,9 +842,10 @@ for regular expressions containing quotation marks or newlines). ## [Byte Array Literals](@id man-byte-array-literals) -Another useful non-standard string literal is the byte-array string literal: `b"..."`. This form -lets you use string notation to express literal byte arrays -- i.e. arrays of -[`UInt8`](@ref) values. The rules for byte array literals are the following: +Another useful non-standard string literal is the byte-array string literal: `b"..."`. This +form lets you use string notation to express read only literal byte arrays -- i.e. arrays of +[`UInt8`](@ref) values. The type of those objects is `CodeUnits{UInt8, String}`. +The rules for byte array literals are the following: * ASCII characters and ASCII escapes produce a single byte. * `\x` and octal escape sequences produce the *byte* corresponding to the escape value. @@ -867,12 +871,35 @@ julia> b"DATA\xff\u2200" The ASCII string "DATA" corresponds to the bytes 68, 65, 84, 65. `\xff` produces the single byte 255. The Unicode escape `\u2200` is encoded in UTF-8 as the three bytes 226, 136, 128. Note that the -resulting byte array does not correspond to a valid UTF-8 string -- if you try to use this as -a regular string literal, you will get a syntax error: +resulting byte array does not correspond to a valid UTF-8 string: -```julia-repl -julia> "DATA\xff\u2200" -ERROR: syntax: invalid UTF-8 sequence +```jldoctest +julia> isvalid("DATA\xff\u2200") +false +``` + +As it was mentioned `CodeUnits{UInt8,String}` type behaves like read only array of `UInt8` and +if you need a standard vector you can convert it using `Vector{UInt8}`: + +```jldoctest +julia> x = b"123" +3-element Base.CodeUnits{UInt8,String}: + 0x31 + 0x32 + 0x33 + +julia> x[1] +0x31 + +julia> x[1] = 0x32 +ERROR: setindex! not defined for Base.CodeUnits{UInt8,String} +[...] + +julia> Vector{UInt8}(x) +3-element Array{UInt8,1}: + 0x31 + 0x32 + 0x33 ``` Also observe the significant distinction between `\xff` and `\uff`: the former escape sequence diff --git a/src/manual/types.md b/src/manual/types.md index 1a7d849..3527f19 100644 --- a/src/manual/types.md +++ b/src/manual/types.md @@ -622,8 +622,8 @@ function norm(p::Point{<:Real}) end ``` -(Equivalently, one could define `function norm{T<:Real}(p::Point{T})` or -`function norm(p::Point{T} where T<:Real)`; see [UnionAll Types](@ref).) +(Equivalently, one could define `function norm(p::Point{T} where T<:Real)` or +`function norm(p::Point{T}) where T<:Real`; see [UnionAll Types](@ref).) More examples will be discussed later in [Methods](@ref). diff --git a/src/manual/variables-and-scoping.md b/src/manual/variables-and-scoping.md index 5e769ca..45a150f 100644 --- a/src/manual/variables-and-scoping.md +++ b/src/manual/variables-and-scoping.md @@ -489,5 +489,85 @@ not supported. Special top-level assignments, such as those performed by the `function` and `struct` keywords, are constant by default. -Note that `const` only affects the variable binding; the variable may be bound to a mutable object -(such as an array), and that object may still be modified. +Note that `const` only affects the variable binding; the variable may be bound to a mutable +object (such as an array), and that object may still be modified. Additionally when one tries +to assign a value a variable that is declared constant the following scenarios are possible: + +* if a new value has a different type than the type of the constant then an error is thrown: +```jldoctest +julia> const x = 1.0 +1.0 + +julia> x = 1 +ERROR: invalid redefinition of constant x +``` +* if a new value has the same type as the constant then a warning is printed: +```jldoctest +julia> const y = 1.0 +1.0 + +julia> y = 2.0 +WARNING: redefining constant y +2.0 +``` +* if an assignment would not result in the change of variable value no message is given: +```jldoctest +julia> const z = 100 +100 + +julia> z = 100 +100 +``` +The last rule applies for immutable objects even if the vairable binding would change, e.g.: +```julia-repl +julia> const s1 = "1" +"1" + +julia> s2 = "1" +"1" + +julia> pointer.([s1, s2], 1) +2-element Array{Ptr{UInt8},1}: + Ptr{UInt8} @0x00000000132c9638 + Ptr{UInt8} @0x0000000013dd3d18 + +julia> s1 = s2 +"1" + +julia> pointer.([s1, s2], 1) +2-element Array{Ptr{UInt8},1}: + Ptr{UInt8} @0x0000000013dd3d18 + Ptr{UInt8} @0x0000000013dd3d18 +``` +However, for mutable objects the warning is printed as expected: +```jldoctest +julia> const a = [1] +1-element Array{Int64,1}: + 1 + +julia> a = [1] +WARNING: redefining constant a +1-element Array{Int64,1}: + 1 +``` + +Note that although possible, changing the value of a variable that is declared as constant +is strongly discouraged. For instance, if a method references a constant and is already +compiled before the constant is changed then it might keep using the old value: +```jldoctest +julia> const x = 1 +1 + +julia> f() = x +f (generic function with 1 method) + +julia> f() +1 + +julia> x = 2 +WARNING: redefining constant x +2 + +julia> f() +1 +``` diff --git a/src/stdlib/LibGit2.md b/src/stdlib/LibGit2.md new file mode 100644 index 0000000..20fd2b4 --- /dev/null +++ b/src/stdlib/LibGit2.md @@ -0,0 +1,168 @@ +# LibGit2 + +```@meta +DocTestSetup = :(using LibGit2) +``` + +The LibGit2 module provides bindings to [libgit2](https://libgit2.github.com/), a portable C library that +implements core functionality for the [Git](https://git-scm.com/) version control system. +These bindings are currently used to power Julia's package manager. +It is expected that this module will eventually be moved into a separate package. + +### Functionality + +Some of this documentation assumes some prior knowledge of the libgit2 API. +For more information on some of the objects and methods referenced here, consult the upstream +[libgit2 API reference](https://libgit2.github.com/libgit2/#v0.25.1). + +```@docs +LibGit2.Buffer +LibGit2.CheckoutOptions +LibGit2.CloneOptions +LibGit2.DescribeOptions +LibGit2.DescribeFormatOptions +LibGit2.DiffDelta +LibGit2.DiffFile +LibGit2.DiffOptionsStruct +LibGit2.FetchHead +LibGit2.FetchOptions +LibGit2.GitAnnotated +LibGit2.GitBlame +LibGit2.GitBlob +LibGit2.GitCommit +LibGit2.GitHash +LibGit2.GitObject +LibGit2.GitRemote +LibGit2.GitRemoteAnon +LibGit2.GitRepo +LibGit2.GitRepoExt +LibGit2.GitRevWalker +LibGit2.GitShortHash +LibGit2.GitSignature +LibGit2.GitStatus +LibGit2.GitTag +LibGit2.GitTree +LibGit2.IndexEntry +LibGit2.IndexTime +LibGit2.BlameOptions +LibGit2.MergeOptions +LibGit2.ProxyOptions +LibGit2.PushOptions +LibGit2.RebaseOperation +LibGit2.RebaseOptions +LibGit2.RemoteCallbacks +LibGit2.SignatureStruct +LibGit2.StatusEntry +LibGit2.StatusOptions +LibGit2.StrArrayStruct +LibGit2.TimeStruct +LibGit2.add! +LibGit2.add_fetch! +LibGit2.add_push! +LibGit2.addblob! +LibGit2.author +LibGit2.authors +LibGit2.branch +LibGit2.branch! +LibGit2.checkout! +LibGit2.clone +LibGit2.commit +LibGit2.committer +LibGit2.count(::Function, ::LibGit2.GitRevWalker; ::LibGit2.GitHash, ::Cint, ::Bool) +LibGit2.counthunks +LibGit2.create_branch +LibGit2.credentials_callback +LibGit2.credentials_cb +LibGit2.default_signature +LibGit2.delete_branch +LibGit2.diff_files +LibGit2.entryid +LibGit2.entrytype +LibGit2.fetch +LibGit2.fetchheads +LibGit2.fetch_refspecs +LibGit2.fetchhead_foreach_cb +LibGit2.merge_base +LibGit2.merge!(::LibGit2.GitRepo; ::Any...) +LibGit2.merge!(::LibGit2.GitRepo, ::Vector{LibGit2.GitAnnotated}; ::LibGit2.MergeOptions, ::LibGit2.CheckoutOptions) +LibGit2.merge!(::LibGit2.GitRepo, ::Vector{LibGit2.GitAnnotated}, ::Bool; ::LibGit2.MergeOptions, ::LibGit2.CheckoutOptions) +LibGit2.ffmerge! +LibGit2.fullname +LibGit2.features +LibGit2.filename +LibGit2.filemode +LibGit2.gitdir +LibGit2.git_url +LibGit2.@githash_str +LibGit2.head +LibGit2.head! +LibGit2.head_oid +LibGit2.headname +LibGit2.init +LibGit2.is_ancestor_of +LibGit2.isbinary +LibGit2.iscommit +LibGit2.isdiff +LibGit2.isdirty +LibGit2.isorphan +LibGit2.isset +LibGit2.iszero +LibGit2.lookup_branch +LibGit2.map(::Function, ::LibGit2.GitRevWalker; ::LibGit2.GitHash, ::AbstractString, ::Cint, ::Bool) +LibGit2.mirror_callback +LibGit2.mirror_cb +LibGit2.message +LibGit2.merge_analysis +LibGit2.name +LibGit2.need_update +LibGit2.objtype +LibGit2.path +LibGit2.peel +LibGit2.posixpath +LibGit2.push +LibGit2.push!(::LibGit2.GitRevWalker, ::LibGit2.GitHash) +LibGit2.push_head! +LibGit2.push_refspecs +LibGit2.raw +LibGit2.read_tree! +LibGit2.rebase! +LibGit2.ref_list +LibGit2.reftype +LibGit2.remotes +LibGit2.remove! +LibGit2.reset +LibGit2.reset! +LibGit2.restore +LibGit2.revcount +LibGit2.set_remote_url +LibGit2.shortname +LibGit2.snapshot +LibGit2.status +LibGit2.stage +LibGit2.tag_create +LibGit2.tag_delete +LibGit2.tag_list +LibGit2.target +LibGit2.toggle +LibGit2.transact +LibGit2.treewalk +LibGit2.upstream +LibGit2.update! +LibGit2.url +LibGit2.version +LibGit2.with +LibGit2.with_warn +LibGit2.workdir +LibGit2.GitObject(::LibGit2.GitTreeEntry) +LibGit2.UserPasswordCredential +LibGit2.SSHCredential +LibGit2.isfilled +LibGit2.CachedCredentials +LibGit2.CredentialPayload +LibGit2.approve +LibGit2.reject +``` + +```@meta +DocTestSetup = nothing +``` From fd05ddd0d839c0584d3730c1102af148446b990b Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Tue, 17 Apr 2018 03:28:39 +0900 Subject: [PATCH 019/153] =?UTF-8?q?=EC=9D=B4=EB=A1=AD=EA=B2=8C=20=EB=B0=94?= =?UTF-8?q?=ED=83=95=EC=B2=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/custom.css | 12 ++++++++++-- src/manual/unicode-input.md | 6 +++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/assets/custom.css b/src/assets/custom.css index 70cc894..92bfef0 100644 --- a/src/assets/custom.css +++ b/src/assets/custom.css @@ -1,6 +1,14 @@ +/* + 이롭게 바탕체 + https://www.iropke.com/archive/iropke-batang-css.html +*/ +@import url('//cdn.jsdelivr.net/font-iropke-batang/1.2/font-iropke-batang.css'); + +body { + font-family: 'Iropke Batang', serif; +} p { - font-family: serif; - line-height: 1.9em; + line-height: 1.8em; margin: 0em; } li p { diff --git a/src/manual/unicode-input.md b/src/manual/unicode-input.md index 00ab38c..3d84bd5 100644 --- a/src/manual/unicode-input.md +++ b/src/manual/unicode-input.md @@ -32,7 +32,11 @@ function tab_completions(symbols...) end function unicode_data() - file = normpath(@__DIR__, "..", "..", "..", "..", "..", "UnicodeData.txt") + if basename(dirname(normpath(@__DIR__, ".."))) == "_build_local" + file = normpath(@__DIR__, "..", "..", "UnicodeData.txt") + else + file = normpath(@__DIR__, "..", "..", "..", "..", "..", "UnicodeData.txt") + end names = Dict{UInt32, String}() open(file) do unidata for line in readlines(unidata) From 8ef2952d84cccde35b18e2b01594f5b5525f0d15 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Wed, 25 Apr 2018 11:48:16 +0900 Subject: [PATCH 020/153] update Julia Commit 9f5351c36a --- codex/NEWS.md | 9 +++++++++ codex/base/base.md | 1 + codex/devdocs/object.md | 2 +- codex/manual/code-loading.md | 7 ++++--- codex/manual/environment-variables.md | 24 +++++++----------------- codex/manual/noteworthy-differences.md | 23 +++++++++++++---------- codex/manual/parallel-computing.md | 2 ++ codex/stdlib/Pkg3.md | 19 ++++++++++++++++--- src/NEWS.md | 9 +++++++++ src/base/base.md | 1 + src/devdocs/object.md | 2 +- src/manual/code-loading.md | 7 ++++--- src/manual/environment-variables.md | 24 +++++++----------------- src/manual/noteworthy-differences.md | 23 +++++++++++++---------- src/manual/parallel-computing.md | 2 ++ src/stdlib/Pkg3.md | 19 ++++++++++++++++--- 16 files changed, 106 insertions(+), 68 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index fe5f7b2..8a2b3cd 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -459,6 +459,12 @@ This section lists changes that do not have deprecation warnings. * `parse(::Type, ::Char)` now uses a default base of 10, like other number parsing methods, instead of 36 ([#26576](https://github.com/JuliaLang/julia/issues/26576)). + * `isequal` for `Ptr`s now compares element types; `==` still compares only addresses + ([#26858](https://github.com/JuliaLang/julia/issues/26858)). + + * `widen` on 8- and 16-bit integer types now widens to the platform word size (`Int`) + instead of to a 32-bit type ([#26859](https://github.com/JuliaLang/julia/issues/26859)). + Library improvements -------------------- @@ -768,6 +774,9 @@ Deprecated or removed `AbstractUnitRange`s are accepted as arguments. Instead, convert the arguments before calling `ones` or `zeros` ([#26733](https://github.com/JuliaLang/julia/issues/26733)). + * The variadic `size(A, dim1, dim2, dims...)` method to return a tuple of multiple + dimension lengths of `A` has been deprecated ([#26862](https://github.com/JuliaLang/julia/issues/26862)). + * The `Operators` module is deprecated. Instead, import required operators explicitly from `Base`, e.g. `import Base: +, -, *, /` ([#22251](https://github.com/JuliaLang/julia/issues/22251)). diff --git a/codex/base/base.md b/codex/base/base.md index 1839bb8..69cc4bc 100644 --- a/codex/base/base.md +++ b/codex/base/base.md @@ -146,6 +146,7 @@ Base.fieldname Base.sizeof(::Type) Base.isconcretetype Base.isbits +Base.isbitstype Core.fieldtype Base.fieldcount Base.fieldoffset diff --git a/codex/devdocs/object.md b/codex/devdocs/object.md index cf9223f..49d1e46 100644 --- a/codex/devdocs/object.md +++ b/codex/devdocs/object.md @@ -1,6 +1,6 @@ # Memory layout of Julia Objects -## Object layout (jl_value_t) +## Object layout (`jl_value_t`) The `jl_value_t` struct is the name for a block of memory owned by the Julia Garbage Collector, representing the data associated with a Julia object in memory. Absent any type information, it diff --git a/codex/manual/code-loading.md b/codex/manual/code-loading.md index 216e05e..cb37157 100644 --- a/codex/manual/code-loading.md +++ b/codex/manual/code-loading.md @@ -126,6 +126,7 @@ A materialized representation of this dependency `graph` looks like this: graph = Dict{UUID,Dict{Symbol,UUID}}( # Priv – the private one: UUID("ba13f791-ae1d-465a-978b-69c3ad90f72b") => Dict{Symbol,UUID}( + :Pub => UUID("ba13f791-ae1d-465a-978b-69c3ad90f72b"), :Zebra => UUID("f7a24cb4-21fc-4002-ac70-f0e3a0dd3f62"), ), # Priv – the public one: @@ -262,12 +263,12 @@ Here is the corresponding `graph` structure, materialized as a dictionary: graph = Dict{UUID,Dict{Symbol,UUID}}( # Bobcat: UUID("85ad11c7-31f6-5d08-84db-0a4914d4cadf") => Dict{Symbol,UUID}( - :Cobra => UUID("4725e24d-f727-424b-bca0-c4307a3456fa"), - :Dingo => UUID("7a7925be-828c-4418-bbeb-bac8dfc843bc"), + :Cobra => UUID("4725e24d-f727-424b-bca0-c4307a3456fa"), + :Dingo => UUID("7a7925be-828c-4418-bbeb-bac8dfc843bc"), ), # Cobra: UUID("4725e24d-f727-424b-bca0-c4307a3456fa") => Dict{Symbol,UUID}( - :Dingo => UUID("7a7925be-828c-4418-bbeb-bac8dfc843bc"), + :Dingo => UUID("7a7925be-828c-4418-bbeb-bac8dfc843bc"), ), # Dingo: UUID("7a7925be-828c-4418-bbeb-bac8dfc843bc") => Dict{Symbol,UUID}(), diff --git a/codex/manual/environment-variables.md b/codex/manual/environment-variables.md index 79a16cd..79bffcc 100644 --- a/codex/manual/environment-variables.md +++ b/codex/manual/environment-variables.md @@ -68,23 +68,13 @@ and a global configuration search path of ### `JULIA_LOAD_PATH` A separated list of absolute paths that are to be appended to the variable -[`LOAD_PATH`](@ref). (In Unix-like systems, the path separator is `:`; in Windows -systems, the path separator is `;`.) The `LOAD_PATH` variable is where -[`Base.require`](@ref) and `Base.load_in_path()` look for code; it defaults to the absolute -paths - -``` -$JULIA_HOME/../local/share/julia/site/v$(VERSION.major).$(VERSION.minor) -$JULIA_HOME/../share/julia/site/v$(VERSION.major).$(VERSION.minor) -``` - -so that, e.g., version 0.6 of Julia on a Linux system with a Julia executable at -`/bin/julia` will have a default `LOAD_PATH` of - -``` -/local/share/julia/site/v0.6 -/share/julia/site/v0.6 -``` +[`LOAD_PATH`](@ref). (In Unix-like systems, the path separator is `:`; in +Windows systems, the path separator is `;`.) The `LOAD_PATH` variable is where +[`Base.require`](@ref) and `Base.load_in_path()` look for code; it defaults to +the absolute path +`$JULIA_HOME/../share/julia/stdlib/v$(VERSION.major).$(VERSION.minor)` so that, +e.g., version 0.7 of Julia on a Linux system with a Julia executable at +`/bin/julia` will have a default `LOAD_PATH` of `/share/julia/stdlib/v0.7`. ### `JULIA_PKGDIR` diff --git a/codex/manual/noteworthy-differences.md b/codex/manual/noteworthy-differences.md index c87b30c..20ba324 100644 --- a/codex/manual/noteworthy-differences.md +++ b/codex/manual/noteworthy-differences.md @@ -127,8 +127,9 @@ For users coming to Julia from R, these are some noteworthy differences: matrices, then `A * B` denotes a matrix multiplication in Julia, equivalent to R's `A %*% B`. In R, this same notation would perform an element-wise (Hadamard) product. To get the element-wise multiplication operation, you need to write `A .* B` in Julia. - * Julia performs matrix transposition using the `.'` operator and conjugated transposition using - the `'` operator. Julia's `A.'` is therefore equivalent to R's `t(A)`. + * Julia performs matrix transposition using the `transpose` function and conjugated transposition using + the `'` operator or the `adjoint` function. Julia's `transpose(A)` is therefore equivalent to R's `t(A)`. + Additionally a non-recursive transpose in Julia is provided by the `permutedims` function. * Julia does not require parentheses when writing `if` statements or `for`/`while` loops: use `for i in [1, 2, 3]` instead of `for (i in c(1, 2, 3))` and `if i == 1` instead of `if (i == 1)`. * Julia does not treat the numbers `0` and `1` as Booleans. You cannot write `if (1)` in Julia, @@ -149,7 +150,8 @@ For users coming to Julia from R, these are some noteworthy differences: * The [DataFrames package](https://github.com/JuliaStats/DataFrames.jl) provides data frames. * Generalized linear models are provided by the [GLM package](https://github.com/JuliaStats/GLM.jl). * Julia provides tuples and real hash tables, but not R-style lists. When returning multiple items, - you should typically use a tuple: instead of `list(a = 1, b = 2)`, use `(1, 2)`. + you should typically use a tuple or a named tuple: instead of `list(a = 1, b = 2)`, use `(1, 2)` + or `(a=1, b=2)`. * Julia encourages users to write their own types, which are easier to use than S3 or S4 objects in R. Julia's multiple dispatch system means that `table(x::TypeA)` and `table(x::TypeB)` act like R's `table.TypeA(x)` and `table.TypeB(x)`. @@ -167,13 +169,14 @@ For users coming to Julia from R, these are some noteworthy differences: * Julia's [`sum`](@ref), [`prod`](@ref), [`maximum`](@ref), and [`minimum`](@ref) are different from their counterparts in R. They all accept one or two arguments. The first argument is an iterable collection such as an array. If there is a second argument, then this argument indicates the - dimensions, over which the operation is carried out. For instance, let `A=[[1 2],[3 4]]` in Julia - and `B=rbind(c(1,2),c(3,4))` be the same matrix in R. Then `sum(A)` gives the same result as - `sum(B)`, but `sum(A, 1)` is a row vector containing the sum over each column and `sum(A, 2)` - is a column vector containing the sum over each row. This contrasts to the behavior of R, where - `sum(B,1)=11` and `sum(B,2)=12`. If the second argument is a vector, then it specifies all the - dimensions over which the sum is performed, e.g., `sum(A,[1,2])=10`. It should be noted that - there is no error checking regarding the second argument. + dimensions, over which the operation is carried out. For instance, let `A = [1 2; 3 4]` in Julia + and `B <- rbind(c(1,2),c(3,4))` be the same matrix in R. Then `sum(A)` gives the same result as + `sum(B)`, but `sum(A, dims=1)` is a row vector containing the sum over each column and `sum(A, dims=2)` + is a column vector containing the sum over each row. This contrasts to the behavior of R, where separate + `colSums(B)` and `rowSums(B)` functions provide these functionalities. If the `dims` keyword argument is a + vector, then it specifies all the dimensions over which the sum is performed, while retaining the + dimensions of the summed array, e.g. `sum(A, dims=(1,2)) == hcat(10)`. It should be noted that there is no + error checking regarding the second argument. * Julia has several functions that can mutate their arguments. For example, it has both [`sort`](@ref) and [`sort!`](@ref). * In R, performance requires vectorization. In Julia, almost the opposite is true: the best performing diff --git a/codex/manual/parallel-computing.md b/codex/manual/parallel-computing.md index 58bdaf9..76bb41a 100644 --- a/codex/manual/parallel-computing.md +++ b/codex/manual/parallel-computing.md @@ -1580,6 +1580,8 @@ by using [`randjump`](@ref) function: ```julia-repl +julia> using Random + julia> function g_fix(r) a = zeros(1000) @threads for i in 1:1000 diff --git a/codex/stdlib/Pkg3.md b/codex/stdlib/Pkg3.md index 289511f..0678767 100644 --- a/codex/stdlib/Pkg3.md +++ b/codex/stdlib/Pkg3.md @@ -322,6 +322,7 @@ Downloaded MacroTools ─ v0.4.0 The dependencies of the unregistered package (here `MacroTools`) got installed. For unregistered packages we could have given a branch (or commit SHA) to track using `#`, just like for registered packages. + ## Developing packages Let’s say we found a bug in one of our dependencies, e.g. `JSON` that we want to fix. We can get the full git-repo using the `develop` command @@ -352,7 +353,7 @@ It is also possible to give a local path as the argument to `develop` which will Overriding the dependency path for a non registered package is done by giving the git-repo url as an argument to `develop`. -### Updating dependencies +## Updating dependencies When new versions of packages the project is using are released, it is a good idea to update. Simply calling `up` will try to update *all* the dependencies of the project. Sometimes this is not what you want. You can specify a subset of the dependencies to upgrade by giving them as arguments to `up`, e.g: @@ -375,7 +376,17 @@ If you just want install the packages that are given by the current `Manifest.to (HelloWorld) pkg> up --manifest --fixed ``` -### Preview mode +## Precompiling the project + +The REPL command `precompile` can be used to precompile all the dependencies in the project. You can for example do + +``` +(HelloWorld) pkg> update; precompile +``` + +do update the dependencies and then precompile them. + +## Preview mode If you just want to see the effects of running a command, but not change your state you can `preview` a command. For example: @@ -393,7 +404,7 @@ or will show you the effects adding `Plots`, or doing a full upgrade, respectively, would have on your project. However, nothing would be installed and your `Project.toml` and `Manfiest.toml` are untouched. -### Using someone elses project +## Using someone elses project Simple clone their project using e.g. `git clone`, `cd` to the project directory and call @@ -402,3 +413,5 @@ Simple clone their project using e.g. `git clone`, `cd` to the project directory ``` This will install the packages at the same state that the project you cloned was using. + + diff --git a/src/NEWS.md b/src/NEWS.md index c2bafec..ab4909c 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -447,6 +447,12 @@ This section lists changes that do not have deprecation warnings. * `parse(::Type, ::Char)` now uses a default base of 10, like other number parsing methods, instead of 36 ([#26576](https://github.com/JuliaLang/julia/issues/26576)). + * `isequal` for `Ptr`s now compares element types; `==` still compares only addresses + ([#26858](https://github.com/JuliaLang/julia/issues/26858)). + + * `widen` on 8- and 16-bit integer types now widens to the platform word size (`Int`) + instead of to a 32-bit type ([#26859](https://github.com/JuliaLang/julia/issues/26859)). + Library improvements -------------------- @@ -755,6 +761,9 @@ Deprecated or removed `AbstractUnitRange`s are accepted as arguments. Instead, convert the arguments before calling `ones` or `zeros` ([#26733](https://github.com/JuliaLang/julia/issues/26733)). + * The variadic `size(A, dim1, dim2, dims...)` method to return a tuple of multiple + dimension lengths of `A` has been deprecated ([#26862](https://github.com/JuliaLang/julia/issues/26862)). + * The `Operators` module is deprecated. Instead, import required operators explicitly from `Base`, e.g. `import Base: +, -, *, /` ([#22251](https://github.com/JuliaLang/julia/issues/22251)). diff --git a/src/base/base.md b/src/base/base.md index 1839bb8..69cc4bc 100644 --- a/src/base/base.md +++ b/src/base/base.md @@ -146,6 +146,7 @@ Base.fieldname Base.sizeof(::Type) Base.isconcretetype Base.isbits +Base.isbitstype Core.fieldtype Base.fieldcount Base.fieldoffset diff --git a/src/devdocs/object.md b/src/devdocs/object.md index cf9223f..49d1e46 100644 --- a/src/devdocs/object.md +++ b/src/devdocs/object.md @@ -1,6 +1,6 @@ # Memory layout of Julia Objects -## Object layout (jl_value_t) +## Object layout (`jl_value_t`) The `jl_value_t` struct is the name for a block of memory owned by the Julia Garbage Collector, representing the data associated with a Julia object in memory. Absent any type information, it diff --git a/src/manual/code-loading.md b/src/manual/code-loading.md index 216e05e..cb37157 100644 --- a/src/manual/code-loading.md +++ b/src/manual/code-loading.md @@ -126,6 +126,7 @@ A materialized representation of this dependency `graph` looks like this: graph = Dict{UUID,Dict{Symbol,UUID}}( # Priv – the private one: UUID("ba13f791-ae1d-465a-978b-69c3ad90f72b") => Dict{Symbol,UUID}( + :Pub => UUID("ba13f791-ae1d-465a-978b-69c3ad90f72b"), :Zebra => UUID("f7a24cb4-21fc-4002-ac70-f0e3a0dd3f62"), ), # Priv – the public one: @@ -262,12 +263,12 @@ Here is the corresponding `graph` structure, materialized as a dictionary: graph = Dict{UUID,Dict{Symbol,UUID}}( # Bobcat: UUID("85ad11c7-31f6-5d08-84db-0a4914d4cadf") => Dict{Symbol,UUID}( - :Cobra => UUID("4725e24d-f727-424b-bca0-c4307a3456fa"), - :Dingo => UUID("7a7925be-828c-4418-bbeb-bac8dfc843bc"), + :Cobra => UUID("4725e24d-f727-424b-bca0-c4307a3456fa"), + :Dingo => UUID("7a7925be-828c-4418-bbeb-bac8dfc843bc"), ), # Cobra: UUID("4725e24d-f727-424b-bca0-c4307a3456fa") => Dict{Symbol,UUID}( - :Dingo => UUID("7a7925be-828c-4418-bbeb-bac8dfc843bc"), + :Dingo => UUID("7a7925be-828c-4418-bbeb-bac8dfc843bc"), ), # Dingo: UUID("7a7925be-828c-4418-bbeb-bac8dfc843bc") => Dict{Symbol,UUID}(), diff --git a/src/manual/environment-variables.md b/src/manual/environment-variables.md index 79a16cd..79bffcc 100644 --- a/src/manual/environment-variables.md +++ b/src/manual/environment-variables.md @@ -68,23 +68,13 @@ and a global configuration search path of ### `JULIA_LOAD_PATH` A separated list of absolute paths that are to be appended to the variable -[`LOAD_PATH`](@ref). (In Unix-like systems, the path separator is `:`; in Windows -systems, the path separator is `;`.) The `LOAD_PATH` variable is where -[`Base.require`](@ref) and `Base.load_in_path()` look for code; it defaults to the absolute -paths - -``` -$JULIA_HOME/../local/share/julia/site/v$(VERSION.major).$(VERSION.minor) -$JULIA_HOME/../share/julia/site/v$(VERSION.major).$(VERSION.minor) -``` - -so that, e.g., version 0.6 of Julia on a Linux system with a Julia executable at -`/bin/julia` will have a default `LOAD_PATH` of - -``` -/local/share/julia/site/v0.6 -/share/julia/site/v0.6 -``` +[`LOAD_PATH`](@ref). (In Unix-like systems, the path separator is `:`; in +Windows systems, the path separator is `;`.) The `LOAD_PATH` variable is where +[`Base.require`](@ref) and `Base.load_in_path()` look for code; it defaults to +the absolute path +`$JULIA_HOME/../share/julia/stdlib/v$(VERSION.major).$(VERSION.minor)` so that, +e.g., version 0.7 of Julia on a Linux system with a Julia executable at +`/bin/julia` will have a default `LOAD_PATH` of `/share/julia/stdlib/v0.7`. ### `JULIA_PKGDIR` diff --git a/src/manual/noteworthy-differences.md b/src/manual/noteworthy-differences.md index c87b30c..20ba324 100644 --- a/src/manual/noteworthy-differences.md +++ b/src/manual/noteworthy-differences.md @@ -127,8 +127,9 @@ For users coming to Julia from R, these are some noteworthy differences: matrices, then `A * B` denotes a matrix multiplication in Julia, equivalent to R's `A %*% B`. In R, this same notation would perform an element-wise (Hadamard) product. To get the element-wise multiplication operation, you need to write `A .* B` in Julia. - * Julia performs matrix transposition using the `.'` operator and conjugated transposition using - the `'` operator. Julia's `A.'` is therefore equivalent to R's `t(A)`. + * Julia performs matrix transposition using the `transpose` function and conjugated transposition using + the `'` operator or the `adjoint` function. Julia's `transpose(A)` is therefore equivalent to R's `t(A)`. + Additionally a non-recursive transpose in Julia is provided by the `permutedims` function. * Julia does not require parentheses when writing `if` statements or `for`/`while` loops: use `for i in [1, 2, 3]` instead of `for (i in c(1, 2, 3))` and `if i == 1` instead of `if (i == 1)`. * Julia does not treat the numbers `0` and `1` as Booleans. You cannot write `if (1)` in Julia, @@ -149,7 +150,8 @@ For users coming to Julia from R, these are some noteworthy differences: * The [DataFrames package](https://github.com/JuliaStats/DataFrames.jl) provides data frames. * Generalized linear models are provided by the [GLM package](https://github.com/JuliaStats/GLM.jl). * Julia provides tuples and real hash tables, but not R-style lists. When returning multiple items, - you should typically use a tuple: instead of `list(a = 1, b = 2)`, use `(1, 2)`. + you should typically use a tuple or a named tuple: instead of `list(a = 1, b = 2)`, use `(1, 2)` + or `(a=1, b=2)`. * Julia encourages users to write their own types, which are easier to use than S3 or S4 objects in R. Julia's multiple dispatch system means that `table(x::TypeA)` and `table(x::TypeB)` act like R's `table.TypeA(x)` and `table.TypeB(x)`. @@ -167,13 +169,14 @@ For users coming to Julia from R, these are some noteworthy differences: * Julia's [`sum`](@ref), [`prod`](@ref), [`maximum`](@ref), and [`minimum`](@ref) are different from their counterparts in R. They all accept one or two arguments. The first argument is an iterable collection such as an array. If there is a second argument, then this argument indicates the - dimensions, over which the operation is carried out. For instance, let `A=[[1 2],[3 4]]` in Julia - and `B=rbind(c(1,2),c(3,4))` be the same matrix in R. Then `sum(A)` gives the same result as - `sum(B)`, but `sum(A, 1)` is a row vector containing the sum over each column and `sum(A, 2)` - is a column vector containing the sum over each row. This contrasts to the behavior of R, where - `sum(B,1)=11` and `sum(B,2)=12`. If the second argument is a vector, then it specifies all the - dimensions over which the sum is performed, e.g., `sum(A,[1,2])=10`. It should be noted that - there is no error checking regarding the second argument. + dimensions, over which the operation is carried out. For instance, let `A = [1 2; 3 4]` in Julia + and `B <- rbind(c(1,2),c(3,4))` be the same matrix in R. Then `sum(A)` gives the same result as + `sum(B)`, but `sum(A, dims=1)` is a row vector containing the sum over each column and `sum(A, dims=2)` + is a column vector containing the sum over each row. This contrasts to the behavior of R, where separate + `colSums(B)` and `rowSums(B)` functions provide these functionalities. If the `dims` keyword argument is a + vector, then it specifies all the dimensions over which the sum is performed, while retaining the + dimensions of the summed array, e.g. `sum(A, dims=(1,2)) == hcat(10)`. It should be noted that there is no + error checking regarding the second argument. * Julia has several functions that can mutate their arguments. For example, it has both [`sort`](@ref) and [`sort!`](@ref). * In R, performance requires vectorization. In Julia, almost the opposite is true: the best performing diff --git a/src/manual/parallel-computing.md b/src/manual/parallel-computing.md index 58bdaf9..76bb41a 100644 --- a/src/manual/parallel-computing.md +++ b/src/manual/parallel-computing.md @@ -1580,6 +1580,8 @@ by using [`randjump`](@ref) function: ```julia-repl +julia> using Random + julia> function g_fix(r) a = zeros(1000) @threads for i in 1:1000 diff --git a/src/stdlib/Pkg3.md b/src/stdlib/Pkg3.md index 289511f..0678767 100644 --- a/src/stdlib/Pkg3.md +++ b/src/stdlib/Pkg3.md @@ -322,6 +322,7 @@ Downloaded MacroTools ─ v0.4.0 The dependencies of the unregistered package (here `MacroTools`) got installed. For unregistered packages we could have given a branch (or commit SHA) to track using `#`, just like for registered packages. + ## Developing packages Let’s say we found a bug in one of our dependencies, e.g. `JSON` that we want to fix. We can get the full git-repo using the `develop` command @@ -352,7 +353,7 @@ It is also possible to give a local path as the argument to `develop` which will Overriding the dependency path for a non registered package is done by giving the git-repo url as an argument to `develop`. -### Updating dependencies +## Updating dependencies When new versions of packages the project is using are released, it is a good idea to update. Simply calling `up` will try to update *all* the dependencies of the project. Sometimes this is not what you want. You can specify a subset of the dependencies to upgrade by giving them as arguments to `up`, e.g: @@ -375,7 +376,17 @@ If you just want install the packages that are given by the current `Manifest.to (HelloWorld) pkg> up --manifest --fixed ``` -### Preview mode +## Precompiling the project + +The REPL command `precompile` can be used to precompile all the dependencies in the project. You can for example do + +``` +(HelloWorld) pkg> update; precompile +``` + +do update the dependencies and then precompile them. + +## Preview mode If you just want to see the effects of running a command, but not change your state you can `preview` a command. For example: @@ -393,7 +404,7 @@ or will show you the effects adding `Plots`, or doing a full upgrade, respectively, would have on your project. However, nothing would be installed and your `Project.toml` and `Manfiest.toml` are untouched. -### Using someone elses project +## Using someone elses project Simple clone their project using e.g. `git clone`, `cd` to the project directory and call @@ -402,3 +413,5 @@ Simple clone their project using e.g. `git clone`, `cd` to the project directory ``` This will install the packages at the same state that the project you cloned was using. + + From 1678591473e814a8152853efcbd2b5e425ac70d1 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Wed, 2 May 2018 00:24:08 +0900 Subject: [PATCH 021/153] update Julia Commit 132a9f45fe --- codex/NEWS.md | 14 +-- codex/base/arrays.md | 2 +- codex/manual/interfaces.md | 173 ++++++++++++++++++++++--------------- src/NEWS.md | 14 +-- src/base/arrays.md | 2 +- src/manual/interfaces.md | 173 ++++++++++++++++++++++--------------- 6 files changed, 224 insertions(+), 154 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index 8a2b3cd..1450a02 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -388,11 +388,6 @@ This section lists changes that do not have deprecation warnings. Its return value has been removed. Use the `process_running` function to determine if a process has already exited. - * Broadcasting has been redesigned with an extensible public interface. The new API is - documented at https://docs.julialang.org/en/latest/manual/interfaces/#Interfaces-1. - `AbstractArray` types that specialized broadcasting using the old internal API will - need to switch to the new API. ([#20740](https://github.com/JuliaLang/julia/issues/20740)) - * The logging system has been redesigned - `info` and `warn` are deprecated and replaced with the logging macros `@info`, `@warn`, `@debug` and `@error`. The `logging` function is also deprecated and replaced with @@ -418,6 +413,15 @@ This section lists changes that do not have deprecation warnings. * `findn(x::AbstractArray)` has been deprecated in favor of `findall(!iszero, x)`, which now returns cartesian indices for multidimensional arrays (see below, [#25532](https://github.com/JuliaLang/julia/issues/25532)). + * Broadcasting operations are no longer fused into a single operation by Julia's parser. + Instead, a lazy `Broadcasted` object is created to represent the fused expression and + then realized with `copy(bc::Broadcasted)` or `copyto!(dest, bc::Broadcasted)` + to evaluate the wrapper. Consequently, package authors generally need to specialize + `copy` and `copyto!` methods rather than `broadcast` and `broadcast!`. This also allows + for more customization and control of fused broadcasts. See the + [Interfaces chapter](https://docs.julialang.org/en/latest/manual/interfaces/#man-interfaces-broadcasting-1) + for more information. + * `find` has been renamed to `findall`. `findall`, `findfirst`, `findlast`, `findnext` now take and/or return the same type of indices as `keys`/`pairs` for `AbstractArray`, `AbstractDict`, `AbstractString`, `Tuple` and `NamedTuple` objects ([#24774](https://github.com/JuliaLang/julia/issues/24774), [#25545](https://github.com/JuliaLang/julia/issues/25545)). diff --git a/codex/base/arrays.md b/codex/base/arrays.md index 3357292..2b1a8d7 100644 --- a/codex/base/arrays.md +++ b/codex/base/arrays.md @@ -69,7 +69,7 @@ For specializing broadcast on custom types, see ```@docs Base.BroadcastStyle Base.broadcast_similar -Base.broadcast_indices +Base.broadcast_axes Base.Broadcast.AbstractArrayStyle Base.Broadcast.ArrayStyle Base.Broadcast.DefaultArrayStyle diff --git a/codex/manual/interfaces.md b/codex/manual/interfaces.md index d13bd75..620bb4f 100644 --- a/codex/manual/interfaces.md +++ b/codex/manual/interfaces.md @@ -435,22 +435,22 @@ V = view(A, [1,2,4], :) # is not strided, as the spacing between rows is not f -## [Broadcasting](@id man-interfaces-broadcasting) +## [Customizing broadcasting](@id man-interfaces-broadcasting) | Methods to implement | Brief description | |:-------------------- |:----------------- | | `Base.BroadcastStyle(::Type{SrcType}) = SrcStyle()` | Broadcasting behavior of `SrcType` | -| `Base.broadcast_similar(f, ::DestStyle, ::Type{ElType}, inds, As...)` | Allocation of output container | +| `Base.broadcast_similar(::DestStyle, ::Type{ElType}, inds, bc)` | Allocation of output container | | **Optional methods** | | | | `Base.BroadcastStyle(::Style1, ::Style2) = Style12()` | Precedence rules for mixing styles | -| `Base.broadcast_indices(::StyleA, A)` | Declaration of the indices of `A` for broadcasting purposes (defaults to [`axes(A)`](@ref)) | +| `Base.broadcast_axes(::StyleA, A)` | Declaration of the indices of `A` for broadcasting purposes (defaults to [`axes(A)`](@ref)) | | `Base.broadcastable(x)` | Convert `x` to an object that has `axes` and supports indexing | | **Bypassing default machinery** | | -| `broadcast(f, As...)` | Complete bypass of broadcasting machinery | -| `broadcast(f, ::DestStyle, ::Nothing, ::Nothing, As...)` | Bypass after container type is computed | -| `broadcast(f, ::DestStyle, ::Type{ElType}, inds::Tuple, As...)` | Bypass after container type, eltype, and indices are computed | -| `broadcast!(f, dest::DestType, ::Nothing, As...)` | Bypass in-place broadcast, specialization on destination type | -| `broadcast!(f, dest, ::BroadcastStyle, As...)` | Bypass in-place broadcast, specialization on `BroadcastStyle` | +| `Base.copy(bc::Broadcasted{DestStyle})` | Custom implementation of `broadcast` | +| `Base.copyto!(dest, bc::Broadcasted{DestStyle})` | Custom implementation of `broadcast!`, specializing on `DestStyle` | +| `Base.copyto!(dest::DestType, bc::Broadcasted{Nothing})` | Custom implementation of `broadcast!`, specializing on `DestType` | +| `Base.Broadcast.broadcasted(f, args...)` | Override the default lazy behavior within a fused expression | +| `Base.Broadcast.instantiate(bc::Broadcasted{DestStyle})` | Override the computation of the lazy broadcast's axes | [Broadcasting](@ref) is triggered by an explicit call to `broadcast` or `broadcast!`, or implicitly by "dot" operations like `A .+ b` or `f.(x, y)`. Any object that has [`axes`](@ref) and supports @@ -463,16 +463,16 @@ in an `Array`. This basic framework is extensible in three major ways: Not all types support `axes` and indexing, but many are convenient to allow in broadcast. The [`Base.broadcastable`](@ref) function is called on each argument to broadcast, allowing -it to return something different that supports `axes` and indexing if it does not. By +it to return something different that supports `axes` and indexing. By default, this is the identity function for all `AbstractArray`s and `Number`s — they already support `axes` and indexing. For a handful of other types (including but not limited to types themselves, functions, special singletons like `missing` and `nothing`, and dates), `Base.broadcastable` returns the argument wrapped in a `Ref` to act as a 0-dimensional "scalar" for the purposes of broadcasting. Custom types can similarly specialize `Base.broadcastable` to define their shape, but they should follow the convention that -`collect(Base.broadcastable(x)) == collect(x)`. A notable exception are `AbstractString`s; -they are special-cased to behave as scalars for the purposes of broadcast even though they -are iterable collections of their characters. +`collect(Base.broadcastable(x)) == collect(x)`. A notable exception is `AbstractString`; +strings are special-cased to behave as scalars for the purposes of broadcast even though +they are iterable collections of their characters. The next two steps (selecting the output array and implementation) are dependent upon determining a single answer for a given set of arguments. Broadcast must take all the varied @@ -483,12 +483,11 @@ styles into a single answer — the "destination style". ### Broadcast Styles -`Base.BroadcastStyle` is the abstract type from which all styles are -derived. When used as a function it has two possible forms, -unary (single-argument) and binary. -The unary variant states that you intend to -implement specific broadcasting behavior and/or output type, -and do not wish to rely on the default fallback ([`Broadcast.DefaultArrayStyle`](@ref)). +`Base.BroadcastStyle` is the abstract type from which all broadcast styles are derived. When used as a +function it has two possible forms, unary (single-argument) and binary. The unary variant states +that you intend to implement specific broadcasting behavior and/or output type, and do not wish to +rely on the default fallback [`Broadcast.DefaultArrayStyle`](@ref). + To override these defaults, you can define a custom `BroadcastStyle` for your object: ```julia @@ -507,27 +506,30 @@ leverage one of the general broadcast wrappers: When your broadcast operation involves several arguments, individual argument styles get combined to determine a single `DestStyle` that controls the type of the output container. -For more detail, see [below](@ref writing-binary-broadcasting-rules). +For more details, see [below](@ref writing-binary-broadcasting-rules). ### Selecting an appropriate output array -The actual allocation of the result array is handled by `Base.broadcast_similar`: +The broadcast style is computed for every broadcasting operation to allow for +dispatch and specialization. The actual allocation of the result array is +handled by `Base.broadcast_similar`, using this style as its first argument. ```julia -Base.broadcast_similar(f, ::DestStyle, ::Type{ElType}, inds, As...) +Base.broadcast_similar(::DestStyle, ::Type{ElType}, inds, bc) ``` -`f` is the operation being performed and `DestStyle` signals the final result from -combining the input styles. -`As...` is the list of input objects. You may not need to use `f` or `As...` -unless they help you build the appropriate object; the fallback definition is +The fallback definition is ```julia -broadcast_similar(f, ::DefaultArrayStyle{N}, ::Type{ElType}, inds::Indices{N}, As...) where {N,ElType} = +broadcast_similar(::DefaultArrayStyle{N}, ::Type{ElType}, inds::Indices{N}, bc) where {N,ElType} = similar(Array{ElType}, inds) ``` -However, if needed you can specialize on any or all of these arguments. +However, if needed you can specialize on any or all of these arguments. The final argument +`bc` is a lazy representation of a (potentially fused) broadcast operation, a `Broadcasted` +object. For these purposes, the most important fields of the wrapper are +`f` and `args`, describing the function and argument list, respectively. Note that the argument +list can — and often does — include other nested `Broadcasted` wrappers. For a complete example, let's say you have created a type, `ArrayAndChar`, that stores an array and a single character: @@ -553,20 +555,21 @@ Base.BroadcastStyle(::Type{<:ArrayAndChar}) = Broadcast.ArrayStyle{ArrayAndChar} ``` -This forces us to also define a `broadcast_similar` method: -```jldoctest ArrayAndChar; filter = r"(^find_aac \(generic function with 2 methods\)$|^$)" -function Base.broadcast_similar(f, ::Broadcast.ArrayStyle{ArrayAndChar}, ::Type{ElType}, inds, As...) where ElType +This means we must also define a corresponding `broadcast_similar` method: +```jldoctest +function Base.broadcast_similar(::Broadcast.ArrayStyle{ArrayAndChar}, ::Type{ElType}, inds, bc) where ElType # Scan the inputs for the ArrayAndChar: - A = find_aac(As...) + A = find_aac(bc) # Use the char field of A to create the output ArrayAndChar(similar(Array{ElType}, inds), A.char) end -"`A = find_aac(As...)` returns the first ArrayAndChar among the arguments." -find_aac(A::ArrayAndChar, B...) = A -find_aac(A, B...) = find_aac(B...); -# output - +"`A = find_aac(As)` returns the first ArrayAndChar among the arguments." +find_aac(bc::Base.Broadcast.Broadcasted) = find_aac(bc.args) +find_aac(args::Tuple) = find_aac(find_aac(args[1]), Base.tail(args)) +find_aac(x) = x +find_aac(a::ArrayAndChar, rest) = a +find_aac(::Any, rest) = find_aac(rest) ``` From these definitions, one obtains the following behavior: @@ -589,58 +592,86 @@ julia> a .+ [5,10] ### [Extending broadcast with custom implementations](@id extending-in-place-broadcast) -Finally, it's worth noting that sometimes it's easier simply to bypass the machinery for -computing result types and container sizes, and just do everything manually. For example, -you can convert a `UnitRange{Int}` `r` to a `UnitRange{BigInt}` with `big.(r)`; the definition -of this method is approximately +In general, a broadcast operation is represented by a lazy `Broadcasted` container that holds onto +the function to be applied alongside its arguments. Those arguments may themselves be more nested +`Broadcasted` containers, forming a large expression tree to be evaluated. A nested tree of +`Broadcasted` containers is directly constructed by the implicit dot syntax; `5 .+ 2.*x` is +transiently represented by `Broadcasted(+, 5, Broadcasted(*, 2, x))`, for example. This is +invisible to users as it is immediately realized through a call to `copy`, but it is this container +that provides the basis for broadcast's extensibility for authors of custom types. The built-in +broadcast machinery will then determine the result type and size based upon the arguments, allocate +it, and then finally copy the realization of the `Broadcasted` object into it with a default +`copyto!(::AbstractArray, ::Broadcasted)` method. The built-in fallback `broadcast` and +`broadcast!` methods similarly construct a transient `Broadcasted` representation of the operation +so they can follow the same codepath. This allows custom array implementations to +provide their own `copyto!` specialization to customize and +optimize broadcasting. This is again determined by the computed broadcast style. This is such +an important part of the operation that it is stored as the first type parameter of the +`Broadcasted` type, allowing for dispatch and specialization. + +For some types, the machinery to "fuse" operations across nested levels of broadcasting +is not available or could be done more efficiently incrementally. In such cases, you may +need or want to evaluate `x .* (x .+ 1)` as if it had been +written `broadcast(*, x, broadcast(+, x, 1))`, where the inner operation is evaluated before +tackling the outer operation. This sort of eager operation is directly supported by a bit +of indirection; instead of directly constructing `Broadcasted` objects, Julia lowers the +fused expression `x .* (x .+ 1)` to `Broadcast.broadcasted(*, x, Broadcast.broadcasted(+, x, 1))`. Now, +by default, `broadcasted` just calls the `Broadcasted` constructor to create the lazy representation +of the fused expression tree, but you can choose to override it for a particular combination +of function and arguments. + +As an example, the builtin `AbstractRange` objects use this machinery to optimize pieces +of broadcasted expressions that can be eagerly evaluated purely in terms of the start, +step, and length (or stop) instead of computing every single element. Just like all the +other machinery, `broadcasted` also computes and exposes the combined broadcast style of its +arguments, so instead of specializing on `broadcasted(f, args...)`, you can specialize on +`broadcasted(::DestStyle, f, args...)` for any combination of style, function, and arguments. + +For example, the following definition supports the negation of ranges: ```julia -Broadcast.broadcast(::typeof(big), r::UnitRange) = big(first(r)):big(last(r)) +broadcasted(::DefaultArrayStyle{1}, ::typeof(-), r::OrdinalRange) = range(-first(r), step=-step(r), length=length(r)) ``` -This exploits Julia's ability to dispatch on a particular function type. (This kind of -explicit definition can indeed be necessary if the output container does not support `setindex!`.) -You can optionally choose to implement the actual broadcasting yourself, but allow -the internal machinery to compute the container type, element type, and indices by specializing - -```julia -Broadcast.broadcast(::typeof(somefunction), ::MyStyle, ::Type{ElType}, inds, As...) -``` +### [Extending in-place broadcasting](@id extending-in-place-broadcast) -Extending `broadcast!` (in-place broadcast) should be done with care, as it is easy to introduce -ambiguities between packages. To avoid these ambiguities, we adhere to the following conventions. - -First, if you want to specialize on the destination type, say `DestType`, then you should -define a method with the following signature: +In-place broadcasting can be supported by defining the appropriate `copyto!(dest, bc::Broadcasted)` +method. Because you might want to specialize either on `dest` or the specific subtype of `bc`, +to avoid ambiguities between packages we recommend the following convention. +If you wish to specialize on a particular style `DestStyle`, define a method for ```julia -broadcast!(f, dest::DestType, ::Nothing, As...) +copyto!(dest, bc::Broadcasted{DestStyle}) ``` +Optionally, with this form you can also specialize on the type of `dest`. -Note that no bounds should be placed on the types of `f` and `As...`. - -Second, if specialized `broadcast!` behavior is desired depending on the input types, -you should write [binary broadcasting rules](@ref writing-binary-broadcasting-rules) to -determine a custom `BroadcastStyle` given the input types, say `MyBroadcastStyle`, and you should define a method with the following -signature: +If instead you want to specialize on the destination type `DestType` without specializing +on `DestStyle`, then you should define a method with the following signature: ```julia -broadcast!(f, dest, ::MyBroadcastStyle, As...) +copyto!(dest::DestType, bc::Broadcasted{Nothing}) ``` -Note the lack of bounds on `f`, `dest`, and `As...`. +This leverages a fallback implementation of `copyto!` that converts the wrapper into a +`Broadcasted{Nothing}`. Consequently, specializing on `DestType` has lower precedence than +methods that specialize on `DestStyle`. -Third, simultaneously specializing on both the type of `dest` and the `BroadcastStyle` is fine. In this case, -it is also allowed to specialize on the types of the source arguments (`As...`). For example, these method signatures are OK: +Similarly, you can completely override out-of-place broadcasting with a `copy(::Broadcasted)` +method. -```julia -broadcast!(f, dest::DestType, ::MyBroadcastStyle, As...) -broadcast!(f, dest::DestType, ::MyBroadcastStyle, As::AbstractArray...) -broadcast!(f, dest::DestType, ::Broadcast.DefaultArrayStyle{0}, As::Number...) -``` +#### Working with `Broadcasted` objects + +In order to implement such a `copy` or `copyto!`, method, of course, you must +work with the `Broadcasted` wrapper to compute each element. There are two main +ways of doing so: +* `Broadcast.flatten` recomputes the potentially nested operation into a single + function and flat list of arguments. You are responsible for implementing the + broadcasting shape rules yourself, but this may be helpful in limited situations. +* Iterating over the `CartesianIndices` of the `axes(::Broadcasted)` and using + indexing with the resulting `CartesianIndex` object to compute the result. -#### [Writing binary broadcasting rules](@id writing-binary-broadcasting-rules) +### [Writing binary broadcasting rules](@id writing-binary-broadcasting-rules) The precedence rules are defined by binary `BroadcastStyle` calls: diff --git a/src/NEWS.md b/src/NEWS.md index ab4909c..8bc35d5 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -376,11 +376,6 @@ This section lists changes that do not have deprecation warnings. Its return value has been removed. Use the `process_running` function to determine if a process has already exited. - * Broadcasting has been redesigned with an extensible public interface. The new API is - documented at https://docs.julialang.org/en/latest/manual/interfaces/#Interfaces-1. - `AbstractArray` types that specialized broadcasting using the old internal API will - need to switch to the new API. ([#20740](https://github.com/JuliaLang/julia/issues/20740)) - * The logging system has been redesigned - `info` and `warn` are deprecated and replaced with the logging macros `@info`, `@warn`, `@debug` and `@error`. The `logging` function is also deprecated and replaced with @@ -406,6 +401,15 @@ This section lists changes that do not have deprecation warnings. * `findn(x::AbstractArray)` has been deprecated in favor of `findall(!iszero, x)`, which now returns cartesian indices for multidimensional arrays (see below, [#25532](https://github.com/JuliaLang/julia/issues/25532)). + * Broadcasting operations are no longer fused into a single operation by Julia's parser. + Instead, a lazy `Broadcasted` object is created to represent the fused expression and + then realized with `copy(bc::Broadcasted)` or `copyto!(dest, bc::Broadcasted)` + to evaluate the wrapper. Consequently, package authors generally need to specialize + `copy` and `copyto!` methods rather than `broadcast` and `broadcast!`. This also allows + for more customization and control of fused broadcasts. See the + [Interfaces chapter](https://docs.julialang.org/en/latest/manual/interfaces/#man-interfaces-broadcasting-1) + for more information. + * `find` has been renamed to `findall`. `findall`, `findfirst`, `findlast`, `findnext` now take and/or return the same type of indices as `keys`/`pairs` for `AbstractArray`, `AbstractDict`, `AbstractString`, `Tuple` and `NamedTuple` objects ([#24774](https://github.com/JuliaLang/julia/issues/24774), [#25545](https://github.com/JuliaLang/julia/issues/25545)). diff --git a/src/base/arrays.md b/src/base/arrays.md index 3357292..2b1a8d7 100644 --- a/src/base/arrays.md +++ b/src/base/arrays.md @@ -69,7 +69,7 @@ For specializing broadcast on custom types, see ```@docs Base.BroadcastStyle Base.broadcast_similar -Base.broadcast_indices +Base.broadcast_axes Base.Broadcast.AbstractArrayStyle Base.Broadcast.ArrayStyle Base.Broadcast.DefaultArrayStyle diff --git a/src/manual/interfaces.md b/src/manual/interfaces.md index d13bd75..620bb4f 100644 --- a/src/manual/interfaces.md +++ b/src/manual/interfaces.md @@ -435,22 +435,22 @@ V = view(A, [1,2,4], :) # is not strided, as the spacing between rows is not f -## [Broadcasting](@id man-interfaces-broadcasting) +## [Customizing broadcasting](@id man-interfaces-broadcasting) | Methods to implement | Brief description | |:-------------------- |:----------------- | | `Base.BroadcastStyle(::Type{SrcType}) = SrcStyle()` | Broadcasting behavior of `SrcType` | -| `Base.broadcast_similar(f, ::DestStyle, ::Type{ElType}, inds, As...)` | Allocation of output container | +| `Base.broadcast_similar(::DestStyle, ::Type{ElType}, inds, bc)` | Allocation of output container | | **Optional methods** | | | | `Base.BroadcastStyle(::Style1, ::Style2) = Style12()` | Precedence rules for mixing styles | -| `Base.broadcast_indices(::StyleA, A)` | Declaration of the indices of `A` for broadcasting purposes (defaults to [`axes(A)`](@ref)) | +| `Base.broadcast_axes(::StyleA, A)` | Declaration of the indices of `A` for broadcasting purposes (defaults to [`axes(A)`](@ref)) | | `Base.broadcastable(x)` | Convert `x` to an object that has `axes` and supports indexing | | **Bypassing default machinery** | | -| `broadcast(f, As...)` | Complete bypass of broadcasting machinery | -| `broadcast(f, ::DestStyle, ::Nothing, ::Nothing, As...)` | Bypass after container type is computed | -| `broadcast(f, ::DestStyle, ::Type{ElType}, inds::Tuple, As...)` | Bypass after container type, eltype, and indices are computed | -| `broadcast!(f, dest::DestType, ::Nothing, As...)` | Bypass in-place broadcast, specialization on destination type | -| `broadcast!(f, dest, ::BroadcastStyle, As...)` | Bypass in-place broadcast, specialization on `BroadcastStyle` | +| `Base.copy(bc::Broadcasted{DestStyle})` | Custom implementation of `broadcast` | +| `Base.copyto!(dest, bc::Broadcasted{DestStyle})` | Custom implementation of `broadcast!`, specializing on `DestStyle` | +| `Base.copyto!(dest::DestType, bc::Broadcasted{Nothing})` | Custom implementation of `broadcast!`, specializing on `DestType` | +| `Base.Broadcast.broadcasted(f, args...)` | Override the default lazy behavior within a fused expression | +| `Base.Broadcast.instantiate(bc::Broadcasted{DestStyle})` | Override the computation of the lazy broadcast's axes | [Broadcasting](@ref) is triggered by an explicit call to `broadcast` or `broadcast!`, or implicitly by "dot" operations like `A .+ b` or `f.(x, y)`. Any object that has [`axes`](@ref) and supports @@ -463,16 +463,16 @@ in an `Array`. This basic framework is extensible in three major ways: Not all types support `axes` and indexing, but many are convenient to allow in broadcast. The [`Base.broadcastable`](@ref) function is called on each argument to broadcast, allowing -it to return something different that supports `axes` and indexing if it does not. By +it to return something different that supports `axes` and indexing. By default, this is the identity function for all `AbstractArray`s and `Number`s — they already support `axes` and indexing. For a handful of other types (including but not limited to types themselves, functions, special singletons like `missing` and `nothing`, and dates), `Base.broadcastable` returns the argument wrapped in a `Ref` to act as a 0-dimensional "scalar" for the purposes of broadcasting. Custom types can similarly specialize `Base.broadcastable` to define their shape, but they should follow the convention that -`collect(Base.broadcastable(x)) == collect(x)`. A notable exception are `AbstractString`s; -they are special-cased to behave as scalars for the purposes of broadcast even though they -are iterable collections of their characters. +`collect(Base.broadcastable(x)) == collect(x)`. A notable exception is `AbstractString`; +strings are special-cased to behave as scalars for the purposes of broadcast even though +they are iterable collections of their characters. The next two steps (selecting the output array and implementation) are dependent upon determining a single answer for a given set of arguments. Broadcast must take all the varied @@ -483,12 +483,11 @@ styles into a single answer — the "destination style". ### Broadcast Styles -`Base.BroadcastStyle` is the abstract type from which all styles are -derived. When used as a function it has two possible forms, -unary (single-argument) and binary. -The unary variant states that you intend to -implement specific broadcasting behavior and/or output type, -and do not wish to rely on the default fallback ([`Broadcast.DefaultArrayStyle`](@ref)). +`Base.BroadcastStyle` is the abstract type from which all broadcast styles are derived. When used as a +function it has two possible forms, unary (single-argument) and binary. The unary variant states +that you intend to implement specific broadcasting behavior and/or output type, and do not wish to +rely on the default fallback [`Broadcast.DefaultArrayStyle`](@ref). + To override these defaults, you can define a custom `BroadcastStyle` for your object: ```julia @@ -507,27 +506,30 @@ leverage one of the general broadcast wrappers: When your broadcast operation involves several arguments, individual argument styles get combined to determine a single `DestStyle` that controls the type of the output container. -For more detail, see [below](@ref writing-binary-broadcasting-rules). +For more details, see [below](@ref writing-binary-broadcasting-rules). ### Selecting an appropriate output array -The actual allocation of the result array is handled by `Base.broadcast_similar`: +The broadcast style is computed for every broadcasting operation to allow for +dispatch and specialization. The actual allocation of the result array is +handled by `Base.broadcast_similar`, using this style as its first argument. ```julia -Base.broadcast_similar(f, ::DestStyle, ::Type{ElType}, inds, As...) +Base.broadcast_similar(::DestStyle, ::Type{ElType}, inds, bc) ``` -`f` is the operation being performed and `DestStyle` signals the final result from -combining the input styles. -`As...` is the list of input objects. You may not need to use `f` or `As...` -unless they help you build the appropriate object; the fallback definition is +The fallback definition is ```julia -broadcast_similar(f, ::DefaultArrayStyle{N}, ::Type{ElType}, inds::Indices{N}, As...) where {N,ElType} = +broadcast_similar(::DefaultArrayStyle{N}, ::Type{ElType}, inds::Indices{N}, bc) where {N,ElType} = similar(Array{ElType}, inds) ``` -However, if needed you can specialize on any or all of these arguments. +However, if needed you can specialize on any or all of these arguments. The final argument +`bc` is a lazy representation of a (potentially fused) broadcast operation, a `Broadcasted` +object. For these purposes, the most important fields of the wrapper are +`f` and `args`, describing the function and argument list, respectively. Note that the argument +list can — and often does — include other nested `Broadcasted` wrappers. For a complete example, let's say you have created a type, `ArrayAndChar`, that stores an array and a single character: @@ -553,20 +555,21 @@ Base.BroadcastStyle(::Type{<:ArrayAndChar}) = Broadcast.ArrayStyle{ArrayAndChar} ``` -This forces us to also define a `broadcast_similar` method: -```jldoctest ArrayAndChar; filter = r"(^find_aac \(generic function with 2 methods\)$|^$)" -function Base.broadcast_similar(f, ::Broadcast.ArrayStyle{ArrayAndChar}, ::Type{ElType}, inds, As...) where ElType +This means we must also define a corresponding `broadcast_similar` method: +```jldoctest +function Base.broadcast_similar(::Broadcast.ArrayStyle{ArrayAndChar}, ::Type{ElType}, inds, bc) where ElType # Scan the inputs for the ArrayAndChar: - A = find_aac(As...) + A = find_aac(bc) # Use the char field of A to create the output ArrayAndChar(similar(Array{ElType}, inds), A.char) end -"`A = find_aac(As...)` returns the first ArrayAndChar among the arguments." -find_aac(A::ArrayAndChar, B...) = A -find_aac(A, B...) = find_aac(B...); -# output - +"`A = find_aac(As)` returns the first ArrayAndChar among the arguments." +find_aac(bc::Base.Broadcast.Broadcasted) = find_aac(bc.args) +find_aac(args::Tuple) = find_aac(find_aac(args[1]), Base.tail(args)) +find_aac(x) = x +find_aac(a::ArrayAndChar, rest) = a +find_aac(::Any, rest) = find_aac(rest) ``` From these definitions, one obtains the following behavior: @@ -589,58 +592,86 @@ julia> a .+ [5,10] ### [Extending broadcast with custom implementations](@id extending-in-place-broadcast) -Finally, it's worth noting that sometimes it's easier simply to bypass the machinery for -computing result types and container sizes, and just do everything manually. For example, -you can convert a `UnitRange{Int}` `r` to a `UnitRange{BigInt}` with `big.(r)`; the definition -of this method is approximately +In general, a broadcast operation is represented by a lazy `Broadcasted` container that holds onto +the function to be applied alongside its arguments. Those arguments may themselves be more nested +`Broadcasted` containers, forming a large expression tree to be evaluated. A nested tree of +`Broadcasted` containers is directly constructed by the implicit dot syntax; `5 .+ 2.*x` is +transiently represented by `Broadcasted(+, 5, Broadcasted(*, 2, x))`, for example. This is +invisible to users as it is immediately realized through a call to `copy`, but it is this container +that provides the basis for broadcast's extensibility for authors of custom types. The built-in +broadcast machinery will then determine the result type and size based upon the arguments, allocate +it, and then finally copy the realization of the `Broadcasted` object into it with a default +`copyto!(::AbstractArray, ::Broadcasted)` method. The built-in fallback `broadcast` and +`broadcast!` methods similarly construct a transient `Broadcasted` representation of the operation +so they can follow the same codepath. This allows custom array implementations to +provide their own `copyto!` specialization to customize and +optimize broadcasting. This is again determined by the computed broadcast style. This is such +an important part of the operation that it is stored as the first type parameter of the +`Broadcasted` type, allowing for dispatch and specialization. + +For some types, the machinery to "fuse" operations across nested levels of broadcasting +is not available or could be done more efficiently incrementally. In such cases, you may +need or want to evaluate `x .* (x .+ 1)` as if it had been +written `broadcast(*, x, broadcast(+, x, 1))`, where the inner operation is evaluated before +tackling the outer operation. This sort of eager operation is directly supported by a bit +of indirection; instead of directly constructing `Broadcasted` objects, Julia lowers the +fused expression `x .* (x .+ 1)` to `Broadcast.broadcasted(*, x, Broadcast.broadcasted(+, x, 1))`. Now, +by default, `broadcasted` just calls the `Broadcasted` constructor to create the lazy representation +of the fused expression tree, but you can choose to override it for a particular combination +of function and arguments. + +As an example, the builtin `AbstractRange` objects use this machinery to optimize pieces +of broadcasted expressions that can be eagerly evaluated purely in terms of the start, +step, and length (or stop) instead of computing every single element. Just like all the +other machinery, `broadcasted` also computes and exposes the combined broadcast style of its +arguments, so instead of specializing on `broadcasted(f, args...)`, you can specialize on +`broadcasted(::DestStyle, f, args...)` for any combination of style, function, and arguments. + +For example, the following definition supports the negation of ranges: ```julia -Broadcast.broadcast(::typeof(big), r::UnitRange) = big(first(r)):big(last(r)) +broadcasted(::DefaultArrayStyle{1}, ::typeof(-), r::OrdinalRange) = range(-first(r), step=-step(r), length=length(r)) ``` -This exploits Julia's ability to dispatch on a particular function type. (This kind of -explicit definition can indeed be necessary if the output container does not support `setindex!`.) -You can optionally choose to implement the actual broadcasting yourself, but allow -the internal machinery to compute the container type, element type, and indices by specializing - -```julia -Broadcast.broadcast(::typeof(somefunction), ::MyStyle, ::Type{ElType}, inds, As...) -``` +### [Extending in-place broadcasting](@id extending-in-place-broadcast) -Extending `broadcast!` (in-place broadcast) should be done with care, as it is easy to introduce -ambiguities between packages. To avoid these ambiguities, we adhere to the following conventions. - -First, if you want to specialize on the destination type, say `DestType`, then you should -define a method with the following signature: +In-place broadcasting can be supported by defining the appropriate `copyto!(dest, bc::Broadcasted)` +method. Because you might want to specialize either on `dest` or the specific subtype of `bc`, +to avoid ambiguities between packages we recommend the following convention. +If you wish to specialize on a particular style `DestStyle`, define a method for ```julia -broadcast!(f, dest::DestType, ::Nothing, As...) +copyto!(dest, bc::Broadcasted{DestStyle}) ``` +Optionally, with this form you can also specialize on the type of `dest`. -Note that no bounds should be placed on the types of `f` and `As...`. - -Second, if specialized `broadcast!` behavior is desired depending on the input types, -you should write [binary broadcasting rules](@ref writing-binary-broadcasting-rules) to -determine a custom `BroadcastStyle` given the input types, say `MyBroadcastStyle`, and you should define a method with the following -signature: +If instead you want to specialize on the destination type `DestType` without specializing +on `DestStyle`, then you should define a method with the following signature: ```julia -broadcast!(f, dest, ::MyBroadcastStyle, As...) +copyto!(dest::DestType, bc::Broadcasted{Nothing}) ``` -Note the lack of bounds on `f`, `dest`, and `As...`. +This leverages a fallback implementation of `copyto!` that converts the wrapper into a +`Broadcasted{Nothing}`. Consequently, specializing on `DestType` has lower precedence than +methods that specialize on `DestStyle`. -Third, simultaneously specializing on both the type of `dest` and the `BroadcastStyle` is fine. In this case, -it is also allowed to specialize on the types of the source arguments (`As...`). For example, these method signatures are OK: +Similarly, you can completely override out-of-place broadcasting with a `copy(::Broadcasted)` +method. -```julia -broadcast!(f, dest::DestType, ::MyBroadcastStyle, As...) -broadcast!(f, dest::DestType, ::MyBroadcastStyle, As::AbstractArray...) -broadcast!(f, dest::DestType, ::Broadcast.DefaultArrayStyle{0}, As::Number...) -``` +#### Working with `Broadcasted` objects + +In order to implement such a `copy` or `copyto!`, method, of course, you must +work with the `Broadcasted` wrapper to compute each element. There are two main +ways of doing so: +* `Broadcast.flatten` recomputes the potentially nested operation into a single + function and flat list of arguments. You are responsible for implementing the + broadcasting shape rules yourself, but this may be helpful in limited situations. +* Iterating over the `CartesianIndices` of the `axes(::Broadcasted)` and using + indexing with the resulting `CartesianIndex` object to compute the result. -#### [Writing binary broadcasting rules](@id writing-binary-broadcasting-rules) +### [Writing binary broadcasting rules](@id writing-binary-broadcasting-rules) The precedence rules are defined by binary `BroadcastStyle` calls: From c1ec612fb518d5e1ca50d1e2966b1e646bf6f5e7 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Sat, 5 May 2018 08:49:40 +0900 Subject: [PATCH 022/153] update Julia Commit ee2211c1b6 --- codex/NEWS.md | 21 ++++- codex/base/arrays.md | 3 +- codex/base/base.md | 1 + codex/base/math.md | 3 +- codex/manual/stacktraces.md | 169 +++++++++++++++++------------------- codex/stdlib/Logging.md | 24 ++--- src/NEWS.md | 21 ++++- src/base/arrays.md | 3 +- src/base/base.md | 1 + src/base/math.md | 3 +- src/manual/stacktraces.md | 169 +++++++++++++++++------------------- src/stdlib/Logging.md | 24 ++--- 12 files changed, 228 insertions(+), 214 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index 1450a02..b9bcc06 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -697,6 +697,18 @@ Deprecated or removed `Matrix{Int}(undef, (2, 4))`, and `Array{Float32,3}(11, 13, 17)` is now `Array{Float32,3}(undef, 11, 13, 17)` ([#24781](https://github.com/JuliaLang/julia/issues/24781)). + * Previously `setindex!(A, x, I...)` (and the syntax `A[I...] = x`) supported two + different modes of operation when supplied with a set of non-scalar indices `I` + (e.g., at least one index is an `AbstractArray`) depending upon the value of `x` + on the right hand side. If `x` is an `AbstractArray`, its _contents_ are copied + elementwise into the locations in `A` selected by `I` and it must have the same + number of elements as `I` selects locations. Otherwise, if `x` is not an + `AbstractArray`, then its _value_ is implicitly broadcast to all locations to + all locations in `A` selected by `I`. This latter behavior—implicitly broadcasting + "scalar"-like values across many locations—is now deprecated in favor of explicitly + using the broadcasted assignment syntax `A[I...] .= x` or `fill!(view(A, I...), x)` + ([#26347](https://github.com/JuliaLang/julia/issues/26347)). + * `LinAlg.fillslots!` has been renamed `LinAlg.fillstored!` ([#25030](https://github.com/JuliaLang/julia/issues/25030)). * `fill!(A::Diagonal, x)` and `fill!(A::AbstractTriangular, x)` have been deprecated @@ -713,9 +725,9 @@ Deprecated or removed * `slicedim(A, d, i)` has been deprecated in favor of `copy(selectdim(A, d, i))`. The new `selectdim` function now always returns a view into `A`; in many cases the `copy` is not necessary. Previously, `slicedim` on a vector `V` over dimension `d=1` and scalar - index `i` would return the just selected element (unless `V` was a `BitVector`). This - has now been made consistent: `selectdim` now always returns a view into the original - array, with a zero-dimensional view in this specific case ([#26009](https://github.com/JuliaLang/julia/issues/26009)). + index `i` would return the just selected element (unless `V` was a `BitVector`). This + has now been made consistent: `selectdim` now always returns a view into the original + array, with a zero-dimensional view in this specific case ([#26009](https://github.com/JuliaLang/julia/issues/26009)). * `whos` has been renamed `varinfo`, and now returns a markdown table instead of printing output ([#12131](https://github.com/JuliaLang/julia/issues/12131)). @@ -947,6 +959,9 @@ Deprecated or removed * `map` on dictionaries previously operated on `key=>value` pairs. This behavior is deprecated, and in the future `map` will operate only on values ([#5794](https://github.com/JuliaLang/julia/issues/5794)). + * `map` on sets previously returned a `Set`, possibly changing the order or number of elements. This + behavior is deprecated and in the future `map` will preserve order and number of elements ([#26980](https://github.com/JuliaLang/julia/issues/26980)). + * Previously, broadcast defaulted to treating its arguments as scalars if they were not arrays. This behavior is deprecated, and in the future `broadcast` will default to iterating over all its arguments. Wrap arguments you wish to be treated as scalars with diff --git a/codex/base/arrays.md b/codex/base/arrays.md index 2b1a8d7..9041a81 100644 --- a/codex/base/arrays.md +++ b/codex/base/arrays.md @@ -30,8 +30,7 @@ Base.trues Base.falses Base.fill Base.fill! -Base.similar(::AbstractArray) -Base.similar(::Any, ::Tuple) +Base.similar ``` ## Basic functions diff --git a/codex/base/base.md b/codex/base/base.md index 69cc4bc..83ccc83 100644 --- a/codex/base/base.md +++ b/codex/base/base.md @@ -316,6 +316,7 @@ Base.AsyncCondition(::Function) ```@docs Base.nameof(::Module) Base.parentmodule +Base.moduleroot Base.@__MODULE__ Base.fullname Base.names diff --git a/codex/base/math.md b/codex/base/math.md index 46b3fc1..df67d02 100644 --- a/codex/base/math.md +++ b/codex/base/math.md @@ -122,12 +122,11 @@ Base.Rounding.RoundNearestTiesUp Base.Rounding.RoundToZero Base.Rounding.RoundUp Base.Rounding.RoundDown -Base.round{T <: AbstractFloat, MR, MI}(::Complex{T}, ::RoundingMode{MR}, ::RoundingMode{MI}) +Base.round(::Complex{<: AbstractFloat}, ::RoundingMode, ::RoundingMode) Base.ceil Base.floor Base.trunc Base.unsafe_trunc -Base.signif Base.min Base.max Base.minmax diff --git a/codex/manual/stacktraces.md b/codex/manual/stacktraces.md index 2cc3d3a..776570d 100644 --- a/codex/manual/stacktraces.md +++ b/codex/manual/stacktraces.md @@ -8,12 +8,13 @@ easy to use programmatically. The primary function used to obtain a stack trace is [`stacktrace`](@ref): ```julia-repl -julia> stacktrace() -4-element Array{StackFrame,1}: - eval(::Module, ::Any) at boot.jl:236 - eval_user_input(::Any, ::Base.REPL.REPLBackend) at REPL.jl:66 - macro expansion at REPL.jl:97 [inlined] - (::Base.REPL.##1#2{Base.REPL.REPLBackend})() at event.jl:73 +6-element Array{Base.StackTraces.StackFrame,1}: + top-level scope + eval at boot.jl:317 [inlined] + eval(::Module, ::Expr) at REPL.jl:5 + eval_user_input(::Any, ::REPL.REPLBackend) at REPL.jl:85 + macro expansion at REPL.jl:116 [inlined] + (::getfield(REPL, Symbol("##28#29")){REPL.REPLBackend})() at event.jl:92 ``` Calling [`stacktrace()`](@ref) returns a vector of [`StackTraces.StackFrame`](@ref) s. For ease of use, the @@ -25,9 +26,10 @@ julia> example() = stacktrace() example (generic function with 1 method) julia> example() -5-element Array{StackFrame,1}: +7-element Array{Base.StackTraces.StackFrame,1}: example() at REPL[1]:1 - eval(::Module, ::Any) at boot.jl:236 + top-level scope + eval at boot.jl:317 [inlined] [...] julia> @noinline child() = stacktrace() @@ -40,14 +42,14 @@ julia> grandparent() = parent() grandparent (generic function with 1 method) julia> grandparent() -7-element Array{StackFrame,1}: +9-element Array{Base.StackTraces.StackFrame,1}: child() at REPL[3]:1 parent() at REPL[4]:1 grandparent() at REPL[5]:1 [...] ``` -Note that when calling [`stacktrace()`](@ref) you'll typically see a frame with `eval(...) at boot.jl`. +Note that when calling [`stacktrace()`](@ref) you'll typically see a frame with `eval at boot.jl`. When calling [`stacktrace()`](@ref) from the REPL you'll also have a few extra frames in the stack from `REPL.jl`, usually looking something like this: @@ -56,12 +58,14 @@ julia> example() = stacktrace() example (generic function with 1 method) julia> example() -5-element Array{StackFrame,1}: +7-element Array{Base.StackTraces.StackFrame,1}: example() at REPL[1]:1 - eval(::Module, ::Any) at boot.jl:236 - eval_user_input(::Any, ::Base.REPL.REPLBackend) at REPL.jl:66 - macro expansion at REPL.jl:97 [inlined] - (::Base.REPL.##1#2{Base.REPL.REPLBackend})() at event.jl:73 + top-level scope + eval at boot.jl:317 [inlined] + eval(::Module, ::Expr) at REPL.jl:5 + eval_user_input(::Any, ::REPL.REPLBackend) at REPL.jl:85 + macro expansion at REPL.jl:116 [inlined] + (::getfield(REPL, Symbol("##28#29")){REPL.REPLBackend})() at event.jl:92 ``` ## Extracting useful information @@ -72,17 +76,17 @@ default C functions do not appear in the stack trace), and an integer representa returned by [`backtrace`](@ref): ```julia-repl -julia> top_frame = stacktrace()[1] -eval(::Module, ::Expr) at REPL.jl:3 +julia> frame = stacktrace()[3] +eval(::Module, ::Expr) at REPL.jl:5 -julia> top_frame.func +julia> frame.func :eval -julia> top_frame.file -Symbol("./boot.jl") +julia> frame.file +Symbol("~/julia/usr/share/julia/stdlib/v0.7/REPL/src/REPL.jl") -julia> top_frame.line -236 +julia> frame.line +5 julia> top_frame.linfo MethodInstance for eval(::Module, ::Expr) @@ -96,7 +100,7 @@ false ```julia-repl julia> top_frame.pointer -0x00007f390d152a59 +0x00007f92d6293171 ``` This makes stack trace information available programmatically for logging, error handling, and @@ -119,9 +123,10 @@ julia> @noinline example() = try example (generic function with 1 method) julia> example() -5-element Array{StackFrame,1}: +7-element Array{Base.StackTraces.StackFrame,1}: example() at REPL[2]:4 - eval(::Module, ::Any) at boot.jl:236 + top-level scope + eval at boot.jl:317 [inlined] [...] ``` @@ -147,7 +152,7 @@ julia> @noinline example() = try example (generic function with 1 method) julia> example() -6-element Array{StackFrame,1}: +8-element Array{Base.StackTraces.StackFrame,1}: bad_function() at REPL[1]:1 example() at REPL[2]:2 [...] @@ -174,7 +179,8 @@ grandparent (generic function with 1 method) julia> grandparent() ERROR: Whoops! -7-element Array{StackFrame,1}: +10-element Array{Base.StackTraces.StackFrame,1}: + error at error.jl:33 [inlined] child() at REPL[1]:1 parent() at REPL[2]:1 grandparent() at REPL[3]:3 @@ -183,77 +189,63 @@ ERROR: Whoops! ## Comparison with [`backtrace`](@ref) -A call to [`backtrace`](@ref) returns a vector of `Ptr{Cvoid}`, which may then be passed into +A call to [`backtrace`](@ref) returns a vector of `Union{Ptr{Nothing}, Base.InterpreterIP}`, which may then be passed into [`stacktrace`](@ref) for translation: ```julia-repl julia> trace = backtrace() -21-element Array{Ptr{Cvoid},1}: - Ptr{Cvoid} @0x00007f10049d5b2f - Ptr{Cvoid} @0x00007f0ffeb4d29c - Ptr{Cvoid} @0x00007f0ffeb4d2a9 - Ptr{Cvoid} @0x00007f1004993fe7 - Ptr{Cvoid} @0x00007f10049a92be - Ptr{Cvoid} @0x00007f10049a823a - Ptr{Cvoid} @0x00007f10049a9fb0 - Ptr{Cvoid} @0x00007f10049aa718 - Ptr{Cvoid} @0x00007f10049c0d5e - Ptr{Cvoid} @0x00007f10049a3286 - Ptr{Cvoid} @0x00007f0ffe9ba3ba - Ptr{Cvoid} @0x00007f0ffe9ba3d0 - Ptr{Cvoid} @0x00007f1004993fe7 - Ptr{Cvoid} @0x00007f0ded34583d - Ptr{Cvoid} @0x00007f0ded345a87 - Ptr{Cvoid} @0x00007f1004993fe7 - Ptr{Cvoid} @0x00007f0ded34308f - Ptr{Cvoid} @0x00007f0ded343320 - Ptr{Cvoid} @0x00007f1004993fe7 - Ptr{Cvoid} @0x00007f10049aeb67 - Ptr{Cvoid} @0x0000000000000000 +18-element Array{Union{Ptr{Nothing}, Base.InterpreterIP},1}: + Ptr{Nothing} @0x00007fd8734c6209 + Ptr{Nothing} @0x00007fd87362b342 + Ptr{Nothing} @0x00007fd87362c136 + Ptr{Nothing} @0x00007fd87362c986 + Ptr{Nothing} @0x00007fd87362d089 + Base.InterpreterIP(CodeInfo(:(begin + Core.SSAValue(0) = backtrace() + trace = Core.SSAValue(0) + return Core.SSAValue(0) + end)), 0x0000000000000000) + Ptr{Nothing} @0x00007fd87362e4cf +[...] julia> stacktrace(trace) -5-element Array{StackFrame,1}: - backtrace() at error.jl:46 - eval(::Module, ::Any) at boot.jl:236 - eval_user_input(::Any, ::Base.REPL.REPLBackend) at REPL.jl:66 - macro expansion at REPL.jl:97 [inlined] - (::Base.REPL.##1#2{Base.REPL.REPLBackend})() at event.jl:73 +6-element Array{Base.StackTraces.StackFrame,1}: + top-level scope + eval at boot.jl:317 [inlined] + eval(::Module, ::Expr) at REPL.jl:5 + eval_user_input(::Any, ::REPL.REPLBackend) at REPL.jl:85 + macro expansion at REPL.jl:116 [inlined] + (::getfield(REPL, Symbol("##28#29")){REPL.REPLBackend})() at event.jl:92 ``` -Notice that the vector returned by [`backtrace`](@ref) had 21 pointers, while the vector returned -by [`stacktrace`](@ref) only has 5. This is because, by default, [`stacktrace`](@ref) removes +Notice that the vector returned by [`backtrace`](@ref) had 18 elements, while the vector returned +by [`stacktrace`](@ref) only has 6. This is because, by default, [`stacktrace`](@ref) removes any lower-level C functions from the stack. If you want to include stack frames from C calls, you can do it like this: ```julia-repl julia> stacktrace(trace, true) -27-element Array{StackFrame,1}: - jl_backtrace_from_here at stackwalk.c:103 - backtrace() at error.jl:46 - backtrace() at sys.so:? - jl_call_method_internal at julia_internal.h:248 [inlined] - jl_apply_generic at gf.c:2215 - do_call at interpreter.c:75 - eval at interpreter.c:215 - eval_body at interpreter.c:519 - jl_interpret_toplevel_thunk at interpreter.c:664 - jl_toplevel_eval_flex at toplevel.c:592 - jl_toplevel_eval_in at builtins.c:614 - eval(::Module, ::Any) at boot.jl:236 - eval(::Module, ::Any) at sys.so:? - jl_call_method_internal at julia_internal.h:248 [inlined] - jl_apply_generic at gf.c:2215 - eval_user_input(::Any, ::Base.REPL.REPLBackend) at REPL.jl:66 - ip:0x7f1c707f1846 - jl_call_method_internal at julia_internal.h:248 [inlined] - jl_apply_generic at gf.c:2215 - macro expansion at REPL.jl:97 [inlined] - (::Base.REPL.##1#2{Base.REPL.REPLBackend})() at event.jl:73 - ip:0x7f1c707ea1ef - jl_call_method_internal at julia_internal.h:248 [inlined] - jl_apply_generic at gf.c:2215 - jl_apply at julia.h:1411 [inlined] - start_task at task.c:261 +21-element Array{Base.StackTraces.StackFrame,1}: + jl_apply_generic at gf.c:2167 + do_call at interpreter.c:324 + eval_value at interpreter.c:416 + eval_body at interpreter.c:559 + jl_interpret_toplevel_thunk_callback at interpreter.c:798 + top-level scope + jl_interpret_toplevel_thunk at interpreter.c:807 + jl_toplevel_eval_flex at toplevel.c:856 + jl_toplevel_eval_in at builtins.c:624 + eval at boot.jl:317 [inlined] + eval(::Module, ::Expr) at REPL.jl:5 + jl_apply_generic at gf.c:2167 + eval_user_input(::Any, ::REPL.REPLBackend) at REPL.jl:85 + jl_apply_generic at gf.c:2167 + macro expansion at REPL.jl:116 [inlined] + (::getfield(REPL, Symbol("##28#29")){REPL.REPLBackend})() at event.jl:92 + jl_fptr_trampoline at gf.c:1838 + jl_apply_generic at gf.c:2167 + jl_apply at julia.h:1540 [inlined] + start_task at task.c:268 ip:0xffffffffffffffff ``` @@ -264,9 +256,10 @@ s by passing them into [`StackTraces.lookup`](@ref): julia> pointer = backtrace()[1]; julia> frame = StackTraces.lookup(pointer) -1-element Array{StackFrame,1}: - jl_backtrace_from_here at stackwalk.c:103 +1-element Array{Base.StackTraces.StackFrame,1}: + jl_apply_generic at gf.c:2167 julia> println("The top frame is from $(frame[1].func)!") -The top frame is from jl_backtrace_from_here! +The top frame is from jl_apply_generic! ``` + diff --git a/codex/stdlib/Logging.md b/codex/stdlib/Logging.md index 6c170f5..fe8a44b 100644 --- a/codex/stdlib/Logging.md +++ b/codex/stdlib/Logging.md @@ -131,7 +131,7 @@ There are three logger types provided by the library. [`ConsoleLogger`](@ref) is the default logger you see when starting the REPL. It displays events in a readable text format and tries to give simple but user friendly control over formatting and filtering. [`NullLogger`](@ref) is a convenient way to drop all -messages where necessary; it is the logging equivalent of the [`DevNull`](@ref) +messages where necessary; it is the logging equivalent of the [`devnull`](@ref) stream. [`SimpleLogger`](@ref) is a very simplistic text formatting logger, mainly useful for debugging the logging system itself. @@ -147,15 +147,15 @@ messages that will be discarded: [`disable_logging`](@ref)). This is a crude but extremely cheap global setting. 2. The current logger state is looked up and the message level checked against the - logger's cached minimum level, as found by calling [`min_enabled_level`](@ref). + logger's cached minimum level, as found by calling [`Logging.min_enabled_level`](@ref). This behavior can be overridden via environment variables (more on this later). -3. The [`shouldlog`](@ref) function is called with the current logger, taking +3. The [`Logging.shouldlog`](@ref) function is called with the current logger, taking some minimal information (level, module, group, id) which can be computed statically. Most usefully, `shouldlog` is passed an event `id` which can be used to discard events early based on a cached predicate. If all these checks pass, the message and key--value pairs are evaluated in full -and passed to the current logger via the [`handle_message`](@ref) function. +and passed to the current logger via the [`Logging.handle_message`](@ref) function. `handle_message()` may perform additional filtering as required and display the event to the screen, save it to a file, etc. @@ -163,7 +163,7 @@ Exceptions that occur while generating the log event are captured and logged by default. This prevents individual broken events from crashing the application, which is helpful when enabling little-used debug events in a production system. This behavior can be customized per logger type by -extending [`catch_exceptions`](@ref). +extending [`Logging.catch_exceptions`](@ref). ## Testing log events @@ -208,13 +208,13 @@ Logging.LogLevel Event processing is controlled by overriding functions associated with `AbstractLogger`: -| Methods to implement |   | Brief description | -|:----------------------------- |:---------------------- |:---------------------------------------- | -| [`handle_message`](@ref) | | Handle a log event | -| [`shouldlog`](@ref) | | Early filtering of events | -| [`min_enabled_level`](@ref) | | Lower bound for log level of accepted events | -| **Optional methods** | **Default definition** | **Brief description** | -| [`catch_exceptions`](@ref) | `true` | Catch exceptions during event evaluation | +| Methods to implement | | Brief description | +|:----------------------------------- |:---------------------- |:---------------------------------------- | +| [`Logging.handle_message`](@ref) | | Handle a log event | +| [`Logging.shouldlog`](@ref) | | Early filtering of events | +| [`Logging.min_enabled_level`](@ref) | | Lower bound for log level of accepted events | +| **Optional methods** | **Default definition** | **Brief description** | +| [`Logging.catch_exceptions`](@ref) | `true` | Catch exceptions during event evaluation | ```@docs diff --git a/src/NEWS.md b/src/NEWS.md index 8bc35d5..f205e0b 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -684,6 +684,18 @@ Deprecated or removed `Matrix{Int}(undef, (2, 4))`, and `Array{Float32,3}(11, 13, 17)` is now `Array{Float32,3}(undef, 11, 13, 17)` ([#24781](https://github.com/JuliaLang/julia/issues/24781)). + * Previously `setindex!(A, x, I...)` (and the syntax `A[I...] = x`) supported two + different modes of operation when supplied with a set of non-scalar indices `I` + (e.g., at least one index is an `AbstractArray`) depending upon the value of `x` + on the right hand side. If `x` is an `AbstractArray`, its _contents_ are copied + elementwise into the locations in `A` selected by `I` and it must have the same + number of elements as `I` selects locations. Otherwise, if `x` is not an + `AbstractArray`, then its _value_ is implicitly broadcast to all locations to + all locations in `A` selected by `I`. This latter behavior—implicitly broadcasting + "scalar"-like values across many locations—is now deprecated in favor of explicitly + using the broadcasted assignment syntax `A[I...] .= x` or `fill!(view(A, I...), x)` + ([#26347](https://github.com/JuliaLang/julia/issues/26347)). + * `LinAlg.fillslots!` has been renamed `LinAlg.fillstored!` ([#25030](https://github.com/JuliaLang/julia/issues/25030)). * `fill!(A::Diagonal, x)` and `fill!(A::AbstractTriangular, x)` have been deprecated @@ -700,9 +712,9 @@ Deprecated or removed * `slicedim(A, d, i)` has been deprecated in favor of `copy(selectdim(A, d, i))`. The new `selectdim` function now always returns a view into `A`; in many cases the `copy` is not necessary. Previously, `slicedim` on a vector `V` over dimension `d=1` and scalar - index `i` would return the just selected element (unless `V` was a `BitVector`). This - has now been made consistent: `selectdim` now always returns a view into the original - array, with a zero-dimensional view in this specific case ([#26009](https://github.com/JuliaLang/julia/issues/26009)). + index `i` would return the just selected element (unless `V` was a `BitVector`). This + has now been made consistent: `selectdim` now always returns a view into the original + array, with a zero-dimensional view in this specific case ([#26009](https://github.com/JuliaLang/julia/issues/26009)). * `whos` has been renamed `varinfo`, and now returns a markdown table instead of printing output ([#12131](https://github.com/JuliaLang/julia/issues/12131)). @@ -934,6 +946,9 @@ Deprecated or removed * `map` on dictionaries previously operated on `key=>value` pairs. This behavior is deprecated, and in the future `map` will operate only on values ([#5794](https://github.com/JuliaLang/julia/issues/5794)). + * `map` on sets previously returned a `Set`, possibly changing the order or number of elements. This + behavior is deprecated and in the future `map` will preserve order and number of elements ([#26980](https://github.com/JuliaLang/julia/issues/26980)). + * Previously, broadcast defaulted to treating its arguments as scalars if they were not arrays. This behavior is deprecated, and in the future `broadcast` will default to iterating over all its arguments. Wrap arguments you wish to be treated as scalars with diff --git a/src/base/arrays.md b/src/base/arrays.md index 2b1a8d7..9041a81 100644 --- a/src/base/arrays.md +++ b/src/base/arrays.md @@ -30,8 +30,7 @@ Base.trues Base.falses Base.fill Base.fill! -Base.similar(::AbstractArray) -Base.similar(::Any, ::Tuple) +Base.similar ``` ## Basic functions diff --git a/src/base/base.md b/src/base/base.md index 69cc4bc..83ccc83 100644 --- a/src/base/base.md +++ b/src/base/base.md @@ -316,6 +316,7 @@ Base.AsyncCondition(::Function) ```@docs Base.nameof(::Module) Base.parentmodule +Base.moduleroot Base.@__MODULE__ Base.fullname Base.names diff --git a/src/base/math.md b/src/base/math.md index 46b3fc1..df67d02 100644 --- a/src/base/math.md +++ b/src/base/math.md @@ -122,12 +122,11 @@ Base.Rounding.RoundNearestTiesUp Base.Rounding.RoundToZero Base.Rounding.RoundUp Base.Rounding.RoundDown -Base.round{T <: AbstractFloat, MR, MI}(::Complex{T}, ::RoundingMode{MR}, ::RoundingMode{MI}) +Base.round(::Complex{<: AbstractFloat}, ::RoundingMode, ::RoundingMode) Base.ceil Base.floor Base.trunc Base.unsafe_trunc -Base.signif Base.min Base.max Base.minmax diff --git a/src/manual/stacktraces.md b/src/manual/stacktraces.md index 2cc3d3a..776570d 100644 --- a/src/manual/stacktraces.md +++ b/src/manual/stacktraces.md @@ -8,12 +8,13 @@ easy to use programmatically. The primary function used to obtain a stack trace is [`stacktrace`](@ref): ```julia-repl -julia> stacktrace() -4-element Array{StackFrame,1}: - eval(::Module, ::Any) at boot.jl:236 - eval_user_input(::Any, ::Base.REPL.REPLBackend) at REPL.jl:66 - macro expansion at REPL.jl:97 [inlined] - (::Base.REPL.##1#2{Base.REPL.REPLBackend})() at event.jl:73 +6-element Array{Base.StackTraces.StackFrame,1}: + top-level scope + eval at boot.jl:317 [inlined] + eval(::Module, ::Expr) at REPL.jl:5 + eval_user_input(::Any, ::REPL.REPLBackend) at REPL.jl:85 + macro expansion at REPL.jl:116 [inlined] + (::getfield(REPL, Symbol("##28#29")){REPL.REPLBackend})() at event.jl:92 ``` Calling [`stacktrace()`](@ref) returns a vector of [`StackTraces.StackFrame`](@ref) s. For ease of use, the @@ -25,9 +26,10 @@ julia> example() = stacktrace() example (generic function with 1 method) julia> example() -5-element Array{StackFrame,1}: +7-element Array{Base.StackTraces.StackFrame,1}: example() at REPL[1]:1 - eval(::Module, ::Any) at boot.jl:236 + top-level scope + eval at boot.jl:317 [inlined] [...] julia> @noinline child() = stacktrace() @@ -40,14 +42,14 @@ julia> grandparent() = parent() grandparent (generic function with 1 method) julia> grandparent() -7-element Array{StackFrame,1}: +9-element Array{Base.StackTraces.StackFrame,1}: child() at REPL[3]:1 parent() at REPL[4]:1 grandparent() at REPL[5]:1 [...] ``` -Note that when calling [`stacktrace()`](@ref) you'll typically see a frame with `eval(...) at boot.jl`. +Note that when calling [`stacktrace()`](@ref) you'll typically see a frame with `eval at boot.jl`. When calling [`stacktrace()`](@ref) from the REPL you'll also have a few extra frames in the stack from `REPL.jl`, usually looking something like this: @@ -56,12 +58,14 @@ julia> example() = stacktrace() example (generic function with 1 method) julia> example() -5-element Array{StackFrame,1}: +7-element Array{Base.StackTraces.StackFrame,1}: example() at REPL[1]:1 - eval(::Module, ::Any) at boot.jl:236 - eval_user_input(::Any, ::Base.REPL.REPLBackend) at REPL.jl:66 - macro expansion at REPL.jl:97 [inlined] - (::Base.REPL.##1#2{Base.REPL.REPLBackend})() at event.jl:73 + top-level scope + eval at boot.jl:317 [inlined] + eval(::Module, ::Expr) at REPL.jl:5 + eval_user_input(::Any, ::REPL.REPLBackend) at REPL.jl:85 + macro expansion at REPL.jl:116 [inlined] + (::getfield(REPL, Symbol("##28#29")){REPL.REPLBackend})() at event.jl:92 ``` ## Extracting useful information @@ -72,17 +76,17 @@ default C functions do not appear in the stack trace), and an integer representa returned by [`backtrace`](@ref): ```julia-repl -julia> top_frame = stacktrace()[1] -eval(::Module, ::Expr) at REPL.jl:3 +julia> frame = stacktrace()[3] +eval(::Module, ::Expr) at REPL.jl:5 -julia> top_frame.func +julia> frame.func :eval -julia> top_frame.file -Symbol("./boot.jl") +julia> frame.file +Symbol("~/julia/usr/share/julia/stdlib/v0.7/REPL/src/REPL.jl") -julia> top_frame.line -236 +julia> frame.line +5 julia> top_frame.linfo MethodInstance for eval(::Module, ::Expr) @@ -96,7 +100,7 @@ false ```julia-repl julia> top_frame.pointer -0x00007f390d152a59 +0x00007f92d6293171 ``` This makes stack trace information available programmatically for logging, error handling, and @@ -119,9 +123,10 @@ julia> @noinline example() = try example (generic function with 1 method) julia> example() -5-element Array{StackFrame,1}: +7-element Array{Base.StackTraces.StackFrame,1}: example() at REPL[2]:4 - eval(::Module, ::Any) at boot.jl:236 + top-level scope + eval at boot.jl:317 [inlined] [...] ``` @@ -147,7 +152,7 @@ julia> @noinline example() = try example (generic function with 1 method) julia> example() -6-element Array{StackFrame,1}: +8-element Array{Base.StackTraces.StackFrame,1}: bad_function() at REPL[1]:1 example() at REPL[2]:2 [...] @@ -174,7 +179,8 @@ grandparent (generic function with 1 method) julia> grandparent() ERROR: Whoops! -7-element Array{StackFrame,1}: +10-element Array{Base.StackTraces.StackFrame,1}: + error at error.jl:33 [inlined] child() at REPL[1]:1 parent() at REPL[2]:1 grandparent() at REPL[3]:3 @@ -183,77 +189,63 @@ ERROR: Whoops! ## Comparison with [`backtrace`](@ref) -A call to [`backtrace`](@ref) returns a vector of `Ptr{Cvoid}`, which may then be passed into +A call to [`backtrace`](@ref) returns a vector of `Union{Ptr{Nothing}, Base.InterpreterIP}`, which may then be passed into [`stacktrace`](@ref) for translation: ```julia-repl julia> trace = backtrace() -21-element Array{Ptr{Cvoid},1}: - Ptr{Cvoid} @0x00007f10049d5b2f - Ptr{Cvoid} @0x00007f0ffeb4d29c - Ptr{Cvoid} @0x00007f0ffeb4d2a9 - Ptr{Cvoid} @0x00007f1004993fe7 - Ptr{Cvoid} @0x00007f10049a92be - Ptr{Cvoid} @0x00007f10049a823a - Ptr{Cvoid} @0x00007f10049a9fb0 - Ptr{Cvoid} @0x00007f10049aa718 - Ptr{Cvoid} @0x00007f10049c0d5e - Ptr{Cvoid} @0x00007f10049a3286 - Ptr{Cvoid} @0x00007f0ffe9ba3ba - Ptr{Cvoid} @0x00007f0ffe9ba3d0 - Ptr{Cvoid} @0x00007f1004993fe7 - Ptr{Cvoid} @0x00007f0ded34583d - Ptr{Cvoid} @0x00007f0ded345a87 - Ptr{Cvoid} @0x00007f1004993fe7 - Ptr{Cvoid} @0x00007f0ded34308f - Ptr{Cvoid} @0x00007f0ded343320 - Ptr{Cvoid} @0x00007f1004993fe7 - Ptr{Cvoid} @0x00007f10049aeb67 - Ptr{Cvoid} @0x0000000000000000 +18-element Array{Union{Ptr{Nothing}, Base.InterpreterIP},1}: + Ptr{Nothing} @0x00007fd8734c6209 + Ptr{Nothing} @0x00007fd87362b342 + Ptr{Nothing} @0x00007fd87362c136 + Ptr{Nothing} @0x00007fd87362c986 + Ptr{Nothing} @0x00007fd87362d089 + Base.InterpreterIP(CodeInfo(:(begin + Core.SSAValue(0) = backtrace() + trace = Core.SSAValue(0) + return Core.SSAValue(0) + end)), 0x0000000000000000) + Ptr{Nothing} @0x00007fd87362e4cf +[...] julia> stacktrace(trace) -5-element Array{StackFrame,1}: - backtrace() at error.jl:46 - eval(::Module, ::Any) at boot.jl:236 - eval_user_input(::Any, ::Base.REPL.REPLBackend) at REPL.jl:66 - macro expansion at REPL.jl:97 [inlined] - (::Base.REPL.##1#2{Base.REPL.REPLBackend})() at event.jl:73 +6-element Array{Base.StackTraces.StackFrame,1}: + top-level scope + eval at boot.jl:317 [inlined] + eval(::Module, ::Expr) at REPL.jl:5 + eval_user_input(::Any, ::REPL.REPLBackend) at REPL.jl:85 + macro expansion at REPL.jl:116 [inlined] + (::getfield(REPL, Symbol("##28#29")){REPL.REPLBackend})() at event.jl:92 ``` -Notice that the vector returned by [`backtrace`](@ref) had 21 pointers, while the vector returned -by [`stacktrace`](@ref) only has 5. This is because, by default, [`stacktrace`](@ref) removes +Notice that the vector returned by [`backtrace`](@ref) had 18 elements, while the vector returned +by [`stacktrace`](@ref) only has 6. This is because, by default, [`stacktrace`](@ref) removes any lower-level C functions from the stack. If you want to include stack frames from C calls, you can do it like this: ```julia-repl julia> stacktrace(trace, true) -27-element Array{StackFrame,1}: - jl_backtrace_from_here at stackwalk.c:103 - backtrace() at error.jl:46 - backtrace() at sys.so:? - jl_call_method_internal at julia_internal.h:248 [inlined] - jl_apply_generic at gf.c:2215 - do_call at interpreter.c:75 - eval at interpreter.c:215 - eval_body at interpreter.c:519 - jl_interpret_toplevel_thunk at interpreter.c:664 - jl_toplevel_eval_flex at toplevel.c:592 - jl_toplevel_eval_in at builtins.c:614 - eval(::Module, ::Any) at boot.jl:236 - eval(::Module, ::Any) at sys.so:? - jl_call_method_internal at julia_internal.h:248 [inlined] - jl_apply_generic at gf.c:2215 - eval_user_input(::Any, ::Base.REPL.REPLBackend) at REPL.jl:66 - ip:0x7f1c707f1846 - jl_call_method_internal at julia_internal.h:248 [inlined] - jl_apply_generic at gf.c:2215 - macro expansion at REPL.jl:97 [inlined] - (::Base.REPL.##1#2{Base.REPL.REPLBackend})() at event.jl:73 - ip:0x7f1c707ea1ef - jl_call_method_internal at julia_internal.h:248 [inlined] - jl_apply_generic at gf.c:2215 - jl_apply at julia.h:1411 [inlined] - start_task at task.c:261 +21-element Array{Base.StackTraces.StackFrame,1}: + jl_apply_generic at gf.c:2167 + do_call at interpreter.c:324 + eval_value at interpreter.c:416 + eval_body at interpreter.c:559 + jl_interpret_toplevel_thunk_callback at interpreter.c:798 + top-level scope + jl_interpret_toplevel_thunk at interpreter.c:807 + jl_toplevel_eval_flex at toplevel.c:856 + jl_toplevel_eval_in at builtins.c:624 + eval at boot.jl:317 [inlined] + eval(::Module, ::Expr) at REPL.jl:5 + jl_apply_generic at gf.c:2167 + eval_user_input(::Any, ::REPL.REPLBackend) at REPL.jl:85 + jl_apply_generic at gf.c:2167 + macro expansion at REPL.jl:116 [inlined] + (::getfield(REPL, Symbol("##28#29")){REPL.REPLBackend})() at event.jl:92 + jl_fptr_trampoline at gf.c:1838 + jl_apply_generic at gf.c:2167 + jl_apply at julia.h:1540 [inlined] + start_task at task.c:268 ip:0xffffffffffffffff ``` @@ -264,9 +256,10 @@ s by passing them into [`StackTraces.lookup`](@ref): julia> pointer = backtrace()[1]; julia> frame = StackTraces.lookup(pointer) -1-element Array{StackFrame,1}: - jl_backtrace_from_here at stackwalk.c:103 +1-element Array{Base.StackTraces.StackFrame,1}: + jl_apply_generic at gf.c:2167 julia> println("The top frame is from $(frame[1].func)!") -The top frame is from jl_backtrace_from_here! +The top frame is from jl_apply_generic! ``` + diff --git a/src/stdlib/Logging.md b/src/stdlib/Logging.md index 6c170f5..fe8a44b 100644 --- a/src/stdlib/Logging.md +++ b/src/stdlib/Logging.md @@ -131,7 +131,7 @@ There are three logger types provided by the library. [`ConsoleLogger`](@ref) is the default logger you see when starting the REPL. It displays events in a readable text format and tries to give simple but user friendly control over formatting and filtering. [`NullLogger`](@ref) is a convenient way to drop all -messages where necessary; it is the logging equivalent of the [`DevNull`](@ref) +messages where necessary; it is the logging equivalent of the [`devnull`](@ref) stream. [`SimpleLogger`](@ref) is a very simplistic text formatting logger, mainly useful for debugging the logging system itself. @@ -147,15 +147,15 @@ messages that will be discarded: [`disable_logging`](@ref)). This is a crude but extremely cheap global setting. 2. The current logger state is looked up and the message level checked against the - logger's cached minimum level, as found by calling [`min_enabled_level`](@ref). + logger's cached minimum level, as found by calling [`Logging.min_enabled_level`](@ref). This behavior can be overridden via environment variables (more on this later). -3. The [`shouldlog`](@ref) function is called with the current logger, taking +3. The [`Logging.shouldlog`](@ref) function is called with the current logger, taking some minimal information (level, module, group, id) which can be computed statically. Most usefully, `shouldlog` is passed an event `id` which can be used to discard events early based on a cached predicate. If all these checks pass, the message and key--value pairs are evaluated in full -and passed to the current logger via the [`handle_message`](@ref) function. +and passed to the current logger via the [`Logging.handle_message`](@ref) function. `handle_message()` may perform additional filtering as required and display the event to the screen, save it to a file, etc. @@ -163,7 +163,7 @@ Exceptions that occur while generating the log event are captured and logged by default. This prevents individual broken events from crashing the application, which is helpful when enabling little-used debug events in a production system. This behavior can be customized per logger type by -extending [`catch_exceptions`](@ref). +extending [`Logging.catch_exceptions`](@ref). ## Testing log events @@ -208,13 +208,13 @@ Logging.LogLevel Event processing is controlled by overriding functions associated with `AbstractLogger`: -| Methods to implement |   | Brief description | -|:----------------------------- |:---------------------- |:---------------------------------------- | -| [`handle_message`](@ref) | | Handle a log event | -| [`shouldlog`](@ref) | | Early filtering of events | -| [`min_enabled_level`](@ref) | | Lower bound for log level of accepted events | -| **Optional methods** | **Default definition** | **Brief description** | -| [`catch_exceptions`](@ref) | `true` | Catch exceptions during event evaluation | +| Methods to implement | | Brief description | +|:----------------------------------- |:---------------------- |:---------------------------------------- | +| [`Logging.handle_message`](@ref) | | Handle a log event | +| [`Logging.shouldlog`](@ref) | | Early filtering of events | +| [`Logging.min_enabled_level`](@ref) | | Lower bound for log level of accepted events | +| **Optional methods** | **Default definition** | **Brief description** | +| [`Logging.catch_exceptions`](@ref) | `true` | Catch exceptions during event evaluation | ```@docs From e996803327a0efa9279841130cefb123cf38dbb5 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Sat, 12 May 2018 10:30:18 +0900 Subject: [PATCH 023/153] update Julia Commit 1d53232f7d --- codex/NEWS.md | 6 +++-- codex/base/arrays.md | 3 +-- codex/base/collections.md | 1 - codex/devdocs/offset-arrays.md | 12 +++++----- codex/manual/mathematical-operations.md | 29 +++++++++++++------------ codex/manual/performance-tips.md | 2 +- codex/stdlib/LibGit2.md | 4 ++-- codex/stdlib/Pkg3.md | 7 +++--- make.jl | 2 +- src/NEWS.md | 6 +++-- src/base/arrays.md | 3 +-- src/base/collections.md | 1 - src/devdocs/offset-arrays.md | 12 +++++----- src/manual/mathematical-operations.md | 29 +++++++++++++------------ src/manual/performance-tips.md | 2 +- src/stdlib/LibGit2.md | 4 ++-- src/stdlib/Pkg3.md | 7 +++--- 17 files changed, 67 insertions(+), 63 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index b9bcc06..2f5b417 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -634,8 +634,10 @@ Library improvements other containers, by taking the multiplicity of the arguments into account. Use `unique` to get the old behavior. - * The type `LinearIndices` has been added, providing conversion from - cartesian indices to linear indices using the normal indexing operation. ([#24715](https://github.com/JuliaLang/julia/issues/24715)) + * The `linearindices` function has been deprecated in favor of the new + `LinearIndices` type, which additionnally provides conversion from + cartesian indices to linear indices using the normal indexing operation. + ([#24715](https://github.com/JuliaLang/julia/issues/24715), [#26775](https://github.com/JuliaLang/julia/issues/26775)). * `IdDict{K,V}` replaces `ObjectIdDict`. It has type parameters like other `AbstractDict` subtypes and its constructors mirror the diff --git a/codex/base/arrays.md b/codex/base/arrays.md index 9041a81..83ca58c 100644 --- a/codex/base/arrays.md +++ b/codex/base/arrays.md @@ -42,7 +42,6 @@ Base.axes(::Any) Base.axes(::AbstractArray, ::Any) Base.length(::AbstractArray) Base.eachindex -Base.linearindices Base.IndexStyle Base.conj! Base.stride @@ -157,7 +156,7 @@ Base.invperm Base.isperm Base.permute!(::Any, ::AbstractVector) Base.invpermute! -Base.reverse +Base.reverse(::AbstractVector; kwargs...) Base.reverseind Base.reverse! ``` diff --git a/codex/base/collections.md b/codex/base/collections.md index 0e2c58a..4c3aad0 100644 --- a/codex/base/collections.md +++ b/codex/base/collections.md @@ -127,7 +127,6 @@ Base.last Base.step Base.collect(::Any) Base.collect(::Type, ::Any) -Base.issubset(::Any, ::Any) Base.filter Base.filter! Base.replace(::Any, ::Pair...) diff --git a/codex/devdocs/offset-arrays.md b/codex/devdocs/offset-arrays.md index 97328a6..9bca679 100644 --- a/codex/devdocs/offset-arrays.md +++ b/codex/devdocs/offset-arrays.md @@ -18,8 +18,8 @@ the exported interfaces of Julia. As an overview, the steps are: * replace many uses of `size` with `axes` - * replace `1:length(A)` with `eachindex(A)`, or in some cases `linearindices(A)` - * replace `length(A)` with `length(linearindices(A))` + * replace `1:length(A)` with `eachindex(A)`, or in some cases `LinearIndices(A)` + * replace `length(A)` with `length(LinearIndices(A))` * replace explicit allocations like `Array{Int}(size(B))` with `similar(Array{Int}, axes(B))` These are described in more detail below. @@ -74,21 +74,21 @@ at the top of any function. For bounds checking, note that there are dedicated functions `checkbounds` and `checkindex` which can sometimes simplify such tests. -### Linear indexing (`linearindices`) +### Linear indexing (`LinearIndices`) Some algorithms are most conveniently (or efficiently) written in terms of a single linear index, `A[i]` even if `A` is multi-dimensional. Regardless of the array's native indices, linear indices always range from `1:length(A)`. However, this raises an ambiguity for one-dimensional arrays (a.k.a., [`AbstractVector`](@ref)): does `v[i]` mean linear indexing , or Cartesian indexing with the array's native indices? -For this reason, your best option may be to iterate over the array with `eachindex(A)`, or, if you require the indices to be sequential integers, to get the index range by calling `linearindices(A)`. This will return `axes(A, 1)` if A is an AbstractVector, and the equivalent of `1:length(A)` otherwise. +For this reason, your best option may be to iterate over the array with `eachindex(A)`, or, if you require the indices to be sequential integers, to get the index range by calling `LinearIndices(A)`. This will return `axes(A, 1)` if A is an AbstractVector, and the equivalent of `1:length(A)` otherwise. By this definition, 1-dimensional arrays always use Cartesian indexing with the array's native indices. To help enforce this, it's worth noting that the index conversion functions will throw an error if shape indicates a 1-dimensional array with unconventional indexing (i.e., is a `Tuple{UnitRange}` rather than a tuple of `OneTo`). For arrays with conventional indexing, these functions continue to work the same as always. -Using `axes` and `linearindices`, here is one way you could rewrite `mycopy!`: +Using `axes` and `LinearIndices`, here is one way you could rewrite `mycopy!`: ```julia function mycopy!(dest::AbstractVector, src::AbstractVector) axes(dest) == axes(src) || throw(DimensionMismatch("vectors must match")) - for i in linearindices(src) + for i in LinearIndices(src) @inbounds dest[i] = src[i] end dest diff --git a/codex/manual/mathematical-operations.md b/codex/manual/mathematical-operations.md index f33449c..1e8ccca 100644 --- a/codex/manual/mathematical-operations.md +++ b/codex/manual/mathematical-operations.md @@ -17,6 +17,7 @@ are supported on all primitive numeric types: | `x - y` | binary minus | performs subtraction | | `x * y` | times | performs multiplication | | `x / y` | divide | performs division | +| `x ÷ y` | integer divide | x / y, truncated to an integer | | `x \ y` | inverse divide | equivalent to `y / x` | | `x ^ y` | power | raises `x` to the `y`th power | | `x % y` | remainder | equivalent to `rem(x,y)` | @@ -357,7 +358,7 @@ Julia applies the following order and associativity of operations, from highest | Exponentiation | `^` | Right | | Unary | `+ - √` | Right[^1] | | Fractions | `//` | Left | -| Multiplication | `* / % & \` | Left[^2] | +| Multiplication | `* / % & \ ÷` | Left[^2] | | Bitshifts | `<< >> >>>` | Left | | Addition | `+ - \| ⊻` | Left[^2] | | Syntax | `: ..` | Left | @@ -471,19 +472,19 @@ See [Conversion and Promotion](@ref conversion-and-promotion) for how to define ### Division functions -| Function | Description | -|:--------------------- |:--------------------------------------------------------------------------------------------------------- | -| [`div(x,y)`](@ref) | truncated division; quotient rounded towards zero | -| [`fld(x,y)`](@ref) | floored division; quotient rounded towards `-Inf` | -| [`cld(x,y)`](@ref) | ceiling division; quotient rounded towards `+Inf` | -| [`rem(x,y)`](@ref) | remainder; satisfies `x == div(x,y)*y + rem(x,y)`; sign matches `x` | -| [`mod(x,y)`](@ref) | modulus; satisfies `x == fld(x,y)*y + mod(x,y)`; sign matches `y` | -| [`mod1(x,y)`](@ref) | `mod` with offset 1; returns `r∈(0,y]` for `y>0` or `r∈[y,0)` for `y<0`, where `mod(r, y) == mod(x, y)` | -| [`mod2pi(x)`](@ref) | modulus with respect to 2pi; `0 <= mod2pi(x)   < 2pi` | -| [`divrem(x,y)`](@ref) | returns `(div(x,y),rem(x,y))` | -| [`fldmod(x,y)`](@ref) | returns `(fld(x,y),mod(x,y))` | -| [`gcd(x,y...)`](@ref) | greatest positive common divisor of `x`, `y`,... | -| [`lcm(x,y...)`](@ref) | least positive common multiple of `x`, `y`,... | +| Function | Description | +|:------------------------- |:--------------------------------------------------------------------------------------------------------- | +| [`div(x,y)`](@ref), `x÷y` | truncated division; quotient rounded towards zero | +| [`fld(x,y)`](@ref) | floored division; quotient rounded towards `-Inf` | +| [`cld(x,y)`](@ref) | ceiling division; quotient rounded towards `+Inf` | +| [`rem(x,y)`](@ref) | remainder; satisfies `x == div(x,y)*y + rem(x,y)`; sign matches `x` | +| [`mod(x,y)`](@ref) | modulus; satisfies `x == fld(x,y)*y + mod(x,y)`; sign matches `y` | +| [`mod1(x,y)`](@ref) | `mod` with offset 1; returns `r∈(0,y]` for `y>0` or `r∈[y,0)` for `y<0`, where `mod(r, y) == mod(x, y)` | +| [`mod2pi(x)`](@ref) | modulus with respect to 2pi; `0 <= mod2pi(x)   < 2pi` | +| [`divrem(x,y)`](@ref) | returns `(div(x,y),rem(x,y))` | +| [`fldmod(x,y)`](@ref) | returns `(fld(x,y),mod(x,y))` | +| [`gcd(x,y...)`](@ref) | greatest positive common divisor of `x`, `y`,... | +| [`lcm(x,y...)`](@ref) | least positive common multiple of `x`, `y`,... | ### Sign and absolute value functions diff --git a/codex/manual/performance-tips.md b/codex/manual/performance-tips.md index bcd5abe..ff8ecd5 100644 --- a/codex/manual/performance-tips.md +++ b/codex/manual/performance-tips.md @@ -1170,7 +1170,7 @@ Sometimes you can enable better optimization by promising certain program proper and could change or disappear in future versions of Julia. The common idiom of using 1:n to index into an AbstractArray is not safe if the Array uses unconventional indexing, -and may cause a segmentation fault if bounds checking is turned off. Use `linearindices(x)` or `eachindex(x)` +and may cause a segmentation fault if bounds checking is turned off. Use `LinearIndices(x)` or `eachindex(x)` instead (see also [offset-arrays](https://docs.julialang.org/en/latest/devdocs/offset-arrays)). Note: While `@simd` needs to be placed directly in front of a loop, both `@inbounds` and `@fastmath` diff --git a/codex/stdlib/LibGit2.md b/codex/stdlib/LibGit2.md index 20fd2b4..48af940 100644 --- a/codex/stdlib/LibGit2.md +++ b/codex/stdlib/LibGit2.md @@ -68,7 +68,7 @@ LibGit2.checkout! LibGit2.clone LibGit2.commit LibGit2.committer -LibGit2.count(::Function, ::LibGit2.GitRevWalker; ::LibGit2.GitHash, ::Cint, ::Bool) +LibGit2.count LibGit2.counthunks LibGit2.create_branch LibGit2.credentials_callback @@ -108,7 +108,7 @@ LibGit2.isorphan LibGit2.isset LibGit2.iszero LibGit2.lookup_branch -LibGit2.map(::Function, ::LibGit2.GitRevWalker; ::LibGit2.GitHash, ::AbstractString, ::Cint, ::Bool) +LibGit2.map LibGit2.mirror_callback LibGit2.mirror_cb LibGit2.message diff --git a/codex/stdlib/Pkg3.md b/codex/stdlib/Pkg3.md index 0678767..26e98f8 100644 --- a/codex/stdlib/Pkg3.md +++ b/codex/stdlib/Pkg3.md @@ -373,7 +373,7 @@ Developed packages are never touched by the package manager. If you just want install the packages that are given by the current `Manifest.toml` use ``` -(HelloWorld) pkg> up --manifest --fixed +(HelloWorld) pkg> instantiate ``` ## Precompiling the project @@ -409,9 +409,10 @@ However, nothing would be installed and your `Project.toml` and `Manfiest.toml` Simple clone their project using e.g. `git clone`, `cd` to the project directory and call ``` -(SomeProject) pkg> up --manifest --fixed +(SomeProject) pkg> instantiate ``` -This will install the packages at the same state that the project you cloned was using. +If the project contains a manifest, this will install the packages at the same state that is given by that manifest. +Otherwise it will resolve the latest versions of the dependencies compatible with the project. diff --git a/make.jl b/make.jl index 28f5bfa..b1b48a4 100644 --- a/make.jl +++ b/make.jl @@ -139,7 +139,7 @@ makedocs( doctest = "doctest" in ARGS, linkcheck = "linkcheck" in ARGS, linkcheck_ignore = ["https://bugs.kde.org/show_bug.cgi?id=136779"], # fails to load from nanosoldier? - strict = false, # true + strict = true, checkdocs = :none, format = "pdf" in ARGS ? :latex : :html, sitename = "줄리아 언어", diff --git a/src/NEWS.md b/src/NEWS.md index f205e0b..0d9b834 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -622,8 +622,10 @@ Library improvements other containers, by taking the multiplicity of the arguments into account. Use `unique` to get the old behavior. - * The type `LinearIndices` has been added, providing conversion from - cartesian indices to linear indices using the normal indexing operation. ([#24715](https://github.com/JuliaLang/julia/issues/24715)) + * The `linearindices` function has been deprecated in favor of the new + `LinearIndices` type, which additionnally provides conversion from + cartesian indices to linear indices using the normal indexing operation. + ([#24715](https://github.com/JuliaLang/julia/issues/24715), [#26775](https://github.com/JuliaLang/julia/issues/26775)). * `IdDict{K,V}` replaces `ObjectIdDict`. It has type parameters like other `AbstractDict` subtypes and its constructors mirror the diff --git a/src/base/arrays.md b/src/base/arrays.md index 9041a81..83ca58c 100644 --- a/src/base/arrays.md +++ b/src/base/arrays.md @@ -42,7 +42,6 @@ Base.axes(::Any) Base.axes(::AbstractArray, ::Any) Base.length(::AbstractArray) Base.eachindex -Base.linearindices Base.IndexStyle Base.conj! Base.stride @@ -157,7 +156,7 @@ Base.invperm Base.isperm Base.permute!(::Any, ::AbstractVector) Base.invpermute! -Base.reverse +Base.reverse(::AbstractVector; kwargs...) Base.reverseind Base.reverse! ``` diff --git a/src/base/collections.md b/src/base/collections.md index 0e2c58a..4c3aad0 100644 --- a/src/base/collections.md +++ b/src/base/collections.md @@ -127,7 +127,6 @@ Base.last Base.step Base.collect(::Any) Base.collect(::Type, ::Any) -Base.issubset(::Any, ::Any) Base.filter Base.filter! Base.replace(::Any, ::Pair...) diff --git a/src/devdocs/offset-arrays.md b/src/devdocs/offset-arrays.md index 97328a6..9bca679 100644 --- a/src/devdocs/offset-arrays.md +++ b/src/devdocs/offset-arrays.md @@ -18,8 +18,8 @@ the exported interfaces of Julia. As an overview, the steps are: * replace many uses of `size` with `axes` - * replace `1:length(A)` with `eachindex(A)`, or in some cases `linearindices(A)` - * replace `length(A)` with `length(linearindices(A))` + * replace `1:length(A)` with `eachindex(A)`, or in some cases `LinearIndices(A)` + * replace `length(A)` with `length(LinearIndices(A))` * replace explicit allocations like `Array{Int}(size(B))` with `similar(Array{Int}, axes(B))` These are described in more detail below. @@ -74,21 +74,21 @@ at the top of any function. For bounds checking, note that there are dedicated functions `checkbounds` and `checkindex` which can sometimes simplify such tests. -### Linear indexing (`linearindices`) +### Linear indexing (`LinearIndices`) Some algorithms are most conveniently (or efficiently) written in terms of a single linear index, `A[i]` even if `A` is multi-dimensional. Regardless of the array's native indices, linear indices always range from `1:length(A)`. However, this raises an ambiguity for one-dimensional arrays (a.k.a., [`AbstractVector`](@ref)): does `v[i]` mean linear indexing , or Cartesian indexing with the array's native indices? -For this reason, your best option may be to iterate over the array with `eachindex(A)`, or, if you require the indices to be sequential integers, to get the index range by calling `linearindices(A)`. This will return `axes(A, 1)` if A is an AbstractVector, and the equivalent of `1:length(A)` otherwise. +For this reason, your best option may be to iterate over the array with `eachindex(A)`, or, if you require the indices to be sequential integers, to get the index range by calling `LinearIndices(A)`. This will return `axes(A, 1)` if A is an AbstractVector, and the equivalent of `1:length(A)` otherwise. By this definition, 1-dimensional arrays always use Cartesian indexing with the array's native indices. To help enforce this, it's worth noting that the index conversion functions will throw an error if shape indicates a 1-dimensional array with unconventional indexing (i.e., is a `Tuple{UnitRange}` rather than a tuple of `OneTo`). For arrays with conventional indexing, these functions continue to work the same as always. -Using `axes` and `linearindices`, here is one way you could rewrite `mycopy!`: +Using `axes` and `LinearIndices`, here is one way you could rewrite `mycopy!`: ```julia function mycopy!(dest::AbstractVector, src::AbstractVector) axes(dest) == axes(src) || throw(DimensionMismatch("vectors must match")) - for i in linearindices(src) + for i in LinearIndices(src) @inbounds dest[i] = src[i] end dest diff --git a/src/manual/mathematical-operations.md b/src/manual/mathematical-operations.md index f33449c..1e8ccca 100644 --- a/src/manual/mathematical-operations.md +++ b/src/manual/mathematical-operations.md @@ -17,6 +17,7 @@ are supported on all primitive numeric types: | `x - y` | binary minus | performs subtraction | | `x * y` | times | performs multiplication | | `x / y` | divide | performs division | +| `x ÷ y` | integer divide | x / y, truncated to an integer | | `x \ y` | inverse divide | equivalent to `y / x` | | `x ^ y` | power | raises `x` to the `y`th power | | `x % y` | remainder | equivalent to `rem(x,y)` | @@ -357,7 +358,7 @@ Julia applies the following order and associativity of operations, from highest | Exponentiation | `^` | Right | | Unary | `+ - √` | Right[^1] | | Fractions | `//` | Left | -| Multiplication | `* / % & \` | Left[^2] | +| Multiplication | `* / % & \ ÷` | Left[^2] | | Bitshifts | `<< >> >>>` | Left | | Addition | `+ - \| ⊻` | Left[^2] | | Syntax | `: ..` | Left | @@ -471,19 +472,19 @@ See [Conversion and Promotion](@ref conversion-and-promotion) for how to define ### Division functions -| Function | Description | -|:--------------------- |:--------------------------------------------------------------------------------------------------------- | -| [`div(x,y)`](@ref) | truncated division; quotient rounded towards zero | -| [`fld(x,y)`](@ref) | floored division; quotient rounded towards `-Inf` | -| [`cld(x,y)`](@ref) | ceiling division; quotient rounded towards `+Inf` | -| [`rem(x,y)`](@ref) | remainder; satisfies `x == div(x,y)*y + rem(x,y)`; sign matches `x` | -| [`mod(x,y)`](@ref) | modulus; satisfies `x == fld(x,y)*y + mod(x,y)`; sign matches `y` | -| [`mod1(x,y)`](@ref) | `mod` with offset 1; returns `r∈(0,y]` for `y>0` or `r∈[y,0)` for `y<0`, where `mod(r, y) == mod(x, y)` | -| [`mod2pi(x)`](@ref) | modulus with respect to 2pi; `0 <= mod2pi(x)   < 2pi` | -| [`divrem(x,y)`](@ref) | returns `(div(x,y),rem(x,y))` | -| [`fldmod(x,y)`](@ref) | returns `(fld(x,y),mod(x,y))` | -| [`gcd(x,y...)`](@ref) | greatest positive common divisor of `x`, `y`,... | -| [`lcm(x,y...)`](@ref) | least positive common multiple of `x`, `y`,... | +| Function | Description | +|:------------------------- |:--------------------------------------------------------------------------------------------------------- | +| [`div(x,y)`](@ref), `x÷y` | truncated division; quotient rounded towards zero | +| [`fld(x,y)`](@ref) | floored division; quotient rounded towards `-Inf` | +| [`cld(x,y)`](@ref) | ceiling division; quotient rounded towards `+Inf` | +| [`rem(x,y)`](@ref) | remainder; satisfies `x == div(x,y)*y + rem(x,y)`; sign matches `x` | +| [`mod(x,y)`](@ref) | modulus; satisfies `x == fld(x,y)*y + mod(x,y)`; sign matches `y` | +| [`mod1(x,y)`](@ref) | `mod` with offset 1; returns `r∈(0,y]` for `y>0` or `r∈[y,0)` for `y<0`, where `mod(r, y) == mod(x, y)` | +| [`mod2pi(x)`](@ref) | modulus with respect to 2pi; `0 <= mod2pi(x)   < 2pi` | +| [`divrem(x,y)`](@ref) | returns `(div(x,y),rem(x,y))` | +| [`fldmod(x,y)`](@ref) | returns `(fld(x,y),mod(x,y))` | +| [`gcd(x,y...)`](@ref) | greatest positive common divisor of `x`, `y`,... | +| [`lcm(x,y...)`](@ref) | least positive common multiple of `x`, `y`,... | ### Sign and absolute value functions diff --git a/src/manual/performance-tips.md b/src/manual/performance-tips.md index bcd5abe..ff8ecd5 100644 --- a/src/manual/performance-tips.md +++ b/src/manual/performance-tips.md @@ -1170,7 +1170,7 @@ Sometimes you can enable better optimization by promising certain program proper and could change or disappear in future versions of Julia. The common idiom of using 1:n to index into an AbstractArray is not safe if the Array uses unconventional indexing, -and may cause a segmentation fault if bounds checking is turned off. Use `linearindices(x)` or `eachindex(x)` +and may cause a segmentation fault if bounds checking is turned off. Use `LinearIndices(x)` or `eachindex(x)` instead (see also [offset-arrays](https://docs.julialang.org/en/latest/devdocs/offset-arrays)). Note: While `@simd` needs to be placed directly in front of a loop, both `@inbounds` and `@fastmath` diff --git a/src/stdlib/LibGit2.md b/src/stdlib/LibGit2.md index 20fd2b4..48af940 100644 --- a/src/stdlib/LibGit2.md +++ b/src/stdlib/LibGit2.md @@ -68,7 +68,7 @@ LibGit2.checkout! LibGit2.clone LibGit2.commit LibGit2.committer -LibGit2.count(::Function, ::LibGit2.GitRevWalker; ::LibGit2.GitHash, ::Cint, ::Bool) +LibGit2.count LibGit2.counthunks LibGit2.create_branch LibGit2.credentials_callback @@ -108,7 +108,7 @@ LibGit2.isorphan LibGit2.isset LibGit2.iszero LibGit2.lookup_branch -LibGit2.map(::Function, ::LibGit2.GitRevWalker; ::LibGit2.GitHash, ::AbstractString, ::Cint, ::Bool) +LibGit2.map LibGit2.mirror_callback LibGit2.mirror_cb LibGit2.message diff --git a/src/stdlib/Pkg3.md b/src/stdlib/Pkg3.md index 0678767..26e98f8 100644 --- a/src/stdlib/Pkg3.md +++ b/src/stdlib/Pkg3.md @@ -373,7 +373,7 @@ Developed packages are never touched by the package manager. If you just want install the packages that are given by the current `Manifest.toml` use ``` -(HelloWorld) pkg> up --manifest --fixed +(HelloWorld) pkg> instantiate ``` ## Precompiling the project @@ -409,9 +409,10 @@ However, nothing would be installed and your `Project.toml` and `Manfiest.toml` Simple clone their project using e.g. `git clone`, `cd` to the project directory and call ``` -(SomeProject) pkg> up --manifest --fixed +(SomeProject) pkg> instantiate ``` -This will install the packages at the same state that the project you cloned was using. +If the project contains a manifest, this will install the packages at the same state that is given by that manifest. +Otherwise it will resolve the latest versions of the dependencies compatible with the project. From a39578a7072a8045022228dece87834f944e97f1 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Fri, 18 May 2018 10:31:04 +0900 Subject: [PATCH 024/153] update Julia Commit c2030eda75 --- codex/NEWS.md | 8 ++++++++ codex/base/arrays.md | 15 ++------------- codex/base/base.md | 11 +++++++++++ codex/base/collections.md | 4 ++++ codex/base/strings.md | 2 +- codex/manual/arrays.md | 18 +++++++++++------- codex/manual/interfaces.md | 20 +++++++++++--------- codex/manual/packages.md | 2 +- codex/manual/strings.md | 5 +++-- codex/stdlib/Logging.md | 2 +- src/NEWS.md | 8 ++++++++ src/base/arrays.md | 15 ++------------- src/base/base.md | 11 +++++++++++ src/base/collections.md | 4 ++++ src/base/strings.md | 2 +- src/manual/arrays.md | 16 ++++++++++------ src/manual/interfaces.md | 20 +++++++++++--------- src/manual/packages.md | 2 +- src/manual/strings.md | 5 +++-- src/stdlib/Logging.md | 2 +- 20 files changed, 105 insertions(+), 67 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index 2f5b417..34e7e2a 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -711,6 +711,9 @@ Deprecated or removed using the broadcasted assignment syntax `A[I...] .= x` or `fill!(view(A, I...), x)` ([#26347](https://github.com/JuliaLang/julia/issues/26347)). + * `broadcast_getindex(A, I...)` and `broadcast_setindex!(A, v, I...)` are deprecated in + favor of `getindex.((A,), I...)` and `setindex!.((A,), v, I...)`, respectively ([#27075](https://github.com/JuliaLang/julia/issues/27075)). + * `LinAlg.fillslots!` has been renamed `LinAlg.fillstored!` ([#25030](https://github.com/JuliaLang/julia/issues/25030)). * `fill!(A::Diagonal, x)` and `fill!(A::AbstractTriangular, x)` have been deprecated @@ -974,6 +977,9 @@ Deprecated or removed been deprecated due to inconsistency with linear algebra. Use `.+` and `.-` for these operations instead ([#22880](https://github.com/JuliaLang/julia/issues/22880), [#22932](https://github.com/JuliaLang/julia/issues/22932)). + * `flipbits!(B)` is deprecated in favor of using in-place broadcast to negate each element: + `B .= .!B` ([#27067](https://github.com/JuliaLang/julia/issues/27067)). + * `isleaftype` is deprecated in favor of the simpler predicates `isconcretetype` and `isdispatchtuple`. Concrete types are those that might equal `typeof(x)` for some `x`; `isleaftype` included some types for which this is not true. Those are now categorized more precisely @@ -1040,6 +1046,8 @@ Deprecated or removed * `isnumber` has been renamed to `isnumeric` ([#25021](https://github.com/JuliaLang/julia/issues/25021)). + * `isalpha` has been renamed to `isletter` ([#26932](https://github.com/JuliaLang/julia/issues/26932)). + * `is_assigned_char` and `normalize_string` have been renamed to `isassigned` and `normalize`, and moved to the new `Unicode` standard library module. `graphemes` has also been moved to that module ([#25021](https://github.com/JuliaLang/julia/issues/25021)). diff --git a/codex/base/arrays.md b/codex/base/arrays.md index 83ca58c..5ed3ebf 100644 --- a/codex/base/arrays.md +++ b/codex/base/arrays.md @@ -6,6 +6,7 @@ Core.AbstractArray Base.AbstractVector Base.AbstractMatrix +Base.AbstractVecOrMat Core.Array Core.Array(::UndefInitializer, ::Any) Core.Array(::Nothing, ::Any) @@ -20,6 +21,7 @@ Base.Matrix Base.Matrix(::UndefInitializer, ::Any, ::Any) Base.Matrix(::Nothing, ::Any, ::Any) Base.Matrix(::Missing, ::Any, ::Any) +Base.VecOrMat Base.getindex(::Type, ::Any...) Base.zeros Base.ones @@ -59,14 +61,11 @@ to operate on arrays, you should use `sin.(a)` to vectorize via `broadcast`. Base.broadcast Base.Broadcast.broadcast! Base.@__dot__ -Base.Broadcast.broadcast_getindex -Base.Broadcast.broadcast_setindex! ``` For specializing broadcast on custom types, see ```@docs Base.BroadcastStyle -Base.broadcast_similar Base.broadcast_axes Base.Broadcast.AbstractArrayStyle Base.Broadcast.ArrayStyle @@ -160,13 +159,3 @@ Base.reverse(::AbstractVector; kwargs...) Base.reverseind Base.reverse! ``` - -## BitArrays - -[`BitArray`](@ref)s are space-efficient "packed" boolean arrays, which store one bit per boolean value. -They can be used similarly to `Array{Bool}` arrays (which store one byte per boolean value), -and can be converted to/from the latter via `Array(bitarray)` and `BitArray(array)`, respectively. - -```@docs -Base.flipbits! -``` diff --git a/codex/base/base.md b/codex/base/base.md index 83ccc83..d069375 100644 --- a/codex/base/base.md +++ b/codex/base/base.md @@ -72,6 +72,8 @@ primitive type ## Base Modules ```@docs +Base.Base +Base.Broadcast Base.Docs Base.Iterators Base.Libc @@ -79,6 +81,7 @@ Base.Meta Base.StackTraces Base.Sys Base.Threads +Base.GC ``` ## All Objects @@ -264,6 +267,13 @@ Base.Sys.windows_version Base.@static ``` +## Versioning + +```@docs +Base.VersionNumber +Base.@v_str +``` + ## Errors ```@docs @@ -332,6 +342,7 @@ Base.functionloc(::Method) ```@docs Base.GC.gc Base.GC.enable +Base.GC.@preserve Meta.lower Meta.@lower Meta.parse(::AbstractString, ::Int) diff --git a/codex/base/collections.md b/codex/base/collections.md index 4c3aad0..63ec437 100644 --- a/codex/base/collections.md +++ b/codex/base/collections.md @@ -77,6 +77,7 @@ Fully implemented by: ```@docs Base.in +Base.:∉ Base.eltype Base.indexin Base.unique @@ -239,6 +240,9 @@ Base.symdiff Base.symdiff! Base.intersect! Base.issubset +Base.:⊈ +Base.:⊊ +Base.issetequal ``` Fully implemented by: diff --git a/codex/base/strings.md b/codex/base/strings.md index efa0a51..d178271 100644 --- a/codex/base/strings.md +++ b/codex/base/strings.md @@ -62,10 +62,10 @@ Base.thisind Base.nextind Base.prevind Base.textwidth -Base.isalpha Base.isascii Base.iscntrl Base.isdigit +Base.isletter Base.islowercase Base.isnumeric Base.isprint diff --git a/codex/manual/arrays.md b/codex/manual/arrays.md index 2492125..c778d8e 100644 --- a/codex/manual/arrays.md +++ b/codex/manual/arrays.md @@ -392,14 +392,15 @@ julia> x = collect(reshape(1:9, 3, 3)) 2 5 8 3 6 9 -julia> x[1:2, 2:3] = -1 --1 +julia> x[3, 3] = -9; + +julia> x[1:2, 1:2] = [-1 -4; -2 -5]; julia> x 3×3 Array{Int64,2}: - 1 -1 -1 - 2 -1 -1 - 3 6 9 + -1 -4 7 + -2 -5 8 + 3 6 -9 ``` ### [Supported index types](@id man-supported-index-types) @@ -654,8 +655,7 @@ julia> broadcast(+, a, b) [Dotted operators](@ref man-dot-operators) such as `.+` and `.*` are equivalent to `broadcast` calls (except that they fuse, as described below). There is also a [`broadcast!`](@ref) function to specify an explicit destination (which can also -be accessed in a fusing fashion by `.=` assignment), and functions [`broadcast_getindex`](@ref) -and [`broadcast_setindex!`](@ref) that broadcast the indices before indexing. Moreover, `f.(args...)` +be accessed in a fusing fashion by `.=` assignment). Moreover, `f.(args...)` is equivalent to `broadcast(f, args...)`, providing a convenient syntax to broadcast any function ([dot syntax](@ref man-vectorized)). Nested "dot calls" `f.(...)` (including calls to `.+` etcetera) [automatically fuse](@ref man-dot-operators) into a single `broadcast` call. @@ -722,6 +722,10 @@ indirectly. By putting the [`@views`](@ref) macro in front of an expression or block of code, any `array[...]` slice in that expression will be converted to create a `SubArray` view instead. +[`BitArray`](@ref)s are space-efficient "packed" boolean arrays, which store one bit per boolean value. +They can be used similarly to `Array{Bool}` arrays (which store one byte per boolean value), +and can be converted to/from the latter via `Array(bitarray)` and `BitArray(array)`, respectively. + A "strided" array is stored in memory with elements laid out in regular offsets such that an instance with a supported `isbits` element type can be passed to external C and Fortran functions that expect this memory layout. Strided arrays diff --git a/codex/manual/interfaces.md b/codex/manual/interfaces.md index 620bb4f..6d72c3d 100644 --- a/codex/manual/interfaces.md +++ b/codex/manual/interfaces.md @@ -440,7 +440,7 @@ V = view(A, [1,2,4], :) # is not strided, as the spacing between rows is not f | Methods to implement | Brief description | |:-------------------- |:----------------- | | `Base.BroadcastStyle(::Type{SrcType}) = SrcStyle()` | Broadcasting behavior of `SrcType` | -| `Base.broadcast_similar(::DestStyle, ::Type{ElType}, inds, bc)` | Allocation of output container | +| `Base.similar(bc::Broadcasted{DestStyle}, ::Type{ElType})` | Allocation of output container | | **Optional methods** | | | | `Base.BroadcastStyle(::Style1, ::Style2) = Style12()` | Precedence rules for mixing styles | | `Base.broadcast_axes(::StyleA, A)` | Declaration of the indices of `A` for broadcasting purposes (defaults to [`axes(A)`](@ref)) | @@ -512,17 +512,17 @@ For more details, see [below](@ref writing-binary-broadcasting-rules). The broadcast style is computed for every broadcasting operation to allow for dispatch and specialization. The actual allocation of the result array is -handled by `Base.broadcast_similar`, using this style as its first argument. +handled by `similar`, using the Broadcasted object as its first argument. ```julia -Base.broadcast_similar(::DestStyle, ::Type{ElType}, inds, bc) +Base.similar(bc::Broadcasted{DestStyle}, ::Type{ElType}) ``` The fallback definition is ```julia -broadcast_similar(::DefaultArrayStyle{N}, ::Type{ElType}, inds::Indices{N}, bc) where {N,ElType} = - similar(Array{ElType}, inds) +similar(bc::Broadcasted{DefaultArrayStyle{N}}, ::Type{ElType}) where {N,ElType} = + similar(Array{ElType}, axes(bc)) ``` However, if needed you can specialize on any or all of these arguments. The final argument @@ -555,13 +555,13 @@ Base.BroadcastStyle(::Type{<:ArrayAndChar}) = Broadcast.ArrayStyle{ArrayAndChar} ``` -This means we must also define a corresponding `broadcast_similar` method: -```jldoctest -function Base.broadcast_similar(::Broadcast.ArrayStyle{ArrayAndChar}, ::Type{ElType}, inds, bc) where ElType +This means we must also define a corresponding `similar` method: +```jldoctest ArrayAndChar; filter = r"(^find_aac \(generic function with 5 methods\)$|^$)" +function Base.similar(bc::Broadcast.Broadcasted{Broadcast.ArrayStyle{ArrayAndChar}}, ::Type{ElType}) where ElType # Scan the inputs for the ArrayAndChar: A = find_aac(bc) # Use the char field of A to create the output - ArrayAndChar(similar(Array{ElType}, inds), A.char) + ArrayAndChar(similar(Array{ElType}, axes(bc)), A.char) end "`A = find_aac(As)` returns the first ArrayAndChar among the arguments." @@ -570,6 +570,8 @@ find_aac(args::Tuple) = find_aac(find_aac(args[1]), Base.tail(args)) find_aac(x) = x find_aac(a::ArrayAndChar, rest) = a find_aac(::Any, rest) = find_aac(rest) +# output + ``` From these definitions, one obtains the following behavior: diff --git a/codex/manual/packages.md b/codex/manual/packages.md index 105686e..f10edc1 100644 --- a/codex/manual/packages.md +++ b/codex/manual/packages.md @@ -1102,7 +1102,7 @@ The first condition applies to any system but Windows and the second condition a UNIX system besides OS X. Runtime checks for the current version of Julia can be made using the built-in `VERSION` variable, -which is of type `VersionNumber`. Such code is occasionally necessary to keep track of new or +which is of type [`VersionNumber`](@ref). Such code is occasionally necessary to keep track of new or deprecated functionality between various releases of Julia. Examples of runtime checks: ```julia diff --git a/codex/manual/strings.md b/codex/manual/strings.md index b4c9930..e5395d9 100644 --- a/codex/manual/strings.md +++ b/codex/manual/strings.md @@ -934,8 +934,9 @@ some confusion regarding the matter. ## [Version Number Literals](@id man-version-number-literals) -Version numbers can easily be expressed with non-standard string literals of the form `v"..."`. -Version number literals create `VersionNumber` objects which follow the specifications of [semantic versioning](http://semver.org), +Version numbers can easily be expressed with non-standard string literals of the form [`v"..."`](@ref @v_str). +Version number literals create [`VersionNumber`](@ref) objects which follow the +specifications of [semantic versioning](http://semver.org), and therefore are composed of major, minor and patch numeric values, followed by pre-release and build alpha-numeric annotations. For example, `v"0.2.1-rc1+win64"` is broken into major version `0`, minor version `2`, patch version `1`, pre-release `rc1` and build `win64`. When entering diff --git a/codex/stdlib/Logging.md b/codex/stdlib/Logging.md index fe8a44b..ba07f66 100644 --- a/codex/stdlib/Logging.md +++ b/codex/stdlib/Logging.md @@ -35,7 +35,7 @@ A = ones(Int, 4, 4) v = ones(100) @info "Some variables" A s=sum(v) -# Output +# output ┌ Info: Some variables │ A = │ 4×4 Array{Int64,2}: diff --git a/src/NEWS.md b/src/NEWS.md index 0d9b834..b00efe8 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -698,6 +698,9 @@ Deprecated or removed using the broadcasted assignment syntax `A[I...] .= x` or `fill!(view(A, I...), x)` ([#26347](https://github.com/JuliaLang/julia/issues/26347)). + * `broadcast_getindex(A, I...)` and `broadcast_setindex!(A, v, I...)` are deprecated in + favor of `getindex.((A,), I...)` and `setindex!.((A,), v, I...)`, respectively ([#27075](https://github.com/JuliaLang/julia/issues/27075)). + * `LinAlg.fillslots!` has been renamed `LinAlg.fillstored!` ([#25030](https://github.com/JuliaLang/julia/issues/25030)). * `fill!(A::Diagonal, x)` and `fill!(A::AbstractTriangular, x)` have been deprecated @@ -961,6 +964,9 @@ Deprecated or removed been deprecated due to inconsistency with linear algebra. Use `.+` and `.-` for these operations instead ([#22880](https://github.com/JuliaLang/julia/issues/22880), [#22932](https://github.com/JuliaLang/julia/issues/22932)). + * `flipbits!(B)` is deprecated in favor of using in-place broadcast to negate each element: + `B .= .!B` ([#27067](https://github.com/JuliaLang/julia/issues/27067)). + * `isleaftype` is deprecated in favor of the simpler predicates `isconcretetype` and `isdispatchtuple`. Concrete types are those that might equal `typeof(x)` for some `x`; `isleaftype` included some types for which this is not true. Those are now categorized more precisely @@ -1027,6 +1033,8 @@ Deprecated or removed * `isnumber` has been renamed to `isnumeric` ([#25021](https://github.com/JuliaLang/julia/issues/25021)). + * `isalpha` has been renamed to `isletter` ([#26932](https://github.com/JuliaLang/julia/issues/26932)). + * `is_assigned_char` and `normalize_string` have been renamed to `isassigned` and `normalize`, and moved to the new `Unicode` standard library module. `graphemes` has also been moved to that module ([#25021](https://github.com/JuliaLang/julia/issues/25021)). diff --git a/src/base/arrays.md b/src/base/arrays.md index 83ca58c..5ed3ebf 100644 --- a/src/base/arrays.md +++ b/src/base/arrays.md @@ -6,6 +6,7 @@ Core.AbstractArray Base.AbstractVector Base.AbstractMatrix +Base.AbstractVecOrMat Core.Array Core.Array(::UndefInitializer, ::Any) Core.Array(::Nothing, ::Any) @@ -20,6 +21,7 @@ Base.Matrix Base.Matrix(::UndefInitializer, ::Any, ::Any) Base.Matrix(::Nothing, ::Any, ::Any) Base.Matrix(::Missing, ::Any, ::Any) +Base.VecOrMat Base.getindex(::Type, ::Any...) Base.zeros Base.ones @@ -59,14 +61,11 @@ to operate on arrays, you should use `sin.(a)` to vectorize via `broadcast`. Base.broadcast Base.Broadcast.broadcast! Base.@__dot__ -Base.Broadcast.broadcast_getindex -Base.Broadcast.broadcast_setindex! ``` For specializing broadcast on custom types, see ```@docs Base.BroadcastStyle -Base.broadcast_similar Base.broadcast_axes Base.Broadcast.AbstractArrayStyle Base.Broadcast.ArrayStyle @@ -160,13 +159,3 @@ Base.reverse(::AbstractVector; kwargs...) Base.reverseind Base.reverse! ``` - -## BitArrays - -[`BitArray`](@ref)s are space-efficient "packed" boolean arrays, which store one bit per boolean value. -They can be used similarly to `Array{Bool}` arrays (which store one byte per boolean value), -and can be converted to/from the latter via `Array(bitarray)` and `BitArray(array)`, respectively. - -```@docs -Base.flipbits! -``` diff --git a/src/base/base.md b/src/base/base.md index 83ccc83..d069375 100644 --- a/src/base/base.md +++ b/src/base/base.md @@ -72,6 +72,8 @@ primitive type ## Base Modules ```@docs +Base.Base +Base.Broadcast Base.Docs Base.Iterators Base.Libc @@ -79,6 +81,7 @@ Base.Meta Base.StackTraces Base.Sys Base.Threads +Base.GC ``` ## All Objects @@ -264,6 +267,13 @@ Base.Sys.windows_version Base.@static ``` +## Versioning + +```@docs +Base.VersionNumber +Base.@v_str +``` + ## Errors ```@docs @@ -332,6 +342,7 @@ Base.functionloc(::Method) ```@docs Base.GC.gc Base.GC.enable +Base.GC.@preserve Meta.lower Meta.@lower Meta.parse(::AbstractString, ::Int) diff --git a/src/base/collections.md b/src/base/collections.md index 4c3aad0..63ec437 100644 --- a/src/base/collections.md +++ b/src/base/collections.md @@ -77,6 +77,7 @@ Fully implemented by: ```@docs Base.in +Base.:∉ Base.eltype Base.indexin Base.unique @@ -239,6 +240,9 @@ Base.symdiff Base.symdiff! Base.intersect! Base.issubset +Base.:⊈ +Base.:⊊ +Base.issetequal ``` Fully implemented by: diff --git a/src/base/strings.md b/src/base/strings.md index efa0a51..d178271 100644 --- a/src/base/strings.md +++ b/src/base/strings.md @@ -62,10 +62,10 @@ Base.thisind Base.nextind Base.prevind Base.textwidth -Base.isalpha Base.isascii Base.iscntrl Base.isdigit +Base.isletter Base.islowercase Base.isnumeric Base.isprint diff --git a/src/manual/arrays.md b/src/manual/arrays.md index 8fb5e29..fea5a6a 100644 --- a/src/manual/arrays.md +++ b/src/manual/arrays.md @@ -367,14 +367,15 @@ julia> x = collect(reshape(1:9, 3, 3)) 2 5 8 3 6 9 -julia> x[1:2, 2:3] = -1 --1 +julia> x[3, 3] = -9; + +julia> x[1:2, 1:2] = [-1 -4; -2 -5]; julia> x 3×3 Array{Int64,2}: - 1 -1 -1 - 2 -1 -1 - 3 6 9 + -1 -4 7 + -2 -5 8 + 3 6 -9 ``` ### [지원하는 인덱스 타입](@id man-supported-index-types) @@ -605,7 +606,6 @@ julia> broadcast(+, a, b) `.+` 와 `.*` 같은 [점찍은 연산자](@ref man-dot-operators)는 `broadcast` 호출과 (아래에 설명할 융합을 제외한다면) 동일하다. 또한 명시적으로 목적지를 지정하는 [`broadcast!`](@ref)도 있다. (`.=` 대입을 사용하여 융합하여서도 액세스할 수 있다.) -그리고 [`broadcast_getindex`](@ref)와 [`broadcast_setindex!`](@ref) 함수는 인덱싱 전에 인덱스를 브로드캐스팅 한다. 게다가, `f.(args...)`는 `broadcast(f, args...)`와 동일하며, 어떤 함수든 [점 문법](@ref man-vectorized)을 통하여 편리하게 브로드캐스팅 할 수 있는 문법을 제공한다. 중첩된 "점 호출" `f.(...)`은 (`.+` 등의 연산자도 포함하여) 하나의 `broadcast` 호출로 [자동으로 융합](@ref man-dot-operators)한다. @@ -668,6 +668,10 @@ data is left in place. [`view`](@ref) stores the input index vectors in a indirectly. [`@views`](@ref) 매크로를 표현식이나 코드 블록 앞에 둠으로써, 그 표현식 내의 모든 `array[...]` 슬라이스가 `SubArray` 뷰를 생성하도록 할 수 있다. +[`BitArray`](@ref)s are space-efficient "packed" boolean arrays, which store one bit per boolean value. +They can be used similarly to `Array{Bool}` arrays (which store one byte per boolean value), +and can be converted to/from the latter via `Array(bitarray)` and `BitArray(array)`, respectively. + A "strided" array is stored in memory with elements laid out in regular offsets such that an instance with a supported `isbits` element type can be passed to external C and Fortran functions that expect this memory layout. Strided arrays diff --git a/src/manual/interfaces.md b/src/manual/interfaces.md index 620bb4f..6d72c3d 100644 --- a/src/manual/interfaces.md +++ b/src/manual/interfaces.md @@ -440,7 +440,7 @@ V = view(A, [1,2,4], :) # is not strided, as the spacing between rows is not f | Methods to implement | Brief description | |:-------------------- |:----------------- | | `Base.BroadcastStyle(::Type{SrcType}) = SrcStyle()` | Broadcasting behavior of `SrcType` | -| `Base.broadcast_similar(::DestStyle, ::Type{ElType}, inds, bc)` | Allocation of output container | +| `Base.similar(bc::Broadcasted{DestStyle}, ::Type{ElType})` | Allocation of output container | | **Optional methods** | | | | `Base.BroadcastStyle(::Style1, ::Style2) = Style12()` | Precedence rules for mixing styles | | `Base.broadcast_axes(::StyleA, A)` | Declaration of the indices of `A` for broadcasting purposes (defaults to [`axes(A)`](@ref)) | @@ -512,17 +512,17 @@ For more details, see [below](@ref writing-binary-broadcasting-rules). The broadcast style is computed for every broadcasting operation to allow for dispatch and specialization. The actual allocation of the result array is -handled by `Base.broadcast_similar`, using this style as its first argument. +handled by `similar`, using the Broadcasted object as its first argument. ```julia -Base.broadcast_similar(::DestStyle, ::Type{ElType}, inds, bc) +Base.similar(bc::Broadcasted{DestStyle}, ::Type{ElType}) ``` The fallback definition is ```julia -broadcast_similar(::DefaultArrayStyle{N}, ::Type{ElType}, inds::Indices{N}, bc) where {N,ElType} = - similar(Array{ElType}, inds) +similar(bc::Broadcasted{DefaultArrayStyle{N}}, ::Type{ElType}) where {N,ElType} = + similar(Array{ElType}, axes(bc)) ``` However, if needed you can specialize on any or all of these arguments. The final argument @@ -555,13 +555,13 @@ Base.BroadcastStyle(::Type{<:ArrayAndChar}) = Broadcast.ArrayStyle{ArrayAndChar} ``` -This means we must also define a corresponding `broadcast_similar` method: -```jldoctest -function Base.broadcast_similar(::Broadcast.ArrayStyle{ArrayAndChar}, ::Type{ElType}, inds, bc) where ElType +This means we must also define a corresponding `similar` method: +```jldoctest ArrayAndChar; filter = r"(^find_aac \(generic function with 5 methods\)$|^$)" +function Base.similar(bc::Broadcast.Broadcasted{Broadcast.ArrayStyle{ArrayAndChar}}, ::Type{ElType}) where ElType # Scan the inputs for the ArrayAndChar: A = find_aac(bc) # Use the char field of A to create the output - ArrayAndChar(similar(Array{ElType}, inds), A.char) + ArrayAndChar(similar(Array{ElType}, axes(bc)), A.char) end "`A = find_aac(As)` returns the first ArrayAndChar among the arguments." @@ -570,6 +570,8 @@ find_aac(args::Tuple) = find_aac(find_aac(args[1]), Base.tail(args)) find_aac(x) = x find_aac(a::ArrayAndChar, rest) = a find_aac(::Any, rest) = find_aac(rest) +# output + ``` From these definitions, one obtains the following behavior: diff --git a/src/manual/packages.md b/src/manual/packages.md index 105686e..f10edc1 100644 --- a/src/manual/packages.md +++ b/src/manual/packages.md @@ -1102,7 +1102,7 @@ The first condition applies to any system but Windows and the second condition a UNIX system besides OS X. Runtime checks for the current version of Julia can be made using the built-in `VERSION` variable, -which is of type `VersionNumber`. Such code is occasionally necessary to keep track of new or +which is of type [`VersionNumber`](@ref). Such code is occasionally necessary to keep track of new or deprecated functionality between various releases of Julia. Examples of runtime checks: ```julia diff --git a/src/manual/strings.md b/src/manual/strings.md index b4c9930..e5395d9 100644 --- a/src/manual/strings.md +++ b/src/manual/strings.md @@ -934,8 +934,9 @@ some confusion regarding the matter. ## [Version Number Literals](@id man-version-number-literals) -Version numbers can easily be expressed with non-standard string literals of the form `v"..."`. -Version number literals create `VersionNumber` objects which follow the specifications of [semantic versioning](http://semver.org), +Version numbers can easily be expressed with non-standard string literals of the form [`v"..."`](@ref @v_str). +Version number literals create [`VersionNumber`](@ref) objects which follow the +specifications of [semantic versioning](http://semver.org), and therefore are composed of major, minor and patch numeric values, followed by pre-release and build alpha-numeric annotations. For example, `v"0.2.1-rc1+win64"` is broken into major version `0`, minor version `2`, patch version `1`, pre-release `rc1` and build `win64`. When entering diff --git a/src/stdlib/Logging.md b/src/stdlib/Logging.md index fe8a44b..ba07f66 100644 --- a/src/stdlib/Logging.md +++ b/src/stdlib/Logging.md @@ -35,7 +35,7 @@ A = ones(Int, 4, 4) v = ones(100) @info "Some variables" A s=sum(v) -# Output +# output ┌ Info: Some variables │ A = │ 4×4 Array{Int64,2}: From 6814d616bb2d655d08fde198d509b8741de71ccf Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Mon, 21 May 2018 10:32:05 +0900 Subject: [PATCH 025/153] update Julia Commit 9a0ff525c1 --- codex/NEWS.md | 6 ++++ codex/base/base.md | 1 + codex/base/collections.md | 15 +++++---- codex/manual/code-loading.md | 14 ++++----- codex/manual/environment-variables.md | 6 ++-- codex/manual/interfaces.md | 45 +++++++++++---------------- codex/manual/modules.md | 6 ++-- codex/manual/strings.md | 5 --- src/NEWS.md | 6 ++++ src/base/base.md | 1 + src/base/collections.md | 15 +++++---- src/manual/code-loading.md | 14 ++++----- src/manual/environment-variables.md | 6 ++-- src/manual/interfaces.md | 45 +++++++++++---------------- src/manual/modules.md | 6 ++-- src/manual/strings.md | 5 --- 16 files changed, 92 insertions(+), 104 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index 34e7e2a..f6b1ae0 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -469,6 +469,9 @@ This section lists changes that do not have deprecation warnings. * `widen` on 8- and 16-bit integer types now widens to the platform word size (`Int`) instead of to a 32-bit type ([#26859](https://github.com/JuliaLang/julia/issues/26859)). + * `mv`,`cp`, `touch`, `mkdir`, `mkpath` now return the path that was created/modified + rather than `nothing` ([#27071](https://github.com/JuliaLang/julia/issues/27071)). + Library improvements -------------------- @@ -478,6 +481,9 @@ Library improvements * `Char` is now a subtype of `AbstractChar`, and most of the functions that take character arguments now accept any `AbstractChar` ([#26286](https://github.com/JuliaLang/julia/issues/26286)). + * `bytes2hex` now accepts an optional `io` argument to output to a hexadecimal stream + without allocating a `String` first ([#27121](https://github.com/JuliaLang/julia/issues/27121)). + * `String(array)` now accepts an arbitrary `AbstractVector{UInt8}`. For `Vector` inputs, it "steals" the memory buffer, leaving them with an empty buffer which is guaranteed not to be shared with the `String` object. For other types of vectors diff --git a/codex/base/base.md b/codex/base/base.md index d069375..6a879a1 100644 --- a/codex/base/base.md +++ b/codex/base/base.md @@ -28,6 +28,7 @@ Base.require Base.compilecache Base.__precompile__ Base.include +Base.MainInclude.include Base.include_string Base.include_dependency Base.which(::Any, ::Any) diff --git a/codex/base/collections.md b/codex/base/collections.md index 63ec437..4a64aea 100644 --- a/codex/base/collections.md +++ b/codex/base/collections.md @@ -2,11 +2,11 @@ ## [Iteration](@id lib-collections-iteration) -Sequential iteration is implemented by the methods [`start`](@ref), [`done`](@ref), and [`next`](@ref). +Sequential iteration is implemented by the [`iterate`](@ref) function. The general `for` loop: ```julia -for i = I # or "for i in I" +for i in iter # or "for i = iter" # body end ``` @@ -14,10 +14,11 @@ end is translated into: ```julia -state = start(I) -while !done(I, state) - (i, state) = next(I, state) +next = iterate(iter) +while next !== nothing + (i, state) = next # body + next = iterate(iter, state) end ``` @@ -26,9 +27,7 @@ See the [manual section on the iteration interface](@ref man-interface-iteration iterable type. ```@docs -Base.start -Base.done -Base.next +Base.iterate Base.IteratorSize Base.IteratorEltype ``` diff --git a/codex/manual/code-loading.md b/codex/manual/code-loading.md index cb37157..e95c37f 100644 --- a/codex/manual/code-loading.md +++ b/codex/manual/code-loading.md @@ -2,7 +2,7 @@ Julia has two mechanisms for loading code: -1. **Code inclusion:** e.g. `include("source.jl")`. Inclusion allows you to split a single program across multiple source files. The expression `include("source.jl")` causes the contents of the file `source.jl` to be evaluated inside of the module where the `include` call occurs. If `include("source.jl")` is called multiple times, `source.jl` is evaluated multiple times. The included path, `source.jl`, is interpreted relative to the file where the `include` call occurs. This makes it simple to relocate a subtree of source files. In the REPL, included paths are interpreted relative to the current working directory, `pwd()`. +1. **Code inclusion:** e.g. `include("source.jl")`. Inclusion allows you to split a single program across multiple source files. The expression `include("source.jl")` causes the contents of the file `source.jl` to be evaluated in the global scope of the module where the `include` call occurs. If `include("source.jl")` is called multiple times, `source.jl` is evaluated multiple times. The included path, `source.jl`, is interpreted relative to the file where the `include` call occurs. This makes it simple to relocate a subtree of source files. In the REPL, included paths are interpreted relative to the current working directory, `pwd()`. 2. **Package loading:** e.g. `import X` or `using X`. The import mechanism allows you to load a package—i.e. an independent, reusable collection of Julia code, wrapped in a module—and makes the resulting module available by the name `X` inside of the importing module. If the same `X` package is imported multiple times in the same Julia session, it is only loaded the first time—on subsequent imports, the importing module gets a reference to the same module. It should be noted, however, that `import X` can load different packages in different contexts: `X` can refer to one package named `X` in the main project but potentially different packages named `X` in each dependency. More on this below. Code inclusion is quite straightforward: it simply parses and evaluates a source file in the context of the caller. Package loading is built on top of code inclusion and is quite a bit more complex. The rest of this chapter, therefore, focuses on the behavior and mechanics of package loading. @@ -35,7 +35,7 @@ An *environment* determines what `import X` and `using X` mean in various code c These three kinds of environment each serve a different purpose: -* Project environments provide **reproducibility.** By checking a project environment into version control—i.e. a git repository—along with the rest of the project's source code, you can reproduce the exact state of the project _and_ all of its dependencies since the manifest file captures the exact version of every dependency and can be rematerialized easily. +* Project environments provide **reproducibility.** By checking a project environment into version control—e.g. a git repository—along with the rest of the project's source code, you can reproduce the exact state of the project _and_ all of its dependencies since the manifest file captures the exact version of every dependency and can be rematerialized easily. * Package directories provide low-overhead **convenience** when a project environment would be overkill: are handy when you have a set of packages and just want to put them somewhere and use them as they are without having to create and maintain a project environment for them. * Stacked environments allow for **augmentation** of the primary environment with additional tools. You can push an environment including development tools onto the stack and they will be available from the REPL and scripts but not from inside of packages. @@ -85,7 +85,7 @@ roots = Dict( Given this `roots` map, in the code of `App` the statement `import Priv` will cause Julia to look up `roots[:Priv]`, which yields `ba13f791-ae1d-465a-978b-69c3ad90f72b`, the UUID of the `Priv` package that is to be loaded in that context. This UUID identifies which `Priv` package to load and use when the main application evaluates `import Priv`. -**The dependency graph** of a project environment is determined by the contents of the manifest file, if present, or if there is no manifest file, `graph` is empty. A manifest file contains a stanza for each direct or indirect dependency of a project, including for each one, its UUID and exact version information and optionally an explicit path to its source code. Consider the following example manifest file for `App`: +**The dependency graph** of a project environment is determined by the contents of the manifest file, if present, or if there is no manifest file, `graph` is empty. A manifest file contains a stanza for each direct or indirect dependency of a project, including for each one, its UUID and a source tree hash or an explicit path to the source code. Consider the following example manifest file for `App`: ```toml [[Priv]] # the private one @@ -177,15 +177,15 @@ paths = Dict{Tuple{UUID,Symbol},String}( "/home/me/projects/App/deps/Priv/src/Priv.jl", # Priv – the public one: (UUID("2d15fe94-a1f7-436c-a4d8-07a9a496e01c"), :Priv) => - # package installed in the user depot: + # package installed in the system depot: "/usr/local/julia/packages/Priv/HDkr/src/Priv.jl", # Pub: (UUID("ba13f791-ae1d-465a-978b-69c3ad90f72b"), :Pub) => - # package installed in the system depot: + # package installed in the user depot: "/home/me/.julia/packages/Pub/oKpw/src/Pub.jl", # Zebra: (UUID("f7a24cb4-21fc-4002-ac70-f0e3a0dd3f62"), :Zebra) => - # package installed in the user depot: + # package installed in the system depot: "/usr/local/julia/packages/Zebra/me9k/src/Zebra.jl", ) ``` @@ -200,7 +200,7 @@ This example map includes three different kinds of package locations: Package directories provide a kind of environment that approximates package loading in Julia 0.6 and earlier, and which resembles package loading in many other dynamic languages. The set of packages available in a package directory corresponds to the set of subdirectories it contains that look like packages: if `X/src/X.jl` is a file in a package directory, then `X` is considered to be a package and `X/src/X.jl` is the file you load to get `X`. Which packages can "see" each other as dependencies depends on whether they contain project files or not and what appears in the `[deps]` sections of those project files. -**The roots map** is determined by the subdirectories of a package directory for which `X/src/X.jl` exists and whether `X/Project.toml` exists and has a top-level `uuid` entry. Specifically `:X => uuid` goes in `roots` for each such `X` where `uuid` is defined as: +**The roots map** is determined by the subdirectories `X` of a package directory for which `X/src/X.jl` exists and whether `X/Project.toml` exists and has a top-level `uuid` entry. Specifically `:X => uuid` goes in `roots` for each such `X` where `uuid` is defined as: 1. If `X/Project.toml` exists and has a `uuid` entry, then `uuid` is that value. 2. If `X/Project.toml` exists and but does *not* have a top-level UUID entry, `uuid` is a dummy UUID generated by hashing the canonical path of `X/Project.toml`. diff --git a/codex/manual/environment-variables.md b/codex/manual/environment-variables.md index 79bffcc..739335b 100644 --- a/codex/manual/environment-variables.md +++ b/codex/manual/environment-variables.md @@ -108,11 +108,11 @@ and the package repository for version 0.6 of Julia would be ### `JULIA_HISTORY` -The absolute path `Base.REPL.find_hist_file()` of the REPL's history file. If -`$JULIA_HISTORY` is not set, then `Base.REPL.find_hist_file()` defaults to +The absolute path `REPL.find_hist_file()` of the REPL's history file. If +`$JULIA_HISTORY` is not set, then `REPL.find_hist_file()` defaults to ``` -$HOME/.julia_history +$HOME/.julia/logs/repl_history.jl ``` ### `JULIA_PKGRESOLVE_ACCURACY` diff --git a/codex/manual/interfaces.md b/codex/manual/interfaces.md index 6d72c3d..9441ae1 100644 --- a/codex/manual/interfaces.md +++ b/codex/manual/interfaces.md @@ -9,9 +9,8 @@ to generically build upon those behaviors. | Required methods |   | Brief description | |:------------------------------ |:---------------------- |:------------------------------------------------------------------------------------- | -| `start(iter)` |   | Returns the initial iteration state | -| `next(iter, state)` |   | Returns the current item and the next state | -| `done(iter, state)` |   | Tests if there are any items remaining | +| `iterate(iter)` |   | Returns either a tuple of the first item and initial state or `nothing` if empty | +| `iterate(iter, state)` |   | Returns either a tuple of the next item and next state or `nothing` if no items remain | | **Important optional methods** | **Default definition** | **Brief description** | | `IteratorSize(IterType)` | `HasLength()` | One of `HasLength()`, `HasShape{N}()`, `IsInfinite()`, or `SizeUnknown()` as appropriate | | `IteratorEltype(IterType)` | `HasEltype()` | Either `EltypeUnknown()` or `HasEltype()` as appropriate | @@ -31,15 +30,14 @@ to generically build upon those behaviors. | `HasEltype()` | `eltype(IterType)` | | `EltypeUnknown()` | (*none*) | -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 -tests if there are any elements remaining, and `next(iter, state)`, which returns a tuple containing -the current element and an updated `state`. The `state` object can be anything, and is generally -considered to be an implementation detail private to the iterable object. +Sequential iteration is implemented by the [`iterate`](@ref) function. Instead +of mutating objects as they are iterated over, Julia iterators may keep track +of the iteration state externally from the object. The return value from iterate +is always either a tuple of a value and a state, or `nothing` if no elements remain. +The state object will be passed back to the iterate function on the next iteration +and is generally considered an implementation detail private to the iterable object. -Any object that defines these three methods is iterable and can be used in the [many functions that rely upon iteration](@ref lib-collections-iteration). +Any object that defines this function is iterable and can be used in the [many functions that rely upon iteration](@ref lib-collections-iteration). It can also be used directly in a `for` loop since the syntax: ```julia @@ -51,10 +49,11 @@ end is translated into: ```julia -state = start(iter) -while !done(iter, state) - (i, state) = next(iter, state) +next = iterate(iter) +while next !== nothing + (i, state) = next # body + next = iterate(iter, state) end ``` @@ -65,18 +64,14 @@ julia> struct Squares count::Int end -julia> Base.start(::Squares) = 1 - -julia> Base.next(S::Squares, state) = (state*state, state+1) - -julia> Base.done(S::Squares, state) = state > S.count +julia> Base.iterate(S::Squares, state=1) = state > S.count ? nothing : (state*state, state+1) julia> Base.eltype(::Type{Squares}) = Int # Note that this is defined for the type julia> Base.length(S::Squares) = S.count ``` -With only [`start`](@ref), [`next`](@ref), and [`done`](@ref) definitions, the `Squares` type is already pretty powerful. +With only [`iterate`](@ref) definition, the `Squares` type is already pretty powerful. We can iterate over all the elements: ```jldoctest squaretype @@ -142,16 +137,12 @@ be used in their specific case. It is also often useful to allow iteration over a collection in *reverse order* by iterating over [`Iterators.reverse(iterator)`](@ref). To actually support reverse-order iteration, however, an iterator -type `T` needs to implement `start`, `next`, and `done` methods for `Iterators.Reverse{T}`. +type `T` needs to implement `iterate` for `Iterators.Reverse{T}`. (Given `r::Iterators.Reverse{T}`, the underling iterator of type `T` is `r.itr`.) In our `Squares` example, we would implement `Iterators.Reverse{Squares}` methods: ```jldoctest squaretype -julia> Base.start(rS::Iterators.Reverse{Squares}) = rS.itr.count - -julia> Base.next(::Iterators.Reverse{Squares}, state) = (state*state, state-1) - -julia> Base.done(::Iterators.Reverse{Squares}, state) = state < 1 +julia> Base.iterate(rS::Iterators.Reverse{Squares}, state=rS.itr.count) = state < 1 ? nothing : (state*state, state-1) julia> collect(Iterators.reverse(Squares(4))) 4-element Array{Int64,1}: @@ -230,7 +221,7 @@ ourselves, we can officially define it as a subtype of an [`AbstractArray`](@ref | `IndexStyle(::Type)` | `IndexCartesian()` | Returns either `IndexLinear()` or `IndexCartesian()`. See the description below. | | `getindex(A, I...)` | defined in terms of scalar `getindex` | [Multidimensional and nonscalar indexing](@ref man-array-indexing) | | `setindex!(A, I...)` | defined in terms of scalar `setindex!` | [Multidimensional and nonscalar indexed assignment](@ref man-array-indexing) | -| `start`/`next`/`done` | defined in terms of scalar `getindex` | Iteration | +| `iterate` | defined in terms of scalar `getindex` | Iteration | | `length(A)` | `prod(size(A))` | Number of elements | | `similar(A)` | `similar(A, eltype(A), size(A))` | Return a mutable array with the same shape and element type | | `similar(A, ::Type{S})` | `similar(A, S, size(A))` | Return a mutable array with the same shape and the specified element type | diff --git a/codex/manual/modules.md b/codex/manual/modules.md index 20930e2..bf1a7ad 100644 --- a/codex/manual/modules.md +++ b/codex/manual/modules.md @@ -131,8 +131,9 @@ since this is needed in the vast majority of cases. ### Default top-level definitions and bare modules -In addition to `using Base`, modules also automatically contain a definition of the `eval` function, -which evaluates expressions within the context of that module. +In addition to `using Base`, modules also automatically contain +definitions of the `eval` and `include` functions, +which evaluate expressions/files within the global scope of that module. If these default definitions are not wanted, modules can be defined using the keyword `baremodule` instead (note: `Core` is still imported, as per above). In terms of `baremodule`, a standard @@ -145,6 +146,7 @@ using Base eval(x) = Core.eval(Mod, x) eval(m,x) = Core.eval(m, x) +include(p) = Base.include(Mod, p) ... diff --git a/codex/manual/strings.md b/codex/manual/strings.md index e5395d9..3fc8483 100644 --- a/codex/manual/strings.md +++ b/codex/manual/strings.md @@ -602,11 +602,6 @@ Some other useful functions include: * [`length(str, i, j)`](@ref) the number of valid character indices in `str` from `i` to `j`. * [`ncodeunits(str)`](@ref) number of [code units](https://en.wikipedia.org/wiki/Character_encoding#Terminology) in a string. * [`codeunit(str, i)`](@ref) gives the code unit value in the string `str` at index `i`. - * [`i = start(str)`](@ref start) gives the first valid index at which a character can be found in `str` - (typically 1). - * [`c, j = next(str,i)`](@ref next) returns next character at or after the index `i` and the next valid - character index following that. With [`start`](@ref) and [`lastindex`](@ref), can be used to iterate - through the characters in `str`. * [`thisind(str, i)`](@ref) given an arbitrary index into a string find the first index of the character into which the index points. * [`nextind(str, i, n=1)`](@ref) find the start of the `n`th character starting after index `i`. * [`prevind(str, i, n=1)`](@ref) find the start of the `n`th character starting before index `i`. diff --git a/src/NEWS.md b/src/NEWS.md index b00efe8..08f0b01 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -457,6 +457,9 @@ This section lists changes that do not have deprecation warnings. * `widen` on 8- and 16-bit integer types now widens to the platform word size (`Int`) instead of to a 32-bit type ([#26859](https://github.com/JuliaLang/julia/issues/26859)). + * `mv`,`cp`, `touch`, `mkdir`, `mkpath` now return the path that was created/modified + rather than `nothing` ([#27071](https://github.com/JuliaLang/julia/issues/27071)). + Library improvements -------------------- @@ -466,6 +469,9 @@ Library improvements * `Char` is now a subtype of `AbstractChar`, and most of the functions that take character arguments now accept any `AbstractChar` ([#26286](https://github.com/JuliaLang/julia/issues/26286)). + * `bytes2hex` now accepts an optional `io` argument to output to a hexadecimal stream + without allocating a `String` first ([#27121](https://github.com/JuliaLang/julia/issues/27121)). + * `String(array)` now accepts an arbitrary `AbstractVector{UInt8}`. For `Vector` inputs, it "steals" the memory buffer, leaving them with an empty buffer which is guaranteed not to be shared with the `String` object. For other types of vectors diff --git a/src/base/base.md b/src/base/base.md index d069375..6a879a1 100644 --- a/src/base/base.md +++ b/src/base/base.md @@ -28,6 +28,7 @@ Base.require Base.compilecache Base.__precompile__ Base.include +Base.MainInclude.include Base.include_string Base.include_dependency Base.which(::Any, ::Any) diff --git a/src/base/collections.md b/src/base/collections.md index 63ec437..4a64aea 100644 --- a/src/base/collections.md +++ b/src/base/collections.md @@ -2,11 +2,11 @@ ## [Iteration](@id lib-collections-iteration) -Sequential iteration is implemented by the methods [`start`](@ref), [`done`](@ref), and [`next`](@ref). +Sequential iteration is implemented by the [`iterate`](@ref) function. The general `for` loop: ```julia -for i = I # or "for i in I" +for i in iter # or "for i = iter" # body end ``` @@ -14,10 +14,11 @@ end is translated into: ```julia -state = start(I) -while !done(I, state) - (i, state) = next(I, state) +next = iterate(iter) +while next !== nothing + (i, state) = next # body + next = iterate(iter, state) end ``` @@ -26,9 +27,7 @@ See the [manual section on the iteration interface](@ref man-interface-iteration iterable type. ```@docs -Base.start -Base.done -Base.next +Base.iterate Base.IteratorSize Base.IteratorEltype ``` diff --git a/src/manual/code-loading.md b/src/manual/code-loading.md index cb37157..e95c37f 100644 --- a/src/manual/code-loading.md +++ b/src/manual/code-loading.md @@ -2,7 +2,7 @@ Julia has two mechanisms for loading code: -1. **Code inclusion:** e.g. `include("source.jl")`. Inclusion allows you to split a single program across multiple source files. The expression `include("source.jl")` causes the contents of the file `source.jl` to be evaluated inside of the module where the `include` call occurs. If `include("source.jl")` is called multiple times, `source.jl` is evaluated multiple times. The included path, `source.jl`, is interpreted relative to the file where the `include` call occurs. This makes it simple to relocate a subtree of source files. In the REPL, included paths are interpreted relative to the current working directory, `pwd()`. +1. **Code inclusion:** e.g. `include("source.jl")`. Inclusion allows you to split a single program across multiple source files. The expression `include("source.jl")` causes the contents of the file `source.jl` to be evaluated in the global scope of the module where the `include` call occurs. If `include("source.jl")` is called multiple times, `source.jl` is evaluated multiple times. The included path, `source.jl`, is interpreted relative to the file where the `include` call occurs. This makes it simple to relocate a subtree of source files. In the REPL, included paths are interpreted relative to the current working directory, `pwd()`. 2. **Package loading:** e.g. `import X` or `using X`. The import mechanism allows you to load a package—i.e. an independent, reusable collection of Julia code, wrapped in a module—and makes the resulting module available by the name `X` inside of the importing module. If the same `X` package is imported multiple times in the same Julia session, it is only loaded the first time—on subsequent imports, the importing module gets a reference to the same module. It should be noted, however, that `import X` can load different packages in different contexts: `X` can refer to one package named `X` in the main project but potentially different packages named `X` in each dependency. More on this below. Code inclusion is quite straightforward: it simply parses and evaluates a source file in the context of the caller. Package loading is built on top of code inclusion and is quite a bit more complex. The rest of this chapter, therefore, focuses on the behavior and mechanics of package loading. @@ -35,7 +35,7 @@ An *environment* determines what `import X` and `using X` mean in various code c These three kinds of environment each serve a different purpose: -* Project environments provide **reproducibility.** By checking a project environment into version control—i.e. a git repository—along with the rest of the project's source code, you can reproduce the exact state of the project _and_ all of its dependencies since the manifest file captures the exact version of every dependency and can be rematerialized easily. +* Project environments provide **reproducibility.** By checking a project environment into version control—e.g. a git repository—along with the rest of the project's source code, you can reproduce the exact state of the project _and_ all of its dependencies since the manifest file captures the exact version of every dependency and can be rematerialized easily. * Package directories provide low-overhead **convenience** when a project environment would be overkill: are handy when you have a set of packages and just want to put them somewhere and use them as they are without having to create and maintain a project environment for them. * Stacked environments allow for **augmentation** of the primary environment with additional tools. You can push an environment including development tools onto the stack and they will be available from the REPL and scripts but not from inside of packages. @@ -85,7 +85,7 @@ roots = Dict( Given this `roots` map, in the code of `App` the statement `import Priv` will cause Julia to look up `roots[:Priv]`, which yields `ba13f791-ae1d-465a-978b-69c3ad90f72b`, the UUID of the `Priv` package that is to be loaded in that context. This UUID identifies which `Priv` package to load and use when the main application evaluates `import Priv`. -**The dependency graph** of a project environment is determined by the contents of the manifest file, if present, or if there is no manifest file, `graph` is empty. A manifest file contains a stanza for each direct or indirect dependency of a project, including for each one, its UUID and exact version information and optionally an explicit path to its source code. Consider the following example manifest file for `App`: +**The dependency graph** of a project environment is determined by the contents of the manifest file, if present, or if there is no manifest file, `graph` is empty. A manifest file contains a stanza for each direct or indirect dependency of a project, including for each one, its UUID and a source tree hash or an explicit path to the source code. Consider the following example manifest file for `App`: ```toml [[Priv]] # the private one @@ -177,15 +177,15 @@ paths = Dict{Tuple{UUID,Symbol},String}( "/home/me/projects/App/deps/Priv/src/Priv.jl", # Priv – the public one: (UUID("2d15fe94-a1f7-436c-a4d8-07a9a496e01c"), :Priv) => - # package installed in the user depot: + # package installed in the system depot: "/usr/local/julia/packages/Priv/HDkr/src/Priv.jl", # Pub: (UUID("ba13f791-ae1d-465a-978b-69c3ad90f72b"), :Pub) => - # package installed in the system depot: + # package installed in the user depot: "/home/me/.julia/packages/Pub/oKpw/src/Pub.jl", # Zebra: (UUID("f7a24cb4-21fc-4002-ac70-f0e3a0dd3f62"), :Zebra) => - # package installed in the user depot: + # package installed in the system depot: "/usr/local/julia/packages/Zebra/me9k/src/Zebra.jl", ) ``` @@ -200,7 +200,7 @@ This example map includes three different kinds of package locations: Package directories provide a kind of environment that approximates package loading in Julia 0.6 and earlier, and which resembles package loading in many other dynamic languages. The set of packages available in a package directory corresponds to the set of subdirectories it contains that look like packages: if `X/src/X.jl` is a file in a package directory, then `X` is considered to be a package and `X/src/X.jl` is the file you load to get `X`. Which packages can "see" each other as dependencies depends on whether they contain project files or not and what appears in the `[deps]` sections of those project files. -**The roots map** is determined by the subdirectories of a package directory for which `X/src/X.jl` exists and whether `X/Project.toml` exists and has a top-level `uuid` entry. Specifically `:X => uuid` goes in `roots` for each such `X` where `uuid` is defined as: +**The roots map** is determined by the subdirectories `X` of a package directory for which `X/src/X.jl` exists and whether `X/Project.toml` exists and has a top-level `uuid` entry. Specifically `:X => uuid` goes in `roots` for each such `X` where `uuid` is defined as: 1. If `X/Project.toml` exists and has a `uuid` entry, then `uuid` is that value. 2. If `X/Project.toml` exists and but does *not* have a top-level UUID entry, `uuid` is a dummy UUID generated by hashing the canonical path of `X/Project.toml`. diff --git a/src/manual/environment-variables.md b/src/manual/environment-variables.md index 79bffcc..739335b 100644 --- a/src/manual/environment-variables.md +++ b/src/manual/environment-variables.md @@ -108,11 +108,11 @@ and the package repository for version 0.6 of Julia would be ### `JULIA_HISTORY` -The absolute path `Base.REPL.find_hist_file()` of the REPL's history file. If -`$JULIA_HISTORY` is not set, then `Base.REPL.find_hist_file()` defaults to +The absolute path `REPL.find_hist_file()` of the REPL's history file. If +`$JULIA_HISTORY` is not set, then `REPL.find_hist_file()` defaults to ``` -$HOME/.julia_history +$HOME/.julia/logs/repl_history.jl ``` ### `JULIA_PKGRESOLVE_ACCURACY` diff --git a/src/manual/interfaces.md b/src/manual/interfaces.md index 6d72c3d..9441ae1 100644 --- a/src/manual/interfaces.md +++ b/src/manual/interfaces.md @@ -9,9 +9,8 @@ to generically build upon those behaviors. | Required methods |   | Brief description | |:------------------------------ |:---------------------- |:------------------------------------------------------------------------------------- | -| `start(iter)` |   | Returns the initial iteration state | -| `next(iter, state)` |   | Returns the current item and the next state | -| `done(iter, state)` |   | Tests if there are any items remaining | +| `iterate(iter)` |   | Returns either a tuple of the first item and initial state or `nothing` if empty | +| `iterate(iter, state)` |   | Returns either a tuple of the next item and next state or `nothing` if no items remain | | **Important optional methods** | **Default definition** | **Brief description** | | `IteratorSize(IterType)` | `HasLength()` | One of `HasLength()`, `HasShape{N}()`, `IsInfinite()`, or `SizeUnknown()` as appropriate | | `IteratorEltype(IterType)` | `HasEltype()` | Either `EltypeUnknown()` or `HasEltype()` as appropriate | @@ -31,15 +30,14 @@ to generically build upon those behaviors. | `HasEltype()` | `eltype(IterType)` | | `EltypeUnknown()` | (*none*) | -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 -tests if there are any elements remaining, and `next(iter, state)`, which returns a tuple containing -the current element and an updated `state`. The `state` object can be anything, and is generally -considered to be an implementation detail private to the iterable object. +Sequential iteration is implemented by the [`iterate`](@ref) function. Instead +of mutating objects as they are iterated over, Julia iterators may keep track +of the iteration state externally from the object. The return value from iterate +is always either a tuple of a value and a state, or `nothing` if no elements remain. +The state object will be passed back to the iterate function on the next iteration +and is generally considered an implementation detail private to the iterable object. -Any object that defines these three methods is iterable and can be used in the [many functions that rely upon iteration](@ref lib-collections-iteration). +Any object that defines this function is iterable and can be used in the [many functions that rely upon iteration](@ref lib-collections-iteration). It can also be used directly in a `for` loop since the syntax: ```julia @@ -51,10 +49,11 @@ end is translated into: ```julia -state = start(iter) -while !done(iter, state) - (i, state) = next(iter, state) +next = iterate(iter) +while next !== nothing + (i, state) = next # body + next = iterate(iter, state) end ``` @@ -65,18 +64,14 @@ julia> struct Squares count::Int end -julia> Base.start(::Squares) = 1 - -julia> Base.next(S::Squares, state) = (state*state, state+1) - -julia> Base.done(S::Squares, state) = state > S.count +julia> Base.iterate(S::Squares, state=1) = state > S.count ? nothing : (state*state, state+1) julia> Base.eltype(::Type{Squares}) = Int # Note that this is defined for the type julia> Base.length(S::Squares) = S.count ``` -With only [`start`](@ref), [`next`](@ref), and [`done`](@ref) definitions, the `Squares` type is already pretty powerful. +With only [`iterate`](@ref) definition, the `Squares` type is already pretty powerful. We can iterate over all the elements: ```jldoctest squaretype @@ -142,16 +137,12 @@ be used in their specific case. It is also often useful to allow iteration over a collection in *reverse order* by iterating over [`Iterators.reverse(iterator)`](@ref). To actually support reverse-order iteration, however, an iterator -type `T` needs to implement `start`, `next`, and `done` methods for `Iterators.Reverse{T}`. +type `T` needs to implement `iterate` for `Iterators.Reverse{T}`. (Given `r::Iterators.Reverse{T}`, the underling iterator of type `T` is `r.itr`.) In our `Squares` example, we would implement `Iterators.Reverse{Squares}` methods: ```jldoctest squaretype -julia> Base.start(rS::Iterators.Reverse{Squares}) = rS.itr.count - -julia> Base.next(::Iterators.Reverse{Squares}, state) = (state*state, state-1) - -julia> Base.done(::Iterators.Reverse{Squares}, state) = state < 1 +julia> Base.iterate(rS::Iterators.Reverse{Squares}, state=rS.itr.count) = state < 1 ? nothing : (state*state, state-1) julia> collect(Iterators.reverse(Squares(4))) 4-element Array{Int64,1}: @@ -230,7 +221,7 @@ ourselves, we can officially define it as a subtype of an [`AbstractArray`](@ref | `IndexStyle(::Type)` | `IndexCartesian()` | Returns either `IndexLinear()` or `IndexCartesian()`. See the description below. | | `getindex(A, I...)` | defined in terms of scalar `getindex` | [Multidimensional and nonscalar indexing](@ref man-array-indexing) | | `setindex!(A, I...)` | defined in terms of scalar `setindex!` | [Multidimensional and nonscalar indexed assignment](@ref man-array-indexing) | -| `start`/`next`/`done` | defined in terms of scalar `getindex` | Iteration | +| `iterate` | defined in terms of scalar `getindex` | Iteration | | `length(A)` | `prod(size(A))` | Number of elements | | `similar(A)` | `similar(A, eltype(A), size(A))` | Return a mutable array with the same shape and element type | | `similar(A, ::Type{S})` | `similar(A, S, size(A))` | Return a mutable array with the same shape and the specified element type | diff --git a/src/manual/modules.md b/src/manual/modules.md index 20930e2..bf1a7ad 100644 --- a/src/manual/modules.md +++ b/src/manual/modules.md @@ -131,8 +131,9 @@ since this is needed in the vast majority of cases. ### Default top-level definitions and bare modules -In addition to `using Base`, modules also automatically contain a definition of the `eval` function, -which evaluates expressions within the context of that module. +In addition to `using Base`, modules also automatically contain +definitions of the `eval` and `include` functions, +which evaluate expressions/files within the global scope of that module. If these default definitions are not wanted, modules can be defined using the keyword `baremodule` instead (note: `Core` is still imported, as per above). In terms of `baremodule`, a standard @@ -145,6 +146,7 @@ using Base eval(x) = Core.eval(Mod, x) eval(m,x) = Core.eval(m, x) +include(p) = Base.include(Mod, p) ... diff --git a/src/manual/strings.md b/src/manual/strings.md index e5395d9..3fc8483 100644 --- a/src/manual/strings.md +++ b/src/manual/strings.md @@ -602,11 +602,6 @@ Some other useful functions include: * [`length(str, i, j)`](@ref) the number of valid character indices in `str` from `i` to `j`. * [`ncodeunits(str)`](@ref) number of [code units](https://en.wikipedia.org/wiki/Character_encoding#Terminology) in a string. * [`codeunit(str, i)`](@ref) gives the code unit value in the string `str` at index `i`. - * [`i = start(str)`](@ref start) gives the first valid index at which a character can be found in `str` - (typically 1). - * [`c, j = next(str,i)`](@ref next) returns next character at or after the index `i` and the next valid - character index following that. With [`start`](@ref) and [`lastindex`](@ref), can be used to iterate - through the characters in `str`. * [`thisind(str, i)`](@ref) given an arbitrary index into a string find the first index of the character into which the index points. * [`nextind(str, i, n=1)`](@ref) find the start of the `n`th character starting after index `i`. * [`prevind(str, i, n=1)`](@ref) find the start of the `n`th character starting before index `i`. From ce8ac3262ede7bd17b2d28d50b43cc29eccac2b7 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Tue, 22 May 2018 11:34:46 +0900 Subject: [PATCH 026/153] update Julia Commit dc30e38e76 --- codex/assets/julia-manual.css | 3 + codex/base/base.md | 1 + codex/index.md | 178 +++++++++++++--------------------- codex/manual/introduction.md | 75 -------------- codex/manual/modules.md | 1 - make.jl | 3 +- src/assets/julia-manual.css | 3 + src/base/base.md | 1 + src/index.md | 163 ++++++++++--------------------- src/manual/introduction.md | 56 ----------- src/manual/modules.md | 1 - 11 files changed, 127 insertions(+), 358 deletions(-) create mode 100644 codex/assets/julia-manual.css delete mode 100644 codex/manual/introduction.md create mode 100644 src/assets/julia-manual.css delete mode 100644 src/manual/introduction.md diff --git a/codex/assets/julia-manual.css b/codex/assets/julia-manual.css new file mode 100644 index 0000000..00772f3 --- /dev/null +++ b/codex/assets/julia-manual.css @@ -0,0 +1,3 @@ +nav.toc h1 { + display: none; +} diff --git a/codex/base/base.md b/codex/base/base.md index 6a879a1..71be16a 100644 --- a/codex/base/base.md +++ b/codex/base/base.md @@ -205,6 +205,7 @@ Base.:(∘) ```@docs Core.eval +Base.MainInclude.eval Base.@eval Base.evalfile Base.esc diff --git a/codex/index.md b/codex/index.md index 1eae84b..c7420bc 100644 --- a/codex/index.md +++ b/codex/index.md @@ -4,122 +4,78 @@ Welcome to the documentation for Julia 0.7. Please read the [release notes](NEWS.md) to see what has changed since the last release. -* [Manual](#Manual-1) -* [Base](#Base-1) -* [Standard Library](#Standard-Library-1) -* [Developer Documentation](#Developer-Documentation-1) +### [Introduction](@id man-introduction) -## Manual +Scientific computing has traditionally required the highest performance, yet domain experts have +largely moved to slower dynamic languages for daily work. We believe there are many good reasons +to prefer dynamic languages for these applications, and we do not expect their use to diminish. +Fortunately, modern language design and compiler techniques make it possible to mostly eliminate +the performance trade-off and provide a single environment productive enough for prototyping and +efficient enough for deploying performance-intensive applications. The Julia programming language +fills this role: it is a flexible dynamic language, appropriate for scientific and numerical computing, +with performance comparable to traditional statically-typed languages. - * [Introduction](@ref man-introduction) - * [Getting Started](@ref man-getting-started) - * [Variables](@ref) - * [Integers and Floating-Point Numbers](@ref) - * [Mathematical Operations and Elementary Functions](@ref) - * [Complex and Rational Numbers](@ref) - * [Strings](@ref man-strings) - * [Functions](@ref man-functions) - * [Control Flow](@ref) - * [Scope of Variables](@ref scope-of-variables) - * [Types](@ref man-types) - * [Methods](@ref) - * [Constructors](@ref man-constructors) - * [Conversion and Promotion](@ref conversion-and-promotion) - * [Interfaces](@ref) - * [Modules](@ref modules) - * [Documentation](@ref) - * [Metaprogramming](@ref) - * [Multi-dimensional Arrays](@ref man-multi-dim-arrays) - * [Missing Values](@ref missing) - * [Networking and Streams](@ref) - * [Parallel Computing](@ref) - * [Running External Programs](@ref) - * [Calling C and Fortran Code](@ref) - * [Handling Operating System Variation](@ref) - * [Environment Variables](@ref) - * [Embedding Julia](@ref) - * [Packages](@ref) - * [Profiling](@ref) - * [Stack Traces](@ref) - * [Performance Tips](@ref man-performance-tips) - * [Workflow Tips](@ref man-workflow-tips) - * [Style Guide](@ref) - * [Frequently Asked Questions](@ref) - * [Noteworthy Differences from other Languages](@ref) - * [Unicode Input](@ref) +Because Julia's compiler is different from the interpreters used for languages like Python or +R, you may find that Julia's performance is unintuitive at first. If you find that something is +slow, we highly recommend reading through the [Performance Tips](@ref man-performance-tips) section before trying anything +else. Once you understand how Julia works, it's easy to write code that's nearly as fast as C. -## Base +Julia features optional typing, multiple dispatch, and good performance, achieved using type inference +and [just-in-time (JIT) compilation](https://en.wikipedia.org/wiki/Just-in-time_compilation), +implemented using [LLVM](https://en.wikipedia.org/wiki/Low_Level_Virtual_Machine). It is multi-paradigm, +combining features of imperative, functional, and object-oriented programming. Julia provides +ease and expressiveness for high-level numerical computing, in the same way as languages such +as R, MATLAB, and Python, but also supports general programming. To achieve this, Julia builds +upon the lineage of mathematical programming languages, but also borrows much from popular dynamic +languages, including [Lisp](https://en.wikipedia.org/wiki/Lisp_(programming_language)), [Perl](https://en.wikipedia.org/wiki/Perl_(programming_language)), +[Python](https://en.wikipedia.org/wiki/Python_(programming_language)), [Lua](https://en.wikipedia.org/wiki/Lua_(programming_language)), +and [Ruby](https://en.wikipedia.org/wiki/Ruby_(programming_language)). - * [Essentials](@ref) - * [Collections and Data Structures](@ref) - * [Mathematics](@ref) - * [Numbers](@ref lib-numbers) - * [Strings](@ref lib-strings) - * [Arrays](@ref lib-arrays) - * [Tasks](@ref) - * [Distributed Computing](@ref) - * [Multi-Threading](@ref) - * [Shared Arrays](@ref) - * [Constants](@ref lib-constants) - * [Filesystem](@ref) - * [I/O and Network](@ref) - * [Punctuation](@ref) - * [Sorting and Related Functions](@ref) - * [Package Manager Functions](@ref) - * [Iteration utilities](@ref) - * [C Interface](@ref) - * [C Standard Library](@ref) - * [Dynamic Linker](@ref) - * [StackTraces](@ref) - * [SIMD Support](@ref) +The most significant departures of Julia from typical dynamic languages are: -## Standard Library + * The core language imposes very little; Julia Base and the standard library is written in Julia itself, including + primitive operations like integer arithmetic + * A rich language of types for constructing and describing objects, that can also optionally be + used to make type declarations + * The ability to define function behavior across many combinations of argument types via [multiple dispatch](https://en.wikipedia.org/wiki/Multiple_dispatch) + * Automatic generation of efficient, specialized code for different argument types + * Good performance, approaching that of statically-compiled languages like C - * [The Julia REPL](@ref) - * [Base64](@ref) - * [CRC32c](@ref) - * [SHA](@ref) - * [Dates](@ref) - * [Delimited Files](@ref) - * [Distributed Computing](@ref) - * [File Events](@ref lib-filewatching) - * [Iterative Eigensolvers](@ref lib-itereigen) - * [Memory-mapped I/O](@ref) - * [Printf](@ref) - * [Profiling](@ref lib-profiling) - * [Random Numbers](@ref) - * [Shared Arrays](@ref) - * [Linear Algebra](@ref) - * [Logging](@ref) - * [Sparse Arrays](@ref) - * [Unicode](@ref) - * [Unit Testing](@ref) +Although one sometimes speaks of dynamic languages as being "typeless", they are definitely not: +every object, whether primitive or user-defined, has a type. The lack of type declarations in +most dynamic languages, however, means that one cannot instruct the compiler about the types of +values, and often cannot explicitly talk about types at all. In static languages, on the other +hand, while one can -- and usually must -- annotate types for the compiler, types exist only at +compile time and cannot be manipulated or expressed at run time. In Julia, types are themselves +run-time objects, and can also be used to convey information to the compiler. -## Developer Documentation +While the casual programmer need not explicitly use types or multiple dispatch, they are the core +unifying features of Julia: functions are defined on different combinations of argument types, +and applied by dispatching to the most specific matching definition. This model is a good fit +for mathematical programming, where it is unnatural for the first argument to "own" an operation +as in traditional object-oriented dispatch. Operators are just functions with special notation +-- to extend addition to new user-defined data types, you define new methods for the `+` function. +Existing code then seamlessly applies to the new data types. - * [Reflection and introspection](@ref) - * Documentation of Julia's Internals - * [Initialization of the Julia runtime](@ref) - * [Julia ASTs](@ref) - * [More about types](@ref) - * [Memory layout of Julia Objects](@ref) - * [Eval of Julia code](@ref) - * [Calling Conventions](@ref) - * [High-level Overview of the Native-Code Generation Process](@ref) - * [Julia Functions](@ref) - * [Base.Cartesian](@ref) - * [Talking to the compiler (the `:meta` mechanism)](@ref) - * [SubArrays](@ref) - * [System Image Building](@ref) - * [Working with LLVM](@ref) - * [printf() and stdio in the Julia runtime](@ref) - * [Bounds checking](@ref) - * [Proper maintenance and care of multi-threading locks](@ref) - * [Arrays with custom indices](@ref man-custom-indices) - * [Module loading](@ref) - * [Inference](@ref) - * Developing/debugging Julia's C code - * [Reporting and analyzing crashes (segfaults)](@ref) - * [gdb debugging tips](@ref) - * [Using Valgrind with Julia](@ref) - * [Sanitizer support](@ref) +Partly because of run-time type inference (augmented by optional type annotations), and partly +because of a strong focus on performance from the inception of the project, Julia's computational +efficiency exceeds that of other dynamic languages, and even rivals that of statically-compiled +languages. For large scale numerical problems, speed always has been, continues to be, and probably +always will be crucial: the amount of data being processed has easily kept pace with Moore's Law +over the past decades. + +Julia aims to create an unprecedented combination of ease-of-use, power, and efficiency in a single +language. In addition to the above, some advantages of Julia over comparable systems include: + + * Free and open source ([MIT licensed](https://github.com/JuliaLang/julia/blob/master/LICENSE.md)) + * User-defined types are as fast and compact as built-ins + * No need to vectorize code for performance; devectorized code is fast + * Designed for parallelism and distributed computation + * Lightweight "green" threading ([coroutines](https://en.wikipedia.org/wiki/Coroutine)) + * Unobtrusive yet powerful type system + * Elegant and extensible conversions and promotions for numeric and other types + * Efficient support for [Unicode](https://en.wikipedia.org/wiki/Unicode), including but not limited + to [UTF-8](https://en.wikipedia.org/wiki/UTF-8) + * Call C functions directly (no wrappers or special APIs needed) + * Powerful shell-like capabilities for managing other processes + * Lisp-like macros and other metaprogramming facilities diff --git a/codex/manual/introduction.md b/codex/manual/introduction.md deleted file mode 100644 index ec75297..0000000 --- a/codex/manual/introduction.md +++ /dev/null @@ -1,75 +0,0 @@ -# [Introduction](@id man-introduction) - -Scientific computing has traditionally required the highest performance, yet domain experts have -largely moved to slower dynamic languages for daily work. We believe there are many good reasons -to prefer dynamic languages for these applications, and we do not expect their use to diminish. -Fortunately, modern language design and compiler techniques make it possible to mostly eliminate -the performance trade-off and provide a single environment productive enough for prototyping and -efficient enough for deploying performance-intensive applications. The Julia programming language -fills this role: it is a flexible dynamic language, appropriate for scientific and numerical computing, -with performance comparable to traditional statically-typed languages. - -Because Julia's compiler is different from the interpreters used for languages like Python or -R, you may find that Julia's performance is unintuitive at first. If you find that something is -slow, we highly recommend reading through the [Performance Tips](@ref man-performance-tips) section before trying anything -else. Once you understand how Julia works, it's easy to write code that's nearly as fast as C. - -Julia features optional typing, multiple dispatch, and good performance, achieved using type inference -and [just-in-time (JIT) compilation](https://en.wikipedia.org/wiki/Just-in-time_compilation), -implemented using [LLVM](https://en.wikipedia.org/wiki/Low_Level_Virtual_Machine). It is multi-paradigm, -combining features of imperative, functional, and object-oriented programming. Julia provides -ease and expressiveness for high-level numerical computing, in the same way as languages such -as R, MATLAB, and Python, but also supports general programming. To achieve this, Julia builds -upon the lineage of mathematical programming languages, but also borrows much from popular dynamic -languages, including [Lisp](https://en.wikipedia.org/wiki/Lisp_(programming_language)), [Perl](https://en.wikipedia.org/wiki/Perl_(programming_language)), -[Python](https://en.wikipedia.org/wiki/Python_(programming_language)), [Lua](https://en.wikipedia.org/wiki/Lua_(programming_language)), -and [Ruby](https://en.wikipedia.org/wiki/Ruby_(programming_language)). - -The most significant departures of Julia from typical dynamic languages are: - - * The core language imposes very little; Julia Base and the standard library is written in Julia itself, including - primitive operations like integer arithmetic - * A rich language of types for constructing and describing objects, that can also optionally be - used to make type declarations - * The ability to define function behavior across many combinations of argument types via [multiple dispatch](https://en.wikipedia.org/wiki/Multiple_dispatch) - * Automatic generation of efficient, specialized code for different argument types - * Good performance, approaching that of statically-compiled languages like C - -Although one sometimes speaks of dynamic languages as being "typeless", they are definitely not: -every object, whether primitive or user-defined, has a type. The lack of type declarations in -most dynamic languages, however, means that one cannot instruct the compiler about the types of -values, and often cannot explicitly talk about types at all. In static languages, on the other -hand, while one can -- and usually must -- annotate types for the compiler, types exist only at -compile time and cannot be manipulated or expressed at run time. In Julia, types are themselves -run-time objects, and can also be used to convey information to the compiler. - -While the casual programmer need not explicitly use types or multiple dispatch, they are the core -unifying features of Julia: functions are defined on different combinations of argument types, -and applied by dispatching to the most specific matching definition. This model is a good fit -for mathematical programming, where it is unnatural for the first argument to "own" an operation -as in traditional object-oriented dispatch. Operators are just functions with special notation --- to extend addition to new user-defined data types, you define new methods for the `+` function. -Existing code then seamlessly applies to the new data types. - -Partly because of run-time type inference (augmented by optional type annotations), and partly -because of a strong focus on performance from the inception of the project, Julia's computational -efficiency exceeds that of other dynamic languages, and even rivals that of statically-compiled -languages. For large scale numerical problems, speed always has been, continues to be, and probably -always will be crucial: the amount of data being processed has easily kept pace with Moore's Law -over the past decades. - -Julia aims to create an unprecedented combination of ease-of-use, power, and efficiency in a single -language. In addition to the above, some advantages of Julia over comparable systems include: - - * Free and open source ([MIT licensed](https://github.com/JuliaLang/julia/blob/master/LICENSE.md)) - * User-defined types are as fast and compact as built-ins - * No need to vectorize code for performance; devectorized code is fast - * Designed for parallelism and distributed computation - * Lightweight "green" threading ([coroutines](https://en.wikipedia.org/wiki/Coroutine)) - * Unobtrusive yet powerful type system - * Elegant and extensible conversions and promotions for numeric and other types - * Efficient support for [Unicode](https://en.wikipedia.org/wiki/Unicode), including but not limited - to [UTF-8](https://en.wikipedia.org/wiki/UTF-8) - * Call C functions directly (no wrappers or special APIs needed) - * Powerful shell-like capabilities for managing other processes - * Lisp-like macros and other metaprogramming facilities diff --git a/codex/manual/modules.md b/codex/manual/modules.md index bf1a7ad..a12f873 100644 --- a/codex/manual/modules.md +++ b/codex/manual/modules.md @@ -145,7 +145,6 @@ baremodule Mod using Base eval(x) = Core.eval(Mod, x) -eval(m,x) = Core.eval(m, x) include(p) = Base.include(Mod, p) ... diff --git a/make.jl b/make.jl index b1b48a4..37b92e6 100644 --- a/make.jl +++ b/make.jl @@ -35,7 +35,6 @@ const PAGES = [ "홈" => "index.md", hide("NEWS.md"), "매뉴얼" => [ - "manual/introduction.md", "manual/getting-started.md", "manual/variables.md", "manual/integers-and-floating-point-numbers.md", @@ -117,13 +116,13 @@ const PAGES = [ "devdocs/offset-arrays.md", "devdocs/require.md", "devdocs/inference.md", - "devdocs/ssair.md", # Julia SSA-form IR ], "Developing/debugging Julia's C code" => [ "devdocs/backtraces.md", "devdocs/debuggingtips.md", "devdocs/valgrind.md", "devdocs/sanitizers.md", + "devdocs/ssair.md", # Julia SSA-form IR ] ], ] diff --git a/src/assets/julia-manual.css b/src/assets/julia-manual.css new file mode 100644 index 0000000..00772f3 --- /dev/null +++ b/src/assets/julia-manual.css @@ -0,0 +1,3 @@ +nav.toc h1 { + display: none; +} diff --git a/src/base/base.md b/src/base/base.md index 6a879a1..71be16a 100644 --- a/src/base/base.md +++ b/src/base/base.md @@ -205,6 +205,7 @@ Base.:(∘) ```@docs Core.eval +Base.MainInclude.eval Base.@eval Base.evalfile Base.esc diff --git a/src/index.md b/src/index.md index b1b6913..f50e24b 100644 --- a/src/index.md +++ b/src/index.md @@ -4,124 +4,63 @@ 지난 버전에 이어, 새롭게 바뀐 점은 [릴리즈 노트](NEWS.md)에서 확인하세요. -한글 문서 번역은 [깃헙](https://github.com/juliakorea/translate-doc)에서 누구나 참여하실 수 있습니다. +!!! note + 한글 문서 번역은 [깃헙](https://github.com/juliakorea/translate-doc)에서 누구나 참여하실 수 있습니다. -* [매뉴얼](#Manual-1) -* [Base](#Base-1) -* [Standard Library](#Standard-Library-1) -* [Developer Documentation](#Developer-Documentation-1) -## 매뉴얼 +### [소개글](@id man-introduction) - * [소개글](@ref man-introduction) - * [시작하기](@ref man-getting-started) - * [변수](@ref Variables) - * [정수와 부동 소수점 수](@ref Integers-and-Floating-Point-Numbers) - * [Mathematical Operations and Elementary Functions](@ref) - * [Complex and Rational Numbers](@ref) - * [Strings](@ref man-strings) - * [Functions](@ref man-functions) - * [Control Flow](@ref) - * [Scope of Variables](@ref scope-of-variables) - * [Types](@ref man-types) - * [메서드](@ref Methods) - * [Constructors](@ref man-constructors) - * [Conversion and Promotion](@ref conversion-and-promotion) - * [Interfaces](@ref) - * [Modules](@ref modules) - * [Documentation](@ref) - * [Metaprogramming](@ref) - * [Multi-dimensional Arrays](@ref man-multi-dim-arrays) - * [Missing Values](@ref missing) - * [Networking and Streams](@ref) - * [Parallel Computing](@ref) - * [Running External Programs](@ref) - * [Calling C and Fortran Code](@ref) - * [Handling Operating System Variation](@ref) - * [Environment Variables](@ref) - * [Embedding Julia](@ref) - * [Packages](@ref) - * [Profiling](@ref) - * [Stack Traces](@ref) - * [Performance Tips](@ref man-performance-tips) - * [Workflow Tips](@ref man-workflow-tips) - * [Style Guide](@ref) - * [Frequently Asked Questions](@ref) - * [Noteworthy Differences from other Languages](@ref) - * [Unicode Input](@ref) +과학 분야 컴퓨팅은 전통적으로 최고의 성능을 요구하지만, 당사자인 전문 연구자들은 속도가 느리더라도 동적인 언어로서 그들의 업무를 처리한다. +동적 언어를 즐겨쓰는 여러가지 이유로 보건데, 이러한 추세가 쉽게 사그러들지는 않아 보인다. +다행히 근래의 언어 디자인과 컴파일러 기법의 발달은, 미뤄두었던 성능 문제를 해결함으로서 +프로토타이핑 작업에 요구되는 개별 환경의 생산성과, 성능이 중요한 애플리케이션의 구축에서 그 효용을 충분히 발휘한다. +줄리아 프로그래밍 언어는 다음과 같은 역할을 수행한다: 과학과 수학 분야 컴퓨팅에 적합한, 기존의 정적 타입 언어에 견줄만한 성능을 갖춘 유연한 동적 언어. -## Base +줄리아 컴파일러는 파이썬, R과 같은 언어의 해석 방식과 다르다. 줄리아가 뽑아내는 성능이 아마도 처음에는 의아할 것이다. +그럼에도 작성한 코드가 느리다면 [성능 팁](@ref man-performance-tips)을 읽어보길 권한다. +줄리아가 어떤 식으로 작동하는지 이해한 뒤라면, C에 근접하는 성능의 코드를 짜는 건 쉽다. - * [Essentials](@ref) - * [Collections and Data Structures](@ref) - * [Mathematics](@ref) - * [Numbers](@ref lib-numbers) - * [Strings](@ref lib-strings) - * [Arrays](@ref lib-arrays) - * [Tasks](@ref) - * [Distributed Computing](@ref) - * [Multi-Threading](@ref) - * [Shared Arrays](@ref) - * [Constants](@ref lib-constants) - * [Filesystem](@ref) - * [I/O and Network](@ref) - * [Punctuation](@ref) - * [Sorting and Related Functions](@ref) - * [Package Manager Functions](@ref) - * [Iteration utilities](@ref) - * [C Interface](@ref) - * [C Standard Library](@ref) - * [Dynamic Linker](@ref) - * [StackTraces](@ref) - * [SIMD Support](@ref) +줄리아는 타입 추론과 [LLVM](https://en.wikipedia.org/wiki/Low_Level_Virtual_Machine)으로 구현한 [적시 컴파일 (JIT)](https://en.wikipedia.org/wiki/Just-in-time_compilation)을 사용해 +선택적 타입, 멀티플 디스패치, 좋은 성능을 이뤄내고 있다. 그리고 명령형, 함수형, 객체 지향 프로그래밍의 특징을 포괄하는 다양한 패러다임을 추구한다. +줄리아는 고급 단계의 수치 계산에 있어 R, 매트랩, 파이썬처럼 간편하고 표현력이 우수하다. +뿐만 아니라 일반적인 형태의 프로그래밍 또한 가능하다. 이를 위해 줄리아는 수학 프로그래밍 언어를 근간으로 해서 구축하였고 +[리스프](https://en.wikipedia.org/wiki/Lisp_(programming_language)), [펄](https://en.wikipedia.org/wiki/Perl_(programming_language)), +[파이썬](https://en.wikipedia.org/wiki/Python_(programming_language)), [루아](https://en.wikipedia.org/wiki/Lua_(programming_language)), +[루비](https://en.wikipedia.org/wiki/Ruby_(programming_language))와 같은 인기있는 동적 언어의 기능을 취합하고 있다. -## Standard Library +기존에 있는 동적 언어와 비교해 보는 줄리아만의 독특한 점은: - * [The Julia REPL](@ref) - * [Base64](@ref) - * [CRC32c](@ref) - * [SHA](@ref) - * [Dates](@ref) - * [Delimited Files](@ref) - * [Distributed Computing](@ref) - * [File Events](@ref lib-filewatching) - * [Iterative Eigensolvers](@ref lib-itereigen) - * [Memory-mapped I/O](@ref) - * [Printf](@ref) - * [Profiling](@ref lib-profiling) - * [Random Numbers](@ref) - * [Shared Arrays](@ref) - * [Linear Algebra](@ref) - * [Logging](@ref) - * [Sparse Arrays](@ref) - * [Unicode](@ref) - * [Unit Testing](@ref) + * 핵심 언어는 최소한으로 꾸린다; 정수를 다루는 프리미티브 연산자(`+` `-` `*` 같은)를 포함하는, 줄리아 Base와 표준 라이브러리는 줄리아 코드로 짜여져 있다. + * 객체를 구성하고 서술하는 타입(types)을 풍부하게 지원하며, 타입 선언을 만들 때도 선택적으로 사용된다. + * 인자 타입을 조합함으로서 함수의 작동 행위를 정의하는 [멀티플 디스패치(multiple dispatch)](https://en.wikipedia.org/wiki/Multiple_dispatch) + * 인자 타입에 따라 효율적이고 특화된 코드를 자동으로 생성 + * C와 같은 정적으로 컴파일되는 언어에 근접하는 훌륭한 성능 -## Developer Documentation +동적 언어에 대해 "타입이 없다"는 식으로 말하곤 하는데 사실은 그렇지 않다: 프리미티브(숫자와 같은 기본 타입의)이거나 별도 정의를 통틀어 모든 객체는 타입을 가진다. +그러나 대부분의 동적 언어는 타입 선언의 부족으로 컴파일러가 해당 값의 타입을 인지하지 못한다거나 타입에 대해 무엇인지 명시적으로 밝힐 수 없는 상태가 되곤 한다. +한편 정적 언어는 타입 정보를 -- 대개 -- 컴파일러용으로서 달기에, 타입은 오직 컴파일 시점에만 존재하여 실행시에는 이를 다루거나 표현할 수 없다. +줄리아에서 타입은 그 자체로 런타임 객체이며 컴파일러가 요하는 정보를 알려주는 데에도 쓰인다. - * [Reflection and introspection](@ref) - * Documentation of Julia's Internals - * [Initialization of the Julia runtime](@ref) - * [Julia ASTs](@ref) - * [More about types](@ref) - * [Memory layout of Julia Objects](@ref) - * [Eval of Julia code](@ref) - * [Calling Conventions](@ref) - * [High-level Overview of the Native-Code Generation Process](@ref) - * [Julia Functions](@ref) - * [Base.Cartesian](@ref) - * [Talking to the compiler (the `:meta` mechanism)](@ref) - * [SubArrays](@ref) - * [System Image Building](@ref) - * [Working with LLVM](@ref) - * [printf() and stdio in the Julia runtime](@ref) - * [Bounds checking](@ref) - * [Proper maintenance and care of multi-threading locks](@ref) - * [Arrays with custom indices](@ref man-custom-indices) - * [Module loading](@ref) - * [Inference](@ref) - * Developing/debugging Julia's C code - * [Reporting and analyzing crashes (segfaults)](@ref) - * [gdb debugging tips](@ref) - * [Using Valgrind with Julia](@ref) - * [Sanitizer support](@ref) +보통의 프로그래머라면 개의치 않을 타입과 멀티플 디스패치는 줄리아의 핵심 개념이다: 함수들은 서로 다른 인자 타입들을 조합함으로서 정의되고 +가장 그 정의와 맞물리는 타입을 찾아 디스패치하여 실행된다. 이 모델은 수학 프로그래밍과 잘 맞는데, +전통적인 객체 지향 디스패치라면 첫번째 인자로 연산자를 "갖는" 것은 자연스럽지 않다. +연산자는 단지 특별히 표기한 함수일 뿐이다 -- `+` 함수에 엮일 새로운 데이터 타입을 정의하려면, 해당하는 메서드 정의만 추가하면 된다. +기존 코드는 새로운 데이터 타입과 더불어 원할하게 작동한다. + +런타임 타입 추론(타입 지정을 점진적으로 늘려가며)을 이유로, 또 이 프로젝트를 시작할 때 무엇보다도 성능을 강조하였기에 +줄리아의 계산 효율은 다른 동적 언어들에 비해 우월하며 심지어 정적으로 컴파일하는 경쟁 언어들마저 능가한다. +거대 규모의 수치 해석 문제에 있어 속도는 매번 그리고 앞으로도, 아마 항상 결정적 요소일 것이다: 처리되는 데이터의 양이 지난 수십년간 무어의 법칙을 따르고 있지 않은가. + +사용하기 편하면서도 강력하고 효율적인 언어를 줄리아는 목표하고 있다. 다른 시스템과 견주어 줄리아를 씀으로 좋은 점은 다음과 같다: + + * 자유롭게 사용 가능하며 오픈 소스이다 ([MIT 라이센스](https://github.com/JuliaLang/julia/blob/master/LICENSE.md)) + * 사용자가 정의한 타입 또한 내장한 타입처럼 빠르고 간결하다 + * 성능을 위해 코드를 벡터화할 필요가 없다; 벡터화하지 않은 코드도 빠르다 + * 병렬과 분산 처리를 위해 고안되었다 + * 가벼운 "그린" 쓰레딩 ([코루틴](https://en.wikipedia.org/wiki/Coroutine)) + * 거슬리지 않는 강력한 타입 시스템 + * 숫자와 다른 타입을 위한 우아하고 확장 가능한 컨버젼 및 프로모션(타입 변환) + * 효율적인 [유니코드](https://en.wikipedia.org/wiki/Unicode) 와 [UTF-8](https://en.wikipedia.org/wiki/UTF-8) 지원 + * C 함수 직접 호출(별도의 래퍼나 특정한 API가 필요하지 않음) + * 다른 프로세스를 관리하는 쉘과 비슷한 강력한 기능 + * 리스프와 비슷한 매크로, 메타프로그래밍을 위한 장치들 diff --git a/src/manual/introduction.md b/src/manual/introduction.md deleted file mode 100644 index a8f20d4..0000000 --- a/src/manual/introduction.md +++ /dev/null @@ -1,56 +0,0 @@ -# [소개글](@id man-introduction) - -과학 분야 컴퓨팅은 전통적으로 최고의 성능을 요구하지만, 당사자인 전문 연구자들은 속도가 느리더라도 동적인 언어로서 그들의 업무를 처리한다. -동적 언어를 즐겨쓰는 여러가지 이유로 보건데, 이러한 추세가 쉽게 사그러들지는 않아 보인다. -다행히 근래의 언어 디자인과 컴파일러 기법의 발달은, 미뤄두었던 성능 문제를 해결함으로서 -프로토타이핑 작업에 요구되는 개별 환경의 생산성과, 성능이 중요한 애플리케이션의 구축에서 그 효용을 충분히 발휘한다. -줄리아 프로그래밍 언어는 다음과 같은 역할을 수행한다: 과학과 수학 분야 컴퓨팅에 적합한, 기존의 정적 타입 언어에 견줄만한 성능을 갖춘 유연한 동적 언어. - -줄리아 컴파일러는 파이썬, R과 같은 언어의 해석 방식과 다르다. 줄리아가 뽑아내는 성능이 아마도 처음에는 의아할 것이다. -그럼에도 작성한 코드가 느리다면 [성능 팁](@ref man-performance-tips)을 읽어보길 권한다. -줄리아가 어떤 식으로 작동하는지 이해한 뒤라면, C에 근접하는 성능의 코드를 짜는 건 쉽다. - -줄리아는 타입 추론과 [LLVM](https://en.wikipedia.org/wiki/Low_Level_Virtual_Machine)으로 구현한 [적시 컴파일 (JIT)](https://en.wikipedia.org/wiki/Just-in-time_compilation)을 사용해 -선택적 타입, 멀티플 디스패치, 좋은 성능을 이뤄내고 있다. 그리고 명령형, 함수형, 객체 지향 프로그래밍의 특징을 포괄하는 다양한 패러다임을 추구한다. -줄리아는 고급 단계의 수치 계산에 있어 R, 매트랩, 파이썬처럼 간편하고 표현력이 우수하다. -뿐만 아니라 일반적인 형태의 프로그래밍 또한 가능하다. 이를 위해 줄리아는 수학 프로그래밍 언어를 근간으로 해서 구축하였고 -[리스프](https://en.wikipedia.org/wiki/Lisp_(programming_language)), [펄](https://en.wikipedia.org/wiki/Perl_(programming_language)), -[파이썬](https://en.wikipedia.org/wiki/Python_(programming_language)), [루아](https://en.wikipedia.org/wiki/Lua_(programming_language)), -[루비](https://en.wikipedia.org/wiki/Ruby_(programming_language))와 같은 인기있는 동적 언어의 기능을 취합하고 있다. - -기존에 있는 동적 언어와 비교해 보는 줄리아만의 독특한 점은: - - * 핵심 언어는 최소한으로 꾸린다; 정수를 다루는 프리미티브 연산자(`+` `-` `*` 같은)를 포함하는, 줄리아 Base와 표준 라이브러리는 줄리아 코드로 짜여져 있다. - * 객체를 구성하고 서술하는 타입(types)을 풍부하게 지원하며, 타입 선언을 만들 때도 선택적으로 사용된다. - * 인자 타입을 조합함으로서 함수의 작동 행위를 정의하는 [멀티플 디스패치(multiple dispatch)](https://en.wikipedia.org/wiki/Multiple_dispatch) - * 인자 타입에 따라 효율적이고 특화된 코드를 자동으로 생성 - * C와 같은 정적으로 컴파일되는 언어에 근접하는 훌륭한 성능 - -동적 언어에 대해 "타입이 없다"는 식으로 말하곤 하는데 사실은 그렇지 않다: 프리미티브(숫자와 같은 기본 타입의)이거나 별도 정의를 통틀어 모든 객체는 타입을 가진다. -그러나 대부분의 동적 언어는 타입 선언의 부족으로 컴파일러가 해당 값의 타입을 인지하지 못한다거나 타입에 대해 무엇인지 명시적으로 밝힐 수 없는 상태가 되곤 한다. -한편 정적 언어는 타입 정보를 -- 대개 -- 컴파일러용으로서 달기에, 타입은 오직 컴파일 시점에만 존재하여 실행시에는 이를 다루거나 표현할 수 없다. -줄리아에서 타입은 그 자체로 런타임 객체이며 컴파일러가 요하는 정보를 알려주는 데에도 쓰인다. - -보통의 프로그래머라면 개의치 않을 타입과 멀티플 디스패치는 줄리아의 핵심 개념이다: 함수들은 서로 다른 인자 타입들을 조합함으로서 정의되고 -가장 그 정의와 맞물리는 타입을 찾아 디스패치하여 실행된다. 이 모델은 수학 프로그래밍과 잘 맞는데, -전통적인 객체 지향 디스패치라면 첫번째 인자로 연산자를 "갖는" 것은 자연스럽지 않다. -연산자는 단지 특별히 표기한 함수일 뿐이다 -- `+` 함수에 엮일 새로운 데이터 타입을 정의하려면, 해당하는 메서드 정의만 추가하면 된다. -기존 코드는 새로운 데이터 타입과 더불어 원할하게 작동한다. - -런타임 타입 추론(타입 지정을 점진적으로 늘려가며)을 이유로, 또 이 프로젝트를 시작할 때 무엇보다도 성능을 강조하였기에 -줄리아의 계산 효율은 다른 동적 언어들에 비해 우월하며 심지어 정적으로 컴파일하는 경쟁 언어들마저 능가한다. -거대 규모의 수치 해석 문제에 있어 속도는 매번 그리고 앞으로도, 아마 항상 결정적 요소일 것이다: 처리되는 데이터의 양이 지난 수십년간 무어의 법칙을 따르고 있지 않은가. - -사용하기 편하면서도 강력하고 효율적인 언어를 줄리아는 목표하고 있다. 다른 시스템과 견주어 줄리아를 씀으로 좋은 점은 다음과 같다: - - * 자유롭게 사용 가능하며 오픈 소스이다 ([MIT 라이센스](https://github.com/JuliaLang/julia/blob/master/LICENSE.md)) - * 사용자가 정의한 타입 또한 내장한 타입처럼 빠르고 간결하다 - * 성능을 위해 코드를 벡터화할 필요가 없다; 벡터화하지 않은 코드도 빠르다 - * 병렬과 분산 처리를 위해 고안되었다 - * 가벼운 "그린" 쓰레딩 ([코루틴](https://en.wikipedia.org/wiki/Coroutine)) - * 거슬리지 않는 강력한 타입 시스템 - * 숫자와 다른 타입을 위한 우아하고 확장 가능한 컨버젼 및 프로모션(타입 변환) - * 효율적인 [유니코드](https://en.wikipedia.org/wiki/Unicode) 와 [UTF-8](https://en.wikipedia.org/wiki/UTF-8) 지원 - * C 함수 직접 호출(별도의 래퍼나 특정한 API가 필요하지 않음) - * 다른 프로세스를 관리하는 쉘과 비슷한 강력한 기능 - * 리스프와 비슷한 매크로, 메타프로그래밍을 위한 장치들 diff --git a/src/manual/modules.md b/src/manual/modules.md index bf1a7ad..a12f873 100644 --- a/src/manual/modules.md +++ b/src/manual/modules.md @@ -145,7 +145,6 @@ baremodule Mod using Base eval(x) = Core.eval(Mod, x) -eval(m,x) = Core.eval(m, x) include(p) = Base.include(Mod, p) ... From 9cb51cb0e91e226cebfe355811d6e1d515efc12d Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Thu, 24 May 2018 02:44:07 +0900 Subject: [PATCH 027/153] update Julia Commit 08fae678fe --- codex/NEWS.md | 16 +++++++++++++++- codex/base/parallel.md | 1 - codex/manual/arrays.md | 10 +++++----- codex/manual/control-flow.md | 4 ++-- codex/manual/interfaces.md | 19 +++++++++++-------- codex/manual/parallel-computing.md | 8 ++++---- src/NEWS.md | 17 ++++++++++++++++- src/base/parallel.md | 1 - src/manual/arrays.md | 10 +++++----- src/manual/control-flow.md | 2 +- src/manual/interfaces.md | 19 +++++++++++-------- src/manual/parallel-computing.md | 8 ++++---- 12 files changed, 74 insertions(+), 41 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index f6b1ae0..fd72618 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -472,6 +472,18 @@ This section lists changes that do not have deprecation warnings. * `mv`,`cp`, `touch`, `mkdir`, `mkpath` now return the path that was created/modified rather than `nothing` ([#27071](https://github.com/JuliaLang/julia/issues/27071)). + * Regular expressions now default to UCP mode. Escape sequences such as `\w` + will now match based on unicode character properties, e.g. `r"\w+"` will + match `café` (not just `caf`). Add the `a` modifier (e.g. `r"\w+"a`) to + restore the previous behavior ([#27189](https://github.com/JuliaLang/julia/issues/27189)). + + * `@sync` now waits only for *lexically* enclosed (i.e. visible directly in the source + text of its argument) `@async` expressions. If you need to wait for a task created by + a called function `f`, have `f` return the task and put `@async wait(f(...))` within + the `@sync` block. + This change makes `@schedule` redundant with `@async`, so `@schedule` has been + deprecated ([#27164](https://github.com/JuliaLang/julia/issues/27164)). + Library improvements -------------------- @@ -655,6 +667,8 @@ Library improvements * `trunc`, `floor`, `ceil`, and `round` specify `digits`, `sigdigits` and `base` using keyword arguments. ([#26156](https://github.com/JuliaLang/julia/issues/26156), [#26670](https://github.com/JuliaLang/julia/issues/26670)) + * `Sys.which()` provides a cross-platform method to find executable files, similar to + the Unix `which` command. ([#26559](https://github.com/JuliaLang/julia/issues/26559)) Compiler/Runtime improvements ----------------------------- @@ -690,7 +704,7 @@ Deprecated or removed `dims` keyword argument. This includes the functions `sum`, `prod`, `maximum`, `minimum`, `all`, `any`, `findmax`, `findmin`, `mean`, `varm`, `std`, `var`, `cov`, `cor`, `median`, `mapreducedim`, `reducedim`, `sort`, `accumulate`, `accumulate!`, - `cumsum`, `cumsum!`, `cumprod`, `cumprod!`, `flipdim`, and `squeeze` ([#25501](https://github.com/JuliaLang/julia/issues/25501)). + `cumsum`, `cumsum!`, `cumprod`, `cumprod!`, `flipdim`, `squeeze`, and `cat` ([#25501](https://github.com/JuliaLang/julia/issues/25501), [#26660](https://github.com/JuliaLang/julia/issues/26660), [#27100](https://github.com/JuliaLang/julia/issues/27100)). * `indices(a)` and `indices(a,d)` have been deprecated in favor of `axes(a)` and `axes(a, d)` ([#25057](https://github.com/JuliaLang/julia/issues/25057)). diff --git a/codex/base/parallel.md b/codex/base/parallel.md index 8f850dd..cd689e1 100644 --- a/codex/base/parallel.md +++ b/codex/base/parallel.md @@ -13,7 +13,6 @@ Base.task_local_storage(::Function, ::Any, ::Any) Base.Condition Base.notify Base.schedule -Base.@schedule Base.@task Base.sleep Base.Channel diff --git a/codex/manual/arrays.md b/codex/manual/arrays.md index c778d8e..994fc5f 100644 --- a/codex/manual/arrays.md +++ b/codex/manual/arrays.md @@ -83,11 +83,11 @@ converted to that type using [`convert`](@ref). Arrays can be constructed and also concatenated using the following functions: -| Function | Description | -|:---------------------- |:---------------------------------------------------- | -| [`cat(k, A...)`](@ref) | concatenate input n-d arrays along the dimension `k` | -| [`vcat(A...)`](@ref) | shorthand for `cat(1, A...)` | -| [`hcat(A...)`](@ref) | shorthand for `cat(2, A...)` | +| Function | Description | +|:--------------------------- |:----------------------------------------------- | +| [`cat(A...; dims=k)`](@ref) | concatenate input arrays along dimension(s) `k` | +| [`vcat(A...)`](@ref) | shorthand for `cat(A...; dims=1)` | +| [`hcat(A...)`](@ref) | shorthand for `cat(A...; dims=2)` | Scalar values passed to these functions are treated as 1-element arrays. diff --git a/codex/manual/control-flow.md b/codex/manual/control-flow.md index 1da1ecd..47cb4a9 100644 --- a/codex/manual/control-flow.md +++ b/codex/manual/control-flow.md @@ -980,8 +980,8 @@ A task created explicitly by calling [`Task`](@ref) is initially not known to th allows you to manage tasks manually using [`yieldto`](@ref) if you wish. However, when such a task waits for an event, it still gets restarted automatically when the event happens, as you would expect. It is also possible to make the scheduler run a task whenever it can, without necessarily -waiting for any events. This is done by calling [`schedule`](@ref), or using the [`@schedule`](@ref) -or [`@async`](@ref) macros (see [Parallel Computing](@ref) for more details). +waiting for any events. This is done by calling [`schedule`](@ref), or using the [`@async`](@ref) +macro (see [Parallel Computing](@ref) for more details). ### Task states diff --git a/codex/manual/interfaces.md b/codex/manual/interfaces.md index 9441ae1..8d4810f 100644 --- a/codex/manual/interfaces.md +++ b/codex/manual/interfaces.md @@ -66,9 +66,6 @@ julia> struct Squares julia> Base.iterate(S::Squares, state=1) = state > S.count ? nothing : (state*state, state+1) -julia> Base.eltype(::Type{Squares}) = Int # Note that this is defined for the type - -julia> Base.length(S::Squares) = S.count ``` With only [`iterate`](@ref) definition, the `Squares` type is already pretty powerful. @@ -104,7 +101,13 @@ There are a few more methods we can extend to give Julia more information about collection. We know that the elements in a `Squares` sequence will always be `Int`. By extending 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`](@ref), too. +we can extend [`length`](@ref), too: + +```jldoctest squaretype +julia> Base.eltype(::Type{Squares}) = Int # Note that this is defined for the type + +julia> Base.length(S::Squares) = S.count +``` 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}`: @@ -525,7 +528,7 @@ list can — and often does — include other nested `Broadcasted` wrappers. For a complete example, let's say you have created a type, `ArrayAndChar`, that stores an array and a single character: -```jldoctest ArrayAndChar +```jldoctest ArrayAndChar; output = false struct ArrayAndChar{T,N} <: AbstractArray{T,N} data::Array{T,N} char::Char @@ -540,14 +543,14 @@ Base.showarg(io::IO, A::ArrayAndChar, toplevel) = print(io, typeof(A), " with ch You might want broadcasting to preserve the `char` "metadata." First we define -```jldoctest ArrayAndChar +```jldoctest ArrayAndChar; output = false Base.BroadcastStyle(::Type{<:ArrayAndChar}) = Broadcast.ArrayStyle{ArrayAndChar}() # output ``` This means we must also define a corresponding `similar` method: -```jldoctest ArrayAndChar; filter = r"(^find_aac \(generic function with 5 methods\)$|^$)" +```jldoctest ArrayAndChar; output = false function Base.similar(bc::Broadcast.Broadcasted{Broadcast.ArrayStyle{ArrayAndChar}}, ::Type{ElType}) where ElType # Scan the inputs for the ArrayAndChar: A = find_aac(bc) @@ -562,7 +565,7 @@ find_aac(x) = x find_aac(a::ArrayAndChar, rest) = a find_aac(::Any, rest) = find_aac(rest) # output - +find_aac (generic function with 5 methods) ``` From these definitions, one obtains the following behavior: diff --git a/codex/manual/parallel-computing.md b/codex/manual/parallel-computing.md index 76bb41a..82cb498 100644 --- a/codex/manual/parallel-computing.md +++ b/codex/manual/parallel-computing.md @@ -565,7 +565,7 @@ A channel can be visualized as a pipe, i.e., it has a write end and read end. # we can schedule `n` instances of `foo` to be active concurrently. for _ in 1:n - @schedule foo() + @async foo() end ``` * Channels are created via the `Channel{T}(sz)` constructor. The channel will only hold objects @@ -672,10 +672,10 @@ julia> function make_jobs(n) julia> n = 12; -julia> @schedule make_jobs(n); # feed the jobs channel with "n" jobs +julia> @async make_jobs(n); # feed the jobs channel with "n" jobs julia> for i in 1:4 # start 4 tasks to process requests in parallel - @schedule do_work() + @async do_work() end julia> @elapsed while n > 0 # print out results @@ -780,7 +780,7 @@ julia> function make_jobs(n) julia> n = 12; -julia> @schedule make_jobs(n); # feed the jobs channel with "n" jobs +julia> @async make_jobs(n); # feed the jobs channel with "n" jobs julia> for p in workers() # start tasks on the workers to process requests in parallel remote_do(do_work, p, jobs, results) diff --git a/src/NEWS.md b/src/NEWS.md index 08f0b01..bf48697 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -460,6 +460,18 @@ This section lists changes that do not have deprecation warnings. * `mv`,`cp`, `touch`, `mkdir`, `mkpath` now return the path that was created/modified rather than `nothing` ([#27071](https://github.com/JuliaLang/julia/issues/27071)). + * Regular expressions now default to UCP mode. Escape sequences such as `\w` + will now match based on unicode character properties, e.g. `r"\w+"` will + match `café` (not just `caf`). Add the `a` modifier (e.g. `r"\w+"a`) to + restore the previous behavior ([#27189](https://github.com/JuliaLang/julia/issues/27189)). + + * `@sync` now waits only for *lexically* enclosed (i.e. visible directly in the source + text of its argument) `@async` expressions. If you need to wait for a task created by + a called function `f`, have `f` return the task and put `@async wait(f(...))` within + the `@sync` block. + This change makes `@schedule` redundant with `@async`, so `@schedule` has been + deprecated ([#27164](https://github.com/JuliaLang/julia/issues/27164)). + Library improvements -------------------- @@ -643,6 +655,9 @@ Library improvements * `trunc`, `floor`, `ceil`, and `round` specify `digits`, `sigdigits` and `base` using keyword arguments. ([#26156](https://github.com/JuliaLang/julia/issues/26156), [#26670](https://github.com/JuliaLang/julia/issues/26670)) + * `Sys.which()` provides a cross-platform method to find executable files, similar to + the Unix `which` command. ([#26559](https://github.com/JuliaLang/julia/issues/26559)) + Compiler/Runtime improvements ----------------------------- @@ -677,7 +692,7 @@ Deprecated or removed `dims` keyword argument. This includes the functions `sum`, `prod`, `maximum`, `minimum`, `all`, `any`, `findmax`, `findmin`, `mean`, `varm`, `std`, `var`, `cov`, `cor`, `median`, `mapreducedim`, `reducedim`, `sort`, `accumulate`, `accumulate!`, - `cumsum`, `cumsum!`, `cumprod`, `cumprod!`, `flipdim`, and `squeeze` ([#25501](https://github.com/JuliaLang/julia/issues/25501)). + `cumsum`, `cumsum!`, `cumprod`, `cumprod!`, `flipdim`, `squeeze`, and `cat` ([#25501](https://github.com/JuliaLang/julia/issues/25501), [#26660](https://github.com/JuliaLang/julia/issues/26660), [#27100](https://github.com/JuliaLang/julia/issues/27100)). * `indices(a)` and `indices(a,d)` have been deprecated in favor of `axes(a)` and `axes(a, d)` ([#25057](https://github.com/JuliaLang/julia/issues/25057)). diff --git a/src/base/parallel.md b/src/base/parallel.md index 8f850dd..cd689e1 100644 --- a/src/base/parallel.md +++ b/src/base/parallel.md @@ -13,7 +13,6 @@ Base.task_local_storage(::Function, ::Any, ::Any) Base.Condition Base.notify Base.schedule -Base.@schedule Base.@task Base.sleep Base.Channel diff --git a/src/manual/arrays.md b/src/manual/arrays.md index fea5a6a..573dbdf 100644 --- a/src/manual/arrays.md +++ b/src/manual/arrays.md @@ -77,11 +77,11 @@ copy. 배열은 다음의 함수를 사용하여 생성하고 병합할 수 있다. -| 함수 | 설명 | -|:---------------------- |:------------------------------------- | -| [`cat(k, A...)`](@ref) | n차원 입력 배열을 `k`차원을 따라 병합 | -| [`vcat(A...)`](@ref) | `cat(1, A...)`의 줄임 | -| [`hcat(A...)`](@ref) | `cat(2, A...)`의 줄임 | +| 함수 | 설명 | +|:--------------------------- |:-------------------------------- | +| [`cat(A...; dims=k)`](@ref) | 입력 배열을 `k` 차원에 따라 병합 | +| [`vcat(A...)`](@ref) | `cat(A...; dims=1)`의 줄임 | +| [`hcat(A...)`](@ref) | `cat(A...; dims=2)`의 줄임 | 스칼라 값이 인수로 전달되면 원소 갯수가 하나인 배열로 취급한다. diff --git a/src/manual/control-flow.md b/src/manual/control-flow.md index 7a4b75a..4851a99 100644 --- a/src/manual/control-flow.md +++ b/src/manual/control-flow.md @@ -817,7 +817,7 @@ taskHdl = @task mytask(7) 이 모든 경우에, `wait`는 태스크를 대기열에 넣고 재시작하는 `Condition` 객체에서 궁극적으로 작동합니다. 태스크가 `Condition`에서 `wait`를 호출하면, 태스크는 실행 불가능한 것으로 표시되고, 조건 대기열에 추가되며 스케줄러로 전환됩니다. 스케줄러는 실행할 다른 태스크를 선택하거나 외부 이벤트 대기를 차단합니다. 모든 것이 잘되면 결국 이벤트 처리기가 조건에서 `notify`를 호출하여 해당 조건을 기다리는 작업을 다시 실행 가능하게 만듭니다. -태스크를 호출하여 명시적으로 생성된 태스크는 처음에는 스케줄러에게 알려지지 않습니다. 원한다면 `yieldto`를 사용하여 수동으로 작업을 관리할 수도 있습니다. 하지만 그런 태스크가 이벤트를 기다리면 예상대로 이벤트가 발생할 때 자동적으로 재시작됩니다. 이벤트를 기다리지 않고 언제든지 스케줄러가 작업을 실행할 수 있게 하는 것도 가능합니다. 이 방법은 `schedule`을 호출하거나, `schedule` 또는 `@async` 매크로(자세한 사항은 Parallel Computing 참조)를 사용하여 수행할 수 있습니다. +태스크를 호출하여 명시적으로 생성된 태스크는 처음에는 스케줄러에게 알려지지 않습니다. 원한다면 `yieldto`를 사용하여 수동으로 작업을 관리할 수도 있습니다. 하지만 그런 태스크가 이벤트를 기다리면 예상대로 이벤트가 발생할 때 자동적으로 재시작됩니다. 이벤트를 기다리지 않고 언제든지 스케줄러가 작업을 실행할 수 있게 하는 것도 가능합니다. 이 방법은 [`schedule`](@ref)을 호출하거나, [`@async`](@ref) 매크로를 사용하여 수행할 수 있습니다 (자세한 사항은 [Parallel Computing](@ref) 참조). ### 태스크 상태 diff --git a/src/manual/interfaces.md b/src/manual/interfaces.md index 9441ae1..8d4810f 100644 --- a/src/manual/interfaces.md +++ b/src/manual/interfaces.md @@ -66,9 +66,6 @@ julia> struct Squares julia> Base.iterate(S::Squares, state=1) = state > S.count ? nothing : (state*state, state+1) -julia> Base.eltype(::Type{Squares}) = Int # Note that this is defined for the type - -julia> Base.length(S::Squares) = S.count ``` With only [`iterate`](@ref) definition, the `Squares` type is already pretty powerful. @@ -104,7 +101,13 @@ There are a few more methods we can extend to give Julia more information about collection. We know that the elements in a `Squares` sequence will always be `Int`. By extending 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`](@ref), too. +we can extend [`length`](@ref), too: + +```jldoctest squaretype +julia> Base.eltype(::Type{Squares}) = Int # Note that this is defined for the type + +julia> Base.length(S::Squares) = S.count +``` 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}`: @@ -525,7 +528,7 @@ list can — and often does — include other nested `Broadcasted` wrappers. For a complete example, let's say you have created a type, `ArrayAndChar`, that stores an array and a single character: -```jldoctest ArrayAndChar +```jldoctest ArrayAndChar; output = false struct ArrayAndChar{T,N} <: AbstractArray{T,N} data::Array{T,N} char::Char @@ -540,14 +543,14 @@ Base.showarg(io::IO, A::ArrayAndChar, toplevel) = print(io, typeof(A), " with ch You might want broadcasting to preserve the `char` "metadata." First we define -```jldoctest ArrayAndChar +```jldoctest ArrayAndChar; output = false Base.BroadcastStyle(::Type{<:ArrayAndChar}) = Broadcast.ArrayStyle{ArrayAndChar}() # output ``` This means we must also define a corresponding `similar` method: -```jldoctest ArrayAndChar; filter = r"(^find_aac \(generic function with 5 methods\)$|^$)" +```jldoctest ArrayAndChar; output = false function Base.similar(bc::Broadcast.Broadcasted{Broadcast.ArrayStyle{ArrayAndChar}}, ::Type{ElType}) where ElType # Scan the inputs for the ArrayAndChar: A = find_aac(bc) @@ -562,7 +565,7 @@ find_aac(x) = x find_aac(a::ArrayAndChar, rest) = a find_aac(::Any, rest) = find_aac(rest) # output - +find_aac (generic function with 5 methods) ``` From these definitions, one obtains the following behavior: diff --git a/src/manual/parallel-computing.md b/src/manual/parallel-computing.md index 76bb41a..82cb498 100644 --- a/src/manual/parallel-computing.md +++ b/src/manual/parallel-computing.md @@ -565,7 +565,7 @@ A channel can be visualized as a pipe, i.e., it has a write end and read end. # we can schedule `n` instances of `foo` to be active concurrently. for _ in 1:n - @schedule foo() + @async foo() end ``` * Channels are created via the `Channel{T}(sz)` constructor. The channel will only hold objects @@ -672,10 +672,10 @@ julia> function make_jobs(n) julia> n = 12; -julia> @schedule make_jobs(n); # feed the jobs channel with "n" jobs +julia> @async make_jobs(n); # feed the jobs channel with "n" jobs julia> for i in 1:4 # start 4 tasks to process requests in parallel - @schedule do_work() + @async do_work() end julia> @elapsed while n > 0 # print out results @@ -780,7 +780,7 @@ julia> function make_jobs(n) julia> n = 12; -julia> @schedule make_jobs(n); # feed the jobs channel with "n" jobs +julia> @async make_jobs(n); # feed the jobs channel with "n" jobs julia> for p in workers() # start tasks on the workers to process requests in parallel remote_do(do_work, p, jobs, results) From 0bcab3f8afae51ed70354decf3b3f1720f31d796 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Fri, 25 May 2018 21:40:50 +0900 Subject: [PATCH 028/153] update Julia Commit 1c74819db1 --- codex/NEWS.md | 43 + codex/devdocs/functions.md | 6 +- codex/manual/arrays.md | 48 +- codex/manual/calling-c-and-fortran-code.md | 2 +- codex/manual/code-loading.md | 2 +- codex/manual/environment-variables.md | 34 +- codex/manual/index.md | 2 - codex/manual/modules.md | 4 +- codex/manual/packages.md | 1118 -------------------- codex/manual/parallel-computing.md | 4 +- codex/manual/performance-tips.md | 4 +- codex/stdlib/LinearAlgebra.md | 37 +- codex/stdlib/Pkg.md | 447 +++++++- codex/stdlib/Pkg3.md | 418 -------- codex/stdlib/REPL.md | 6 +- codex/stdlib/linearalgebra.md | 37 +- make.jl | 1 - src/NEWS.md | 43 + src/devdocs/functions.md | 6 +- src/manual/arrays.md | 48 +- src/manual/calling-c-and-fortran-code.md | 2 +- src/manual/code-loading.md | 2 +- src/manual/environment-variables.md | 34 +- src/manual/index.md | 2 - src/manual/modules.md | 4 +- src/manual/packages.md | 1118 -------------------- src/manual/parallel-computing.md | 4 +- src/manual/performance-tips.md | 4 +- src/stdlib/LinearAlgebra.md | 37 +- src/stdlib/Pkg.md | 447 +++++++- src/stdlib/Pkg3.md | 418 -------- src/stdlib/REPL.md | 6 +- src/stdlib/linearalgebra.md | 37 +- 33 files changed, 1048 insertions(+), 3377 deletions(-) delete mode 100644 codex/manual/packages.md delete mode 100644 codex/stdlib/Pkg3.md delete mode 100644 src/manual/packages.md delete mode 100644 src/stdlib/Pkg3.md diff --git a/codex/NEWS.md b/codex/NEWS.md index fd72618..5bb85ee 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -219,6 +219,9 @@ Breaking changes This section lists changes that do not have deprecation warnings. + * The package manager `Pkg` has been replaced with a new one. See the manual entries on + "Code Loading" and "Pkg" for documentation. + * `replace(s::AbstractString, pat=>repl)` for function `repl` arguments formerly passed a substring to `repl` in all cases. It now passes substrings for string patterns `pat`, but a `Char` for character patterns (when `pat` is a @@ -227,6 +230,21 @@ This section lists changes that do not have deprecation warnings. * `readuntil` now does *not* include the delimiter in its result, matching the behavior of `readline`. Pass `keep=true` to get the old behavior ([#25633](https://github.com/JuliaLang/julia/issues/25633)). + * `lu` methods now return decomposition objects such as `LU` rather than + tuples of arrays or tuples of numbers ([#26997](https://github.com/JuliaLang/julia/issues/26997), [#27159](https://github.com/JuliaLang/julia/issues/27159), [#27212](https://github.com/JuliaLang/julia/issues/27212)). + + * `schur` methods now return decomposition objects such as `Schur` and + `GeneralizedSchur` rather than tuples of arrays ([#26997](https://github.com/JuliaLang/julia/issues/26997), [#27159](https://github.com/JuliaLang/julia/issues/27159), [#27212](https://github.com/JuliaLang/julia/issues/27212)). + + * `lq` methods now return decomposition objects such as `LQ` + rather than tuples of arrays ([#26997](https://github.com/JuliaLang/julia/issues/26997), [#27159](https://github.com/JuliaLang/julia/issues/27159), [#27212](https://github.com/JuliaLang/julia/issues/27212)). + + * `qr` methods now return decomposition objects such as `QR`, `QRPivoted`, + and `QRCompactWY` rather than tuples of arrays ([#26997](https://github.com/JuliaLang/julia/issues/26997), [#27159](https://github.com/JuliaLang/julia/issues/27159), [#27212](https://github.com/JuliaLang/julia/issues/27212)). + + * `svd` methods now return decomposition objects such as `SVD` and + `GeneralizedSVD` rather than tuples of arrays or tuples of numbers ([#26997](https://github.com/JuliaLang/julia/issues/26997), [#27159](https://github.com/JuliaLang/julia/issues/27159), [#27212](https://github.com/JuliaLang/julia/issues/27212)). + * `countlines` now always counts the last non-empty line even if it does not end with EOL, matching the behavior of `eachline` and `readlines` ([#25845](https://github.com/JuliaLang/julia/issues/25845)). @@ -695,6 +713,31 @@ Deprecated or removed * The keyword `immutable` is fully deprecated to `struct`, and `type` is fully deprecated to `mutable struct` ([#19157](https://github.com/JuliaLang/julia/issues/19157), [#20418](https://github.com/JuliaLang/julia/issues/20418)). + * `lufact`, `schurfact`, `lqfact`, `qrfact`, `ldltfact`, `svdfact`, + `bkfact`, `hessfact`, `eigfact`, and `cholfact` have respectively been + deprecated to `lu`, `schur`, `lq`, `qr`, `ldlt`, `svd`, `bunchkaufman`, + `hessenberg`, `eigen`, and `cholesky` ([#26997](https://github.com/JuliaLang/julia/issues/26997), [#27159](https://github.com/JuliaLang/julia/issues/27159), [#27212](https://github.com/JuliaLang/julia/issues/27212)). + + * `lufact!`, `schurfact!`, `lqfact!`, `qrfact!`, `ldltfact!`, `svdfact!`, + `bkfact!`, `hessfact!`, and `eigfact!` have respectively been deprecated to + `lu!`, `schur!`, `lq!`, `qr!`, `ldlt!`, `svd!`, `bunchkaufman!`, + `hessenberg!`, and `eigen!` ([#26997](https://github.com/JuliaLang/julia/issues/26997), [#27159](https://github.com/JuliaLang/julia/issues/27159), [#27212](https://github.com/JuliaLang/julia/issues/27212)). + + * `eig(A[, args...])` has been deprecated in favor of `eigen(A[, args...])`. + Whereas the former returns a tuple of arrays, the latter returns an `Eigen` object. + So for a direct replacement, use `(eigen(A[, args...])...,)`. But going forward, + consider using the direct result of `eigen(A[, args...])` instead, either + destructured into its components (`vals, vecs = eigen(A[, args...])`) or + as an `Eigen` object (`X = eigen(A[, args...])`) ([#26997](https://github.com/JuliaLang/julia/issues/26997), [#27159](https://github.com/JuliaLang/julia/issues/27159), [#27212](https://github.com/JuliaLang/julia/issues/27212)). + + * `eig(A::AbstractMatrix, B::AbstractMatrix)` and `eig(A::Number, B::Number)` + have been deprecated in favor of `eigen(A, B)`. Whereas the former each return + a tuple of arrays, the latter returns a `GeneralizedEigen` object. So for a direct + replacement, use `(eigen(A, B)...,)`. But going forward, consider using the + direct result of `eigen(A, B)` instead, either destructured into its components + (`vals, vecs = eigen(A, B)`), or as a `GeneralizedEigen` object + (`X = eigen(A, B)`) ([#26997](https://github.com/JuliaLang/julia/issues/26997), [#27159](https://github.com/JuliaLang/julia/issues/27159), [#27212](https://github.com/JuliaLang/julia/issues/27212)). + * Indexing into multidimensional arrays with more than one index but fewer indices than there are dimensions is no longer permitted when those trailing dimensions have lengths greater than 1. Instead, reshape the array or add trailing indices so the dimensionality and number of indices diff --git a/codex/devdocs/functions.md b/codex/devdocs/functions.md index 294b0fb..d20db2f 100644 --- a/codex/devdocs/functions.md +++ b/codex/devdocs/functions.md @@ -135,7 +135,7 @@ or "keyword sorter", or "kwsorter", and is stored in the `kwsorter` field of `Me Every definition in the kwsorter function has the same arguments as some definition in the normal method table, except with a single `Array` argument prepended. This array contains alternating symbols and values that represent the passed keyword arguments. The kwsorter's job is to move -keyword arguments into their canonical positions based on name, plus evaluate and substite any +keyword arguments into their canonical positions based on name, plus evaluate and substitute any needed default value expressions. The result is a normal positional argument list, which is then passed to yet another function. @@ -248,6 +248,6 @@ constructor generation), and using `new` directly to create closure instances. N thing ever, but you do what you gotta do. The next problem was the `@test` macro, which generated a 0-argument closure for each test case. -This is not really necessary, since each test case is simply run once in place. Therefore I modified -`@test` to expand to a try-catch block that records the test result (true, false, or exception +This is not really necessary, since each test case is simply run once in place. Therefore, `@test` +was modified to expand to a try-catch block that records the test result (true, false, or exception raised) and calls the test suite handler on it. diff --git a/codex/manual/arrays.md b/codex/manual/arrays.md index 994fc5f..521d160 100644 --- a/codex/manual/arrays.md +++ b/codex/manual/arrays.md @@ -746,37 +746,37 @@ creating any temporaries, and by calling the appropriate LAPACK function with th dimension size and stride parameters. ```julia-repl -julia> a = rand(10,10) +julia> a = rand(10, 10) 10×10 Array{Float64,2}: - 0.561255 0.226678 0.203391 0.308912 … 0.750307 0.235023 0.217964 - 0.718915 0.537192 0.556946 0.996234 0.666232 0.509423 0.660788 - 0.493501 0.0565622 0.118392 0.493498 0.262048 0.940693 0.252965 - 0.0470779 0.736979 0.264822 0.228787 0.161441 0.897023 0.567641 - 0.343935 0.32327 0.795673 0.452242 0.468819 0.628507 0.511528 - 0.935597 0.991511 0.571297 0.74485 … 0.84589 0.178834 0.284413 - 0.160706 0.672252 0.133158 0.65554 0.371826 0.770628 0.0531208 - 0.306617 0.836126 0.301198 0.0224702 0.39344 0.0370205 0.536062 - 0.890947 0.168877 0.32002 0.486136 0.096078 0.172048 0.77672 - 0.507762 0.573567 0.220124 0.165816 0.211049 0.433277 0.539476 + 0.517515 0.0348206 0.749042 0.0979679 … 0.75984 0.950481 0.579513 + 0.901092 0.873479 0.134533 0.0697848 0.0586695 0.193254 0.726898 + 0.976808 0.0901881 0.208332 0.920358 0.288535 0.705941 0.337137 + 0.657127 0.0317896 0.772837 0.534457 0.0966037 0.700694 0.675999 + 0.471777 0.144969 0.0718405 0.0827916 0.527233 0.173132 0.694304 + 0.160872 0.455168 0.489254 0.827851 … 0.62226 0.0995456 0.946522 + 0.291857 0.769492 0.68043 0.629461 0.727558 0.910796 0.834837 + 0.775774 0.700731 0.700177 0.0126213 0.00822304 0.327502 0.955181 + 0.9715 0.64354 0.848441 0.241474 0.591611 0.792573 0.194357 + 0.646596 0.575456 0.0995212 0.038517 0.709233 0.477657 0.0507231 julia> b = view(a, 2:2:8,2:2:4) -4×2 SubArray{Float64,2,Array{Float64,2},Tuple{StepRange{Int64,Int64},StepRange{Int64,Int64}},false}: - 0.537192 0.996234 - 0.736979 0.228787 - 0.991511 0.74485 - 0.836126 0.0224702 +4×2 view(::Array{Float64,2}, 2:2:8, 2:2:4) with eltype Float64: + 0.873479 0.0697848 + 0.0317896 0.534457 + 0.455168 0.827851 + 0.700731 0.0126213 -julia> (q,r) = qr(b); +julia> (q, r) = qr(b); julia> q -4×2 Array{Float64,2}: - -0.338809 0.78934 - -0.464815 -0.230274 - -0.625349 0.194538 - -0.527347 -0.534856 +4×4 LinearAlgebra.QRCompactWYQ{Float64,Array{Float64,2}}: + -0.722358 0.227524 -0.247784 -0.604181 + -0.0262896 -0.575919 -0.804227 0.144377 + -0.376419 -0.75072 0.540177 -0.0541979 + -0.579497 0.230151 -0.00552346 0.781782 julia> r 2×2 Array{Float64,2}: - -1.58553 -0.921517 - 0.0 0.866567 + -1.20921 -0.383393 + 0.0 -0.910506 ``` diff --git a/codex/manual/calling-c-and-fortran-code.md b/codex/manual/calling-c-and-fortran-code.md index affc89b..7eeac82 100644 --- a/codex/manual/calling-c-and-fortran-code.md +++ b/codex/manual/calling-c-and-fortran-code.md @@ -934,7 +934,7 @@ function qsort(a::Vector{T}, cmp) where T # Here, `callback` isa Base.CFunction, which will be converted to Ptr{Cvoid} # (and protected against finalization) by the ccall ccall(:qsort, Cvoid, (Ptr{T}, Csize_t, Csize_t, Ptr{Cvoid}), - a, length(A), Base.elsize(A), callback) + a, length(a), Base.elsize(a), callback) # We could instead use: # GC.@preserve callback begin # use(Base.unsafe_convert(Ptr{Cvoid}, callback)) diff --git a/codex/manual/code-loading.md b/codex/manual/code-loading.md index e95c37f..2140306 100644 --- a/codex/manual/code-loading.md +++ b/codex/manual/code-loading.md @@ -19,7 +19,7 @@ Understanding how Julia answers these questions is key to understanding package ## Federation of packages -Julia supports federated management of packages. This means that multiple independent parties can maintain both public and private packages and registries of them, and that projects can depend on a mix of public and private packages from different registries. Packages from various registries are installed and managed using a common set of tools and workflows. The Pkg3 next-generation package manager [[docs](https://julialang.org/Pkg3.jl/latest/), [repo](https://github.com/JuliaLang/Pkg3.jl)] ships with Julia 0.7/1.0 and lets you install and manage dependencies of your projects, by creating and manipulating project files, which describe what your project depends on, and manifest files that snapshot exact versions of your project's complete dependency graph. +Julia supports federated management of packages. This means that multiple independent parties can maintain both public and private packages and registries of them, and that projects can depend on a mix of public and private packages from different registries. Packages from various registries are installed and managed using a common set of tools and workflows. The `Pkg` package manager ships with Julia 0.7/1.0 and lets you install and manage dependencies of your projects, by creating and manipulating project files, which describe what your project depends on, and manifest files that snapshot exact versions of your project's complete dependency graph. One consequence of federation is that there cannot be a central authority for package naming. Different entities may use the same name to refer to unrelated packages. This possibility is unavoidable since these entities do not coordinate and may not even know about each other. Because of the lack of a central naming authority, a single project can quite possibly end up depending on different packages with the same name. Julia's package loading mechanism handles this by not requiring package names to be globally unique, even within the dependency graph of a single project. Instead, packages are identified by [universally unique identifiers](https://en.wikipedia.org/wiki/Universally_unique_identifier) (UUIDs) which are assigned to them before they are registered. The question *"what is `X`?"* is answered by determining the UUID of `X`. diff --git a/codex/manual/environment-variables.md b/codex/manual/environment-variables.md index 739335b..6d6286d 100644 --- a/codex/manual/environment-variables.md +++ b/codex/manual/environment-variables.md @@ -76,36 +76,6 @@ the absolute path e.g., version 0.7 of Julia on a Linux system with a Julia executable at `/bin/julia` will have a default `LOAD_PATH` of `/share/julia/stdlib/v0.7`. -### `JULIA_PKGDIR` - -The path of the parent directory `Pkg.Dir._pkgroot()` for the version-specific -Julia package repositories. If the path is relative, then it is taken with -respect to the working directory. If `$JULIA_PKGDIR` is not set, then -`Pkg.Dir._pkgroot()` defaults to - -``` -$HOME/.julia -``` - -Then the repository location `Pkg.dir` for a given Julia version is - -``` -$JULIA_PKGDIR/v$(VERSION.major).$(VERSION.minor) -``` - -For example, for a Linux user whose home directory is `/home/alice`, the directory -containing the package repositories would by default be - -``` -/home/alice/.julia -``` - -and the package repository for version 0.6 of Julia would be - -``` -/home/alice/.julia/v0.6 -``` - ### `JULIA_HISTORY` The absolute path `REPL.find_hist_file()` of the REPL's history file. If @@ -118,7 +88,7 @@ $HOME/.julia/logs/repl_history.jl ### `JULIA_PKGRESOLVE_ACCURACY` A positive `Int` that determines how much time the max-sum subroutine -`MaxSum.maxsum()` of the package dependency resolver `Pkg.resolve` +`MaxSum.maxsum()` of the package dependency resolver will devote to attempting satisfying constraints before giving up: this value is by default `1`, and larger values correspond to larger amounts of time. @@ -154,7 +124,7 @@ exists, or `emacs` otherwise. !!! note `$JULIA_EDITOR` is *not* used in the determination of the editor for - `Pkg.edit`: this function checks `$VISUAL` and `$EDITOR` alone. + `OldPkg.edit`: this function checks `$VISUAL` and `$EDITOR` alone. ## Parallelization diff --git a/codex/manual/index.md b/codex/manual/index.md index 5f79a98..3ae00cf 100644 --- a/codex/manual/index.md +++ b/codex/manual/index.md @@ -28,8 +28,6 @@ * [Handling Operating System Variation](@ref) * [Environment Variables](@ref) * [Embedding Julia](@ref) - * [Packages](@ref) - * [Package Development](@ref) * [Profiling](@ref) * [Memory allocation analysis](@ref) * [Stack Traces](@ref) diff --git a/codex/manual/modules.md b/codex/manual/modules.md index a12f873..c6c6840 100644 --- a/codex/manual/modules.md +++ b/codex/manual/modules.md @@ -363,7 +363,7 @@ code to help the user avoid other wrong-behavior situations: 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`](@ref)), and no cleanup is done after [`Pkg.rm`](@ref) + (including by [`Pkg.update`], and no cleanup is done after [`Pkg.rm`] 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__`](@ref)/`source_path()` @@ -383,5 +383,5 @@ command line flag `--compiled-modules={yes|no}` enables you to toggle module pre off. When Julia is started with `--compiled-modules=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`](@ref) to disable automatic precompilation triggering when installing, +line flag is passed to [`Pkg.build`] to disable automatic precompilation triggering when installing, updating, and explicitly building packages. diff --git a/codex/manual/packages.md b/codex/manual/packages.md deleted file mode 100644 index f10edc1..0000000 --- a/codex/manual/packages.md +++ /dev/null @@ -1,1118 +0,0 @@ -# Packages - -Julia has a built-in package manager for installing add-on functionality written in Julia. It -can also install external libraries using your operating system's standard system for doing so, -or by compiling from source. The list of registered Julia packages can be found at [http://pkg.julialang.org](http://pkg.julialang.org). -All package manager commands are found in the `Pkg` standard library which becomes available after using -`import Pkg`. - -First we'll go over the mechanics of the `Pkg` family of commands and then we'll provide some -guidance on how to get your package registered. Be sure to read the section below on package naming -conventions, tagging versions and the importance of a `REQUIRE` file for when you're ready to -add your code to the curated METADATA repository. - -## Package Status - -The [`Pkg.status()`](@ref) function prints out a summary of the state of packages you have installed. -Initially, you'll have no packages installed: - -```julia-repl -julia> Pkg.status() -INFO: Initializing package repository /Users/someone/.julia/v0.6 -INFO: Cloning METADATA from git://github.com/JuliaLang/METADATA.jl -No packages installed. -``` - -Your package directory is automatically initialized the first time you run a `Pkg` command -that expects it to exist – which includes [`Pkg.status()`](@ref). Here's an example non-trivial -set of required and additional packages: - -```julia-repl -julia> Pkg.status() -Required packages: - - Distributions 0.2.8 - - SHA 0.3.2 -Additional packages: - - NumericExtensions 0.2.17 - - Stats 0.2.6 -``` - -These packages are all on registered versions, managed by `Pkg`. Packages can be in more -complicated states, indicated by annotations to the right of the installed package version; we -will explain these states and annotations as we encounter them. For programmatic usage, [`Pkg.installed()`](@ref) -returns a dictionary, mapping installed package names to the version of that package which is -installed: - -```julia-repl -julia> Pkg.installed() -Dict{String,VersionNumber} with 4 entries: -"Distributions" => v"0.2.8" -"Stats" => v"0.2.6" -"SHA" => v"0.3.2" -"NumericExtensions" => v"0.2.17" -``` - -## Adding and Removing Packages - -Julia's package manager is a little unusual in that it is declarative rather than imperative. -This means that you tell it what you want and it figures out what versions to install (or remove) -to satisfy those requirements optimally – and minimally. So rather than installing a package, -you just add it to the list of requirements and then "resolve" what needs to be installed. In -particular, this means that if some package had been installed because it was needed by a previous -version of something you wanted, and a newer version doesn't have that requirement anymore, updating -will actually remove that package. - -Your package requirements are in the file `~/.julia/v0.6/REQUIRE`. You can edit this file by hand -and then call [`Pkg.resolve()`](@ref) to install, upgrade or remove packages to optimally satisfy -the requirements, or you can do [`Pkg.edit()`](@ref), which will open `REQUIRE` in your editor -(configured via the `EDITOR` or `VISUAL` environment variables), and then automatically call -[`Pkg.resolve()`](@ref) afterwards if necessary. If you only want to add or remove the requirement -for a single package, you can also use the non-interactive [`Pkg.add()`](@ref) and [`Pkg.rm()`](@ref) -commands, which add or remove a single requirement to `REQUIRE` and then call [`Pkg.resolve()`](@ref). - -You can add a package to the list of requirements with the [`Pkg.add()`](@ref) function, and the -package and all the packages that it depends on will be installed: - -```julia-repl -julia> Pkg.status() -No packages installed. - -julia> Pkg.add("Distributions") -INFO: Cloning cache of Distributions from git://github.com/JuliaStats/Distributions.jl.git -INFO: Cloning cache of NumericExtensions from git://github.com/lindahua/NumericExtensions.jl.git -INFO: Cloning cache of Stats from git://github.com/JuliaStats/Stats.jl.git -INFO: Installing Distributions v0.2.7 -INFO: Installing NumericExtensions v0.2.17 -INFO: Installing Stats v0.2.6 -INFO: REQUIRE updated. - -julia> Pkg.status() -Required packages: - - Distributions 0.2.7 -Additional packages: - - NumericExtensions 0.2.17 - - Stats 0.2.6 -``` - -What this is doing is first adding `Distributions` to your `~/.julia/v0.6/REQUIRE` file: - -``` -$ cat ~/.julia/v0.6/REQUIRE -Distributions -``` - -It then runs [`Pkg.resolve()`](@ref) using these new requirements, which leads to the conclusion -that the `Distributions` package should be installed since it is required but not installed. As -stated before, you can accomplish the same thing by editing your `~/.julia/v0.6/REQUIRE` file -by hand and then running [`Pkg.resolve()`](@ref) yourself: - -```julia-repl -$ echo SHA >> ~/.julia/v0.6/REQUIRE - -julia> Pkg.resolve() -INFO: Cloning cache of SHA from git://github.com/staticfloat/SHA.jl.git -INFO: Installing SHA v0.3.2 - -julia> Pkg.status() -Required packages: - - Distributions 0.2.7 - - SHA 0.3.2 -Additional packages: - - NumericExtensions 0.2.17 - - Stats 0.2.6 -``` - -This is functionally equivalent to calling [`Pkg.add("SHA")`](@ref), except that [`Pkg.add()`](@ref) -doesn't change `REQUIRE` until *after* installation has completed, so if there are problems, -`REQUIRE` will be left as it was before calling [`Pkg.add()`](@ref). The format of the `REQUIRE` -file is described in [Requirements Specification](@ref); it allows, among other things, requiring -specific ranges of versions of packages. - -When you decide that you don't want to have a package around any more, you can use [`Pkg.rm()`](@ref) -to remove the requirement for it from the `REQUIRE` file: - -```julia-repl -julia> Pkg.rm("Distributions") -INFO: Removing Distributions v0.2.7 -INFO: Removing Stats v0.2.6 -INFO: Removing NumericExtensions v0.2.17 -INFO: REQUIRE updated. - -julia> Pkg.status() -Required packages: - - SHA 0.3.2 - -julia> Pkg.rm("SHA") -INFO: Removing SHA v0.3.2 -INFO: REQUIRE updated. - -julia> Pkg.status() -No packages installed. -``` - -Once again, this is equivalent to editing the `REQUIRE` file to remove the line with each package -name on it then running [`Pkg.resolve()`](@ref) to update the set of installed packages to match. -While [`Pkg.add()`](@ref) and [`Pkg.rm()`](@ref) are convenient for adding and removing requirements -for a single package, when you want to add or remove multiple packages, you can call [`Pkg.edit()`](@ref) -to manually change the contents of `REQUIRE` and then update your packages accordingly. [`Pkg.edit()`](@ref) -does not roll back the contents of `REQUIRE` if [`Pkg.resolve()`](@ref) fails – rather, you -have to run [`Pkg.edit()`](@ref) again to fix the files contents yourself. - -Because the package manager uses libgit2 internally to manage the package git repositories, users -may run into protocol issues (if behind a firewall, for example), when running [`Pkg.add()`](@ref). -By default, all GitHub-hosted packages wil be accessed via 'https'; this default can be modified -by calling [`Pkg.setprotocol!()`](@ref). The following command can be run from the command line -in order to tell git to use 'https' instead of the 'git' protocol when cloning all repositories, -wherever they are hosted: - -``` -git config --global url."https://".insteadOf git:// -``` - -However, this change will be system-wide and thus the use of [`Pkg.setprotocol!()`](@ref) is preferable. - -!!! note - The package manager functions also accept the `.jl` suffix on package names, though the suffix is - stripped internally. For example: - - ```julia - Pkg.add("Distributions.jl") - Pkg.rm("Distributions.jl") - ``` - -## Offline Installation of Packages - -For machines with no Internet connection, packages may be installed by copying the package root -directory (given by [`Pkg.dir()`](@ref)) from a machine with the same operating system and environment. - -[`Pkg.add()`](@ref) does the following within the package root directory: - -1. Adds the name of the package to `REQUIRE`. -2. Downloads the package to `.cache`, then copies the package to the package root directory. -3. Recursively performs step 2 against all the packages listed in the package's `REQUIRE` file. -4. Runs [`Pkg.build()`](@ref) - -!!! warning - Copying installed packages from a different machine is brittle for packages requiring binary external - dependencies. Such packages may break due to differences in operating system versions, build environments, - and/or absolute path dependencies. - -## Installing Unregistered Packages - -Julia packages are simply git repositories, clonable via any of the [protocols](https://www.kernel.org/pub/software/scm/git/docs/git-clone.html#URLS) -that git supports, and containing Julia code that follows certain layout conventions. Official -Julia packages are registered in the [METADATA.jl](https://github.com/JuliaLang/METADATA.jl) repository, -available at a well-known location [^1]. The [`Pkg.add()`](@ref) and [`Pkg.rm()`](@ref) commands -in the previous section interact with registered packages, but the package manager can install -and work with unregistered packages too. To install an unregistered package, use [`Pkg.clone(url)`](@ref), -where `url` is a git URL from which the package can be cloned: - -```julia-repl -julia> Pkg.clone("git://example.com/path/to/Package.jl.git") -INFO: Cloning Package from git://example.com/path/to/Package.jl.git -Cloning into 'Package'... -remote: Counting objects: 22, done. -remote: Compressing objects: 100% (10/10), done. -remote: Total 22 (delta 8), reused 22 (delta 8) -Receiving objects: 100% (22/22), 2.64 KiB, done. -Resolving deltas: 100% (8/8), done. -``` - -By convention, Julia repository names end with `.jl` (the additional `.git` indicates a "bare" -git repository), which keeps them from colliding with repositories for other languages, and also -makes Julia packages easy to find in search engines. When packages are installed in your `.julia/v0.6` -directory, however, the extension is redundant so we leave it off. - -If unregistered packages contain a `REQUIRE` file at the top of their source tree, that file will -be used to determine which registered packages the unregistered package depends on, and they will -automatically be installed. Unregistered packages participate in the same version resolution logic -as registered packages, so installed package versions will be adjusted as necessary to satisfy -the requirements of both registered and unregistered packages. - -[^1]: - The official set of packages is at [https://github.com/JuliaLang/METADATA.jl](https://github.com/JuliaLang/METADATA.jl), - but individuals and organizations can easily use a different metadata repository. This allows - control which packages are available for automatic installation. One can allow only audited and - approved package versions, and make private packages or forks available. See [Custom METADATA Repository](@ref) - for details. - -## Updating Packages - -When package developers publish new registered versions of packages that you're using, you will, -of course, want the new shiny versions. To get the latest and greatest versions of all your packages, -just do [`Pkg.update()`](@ref): - -```julia-repl -julia> Pkg.update() -INFO: Updating METADATA... -INFO: Computing changes... -INFO: Upgrading Distributions: v0.2.8 => v0.2.10 -INFO: Upgrading Stats: v0.2.7 => v0.2.8 -``` - -The first step of updating packages is to pull new changes to `~/.julia/v0.6/METADATA` and see -if any new registered package versions have been published. After this, [`Pkg.update()`](@ref) -attempts to update packages that are checked out on a branch and not dirty (i.e. no changes have -been made to files tracked by git) by pulling changes from the package's upstream repository. -Upstream changes will only be applied if no merging or rebasing is necessary – i.e. if the branch -can be ["fast-forwarded"](https://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging). -If the branch cannot be fast-forwarded, it is assumed that you're working on it and will update -the repository yourself. - -Finally, the update process recomputes an optimal set of package versions to have installed to -satisfy your top-level requirements and the requirements of "fixed" packages. A package is considered -fixed if it is one of the following: - -1. **Unregistered:** the package is not in `METADATA` – you installed it with [`Pkg.clone()`](@ref). -2. **Checked out:** the package repo is on a development branch. -3. **Dirty:** changes have been made to files in the repo. - -If any of these are the case, the package manager cannot freely change the installed version of -the package, so its requirements must be satisfied by whatever other package versions it picks. -The combination of top-level requirements in `~/.julia/v0.6/REQUIRE` and the requirement of fixed -packages are used to determine what should be installed. - -You can also update only a subset of the installed packages, by providing arguments to the [`Pkg.update`](@ref) -function. In that case, only the packages provided as arguments and their dependencies will be -updated: - -```julia-repl -julia> Pkg.update("Example") -INFO: Updating METADATA... -INFO: Computing changes... -INFO: Upgrading Example: v0.4.0 => 0.4.1 -``` - -This partial update process still computes the new set of package versions according to top-level -requirements and "fixed" packages, but it additionally considers all other packages except those -explicitly provided, and their dependencies, as fixed. - -## Checkout, Pin and Free - -You may want to use the `master` version of a package rather than one of its registered versions. -There might be fixes or functionality on master that you need that aren't yet published in any -registered versions, or you may be a developer of the package and need to make changes on `master` -or some other development branch. In such cases, you can do [`Pkg.checkout(pkg)`](@ref) to checkout -the `master` branch of `pkg` or [`Pkg.checkout(pkg,branch)`](@ref) to checkout some other branch: - -```julia-repl -julia> Pkg.add("Distributions") -INFO: Installing Distributions v0.2.9 -INFO: Installing NumericExtensions v0.2.17 -INFO: Installing Stats v0.2.7 -INFO: REQUIRE updated. - -julia> Pkg.status() -Required packages: - - Distributions 0.2.9 -Additional packages: - - NumericExtensions 0.2.17 - - Stats 0.2.7 - -julia> Pkg.checkout("Distributions") -INFO: Checking out Distributions master... -INFO: No packages to install, update or remove. - -julia> Pkg.status() -Required packages: - - Distributions 0.2.9+ master -Additional packages: - - NumericExtensions 0.2.17 - - Stats 0.2.7 -``` - -Immediately after installing `Distributions` with [`Pkg.add()`](@ref) it is on the current most -recent registered version – `0.2.9` at the time of writing this. Then after running [`Pkg.checkout("Distributions")`](@ref), -you can see from the output of [`Pkg.status()`](@ref) that `Distributions` is on an unregistered -version greater than `0.2.9`, indicated by the "pseudo-version" number `0.2.9+`. - -When you checkout an unregistered version of a package, the copy of the `REQUIRE` file in the -package repo takes precedence over any requirements registered in `METADATA`, so it is important -that developers keep this file accurate and up-to-date, reflecting the actual requirements of -the current version of the package. If the `REQUIRE` file in the package repo is incorrect or -missing, dependencies may be removed when the package is checked out. This file is also used to -populate newly published versions of the package if you use the API that `Pkg` provides -for this (described below). - -When you decide that you no longer want to have a package checked out on a branch, you can "free" -it back to the control of the package manager with [`Pkg.free(pkg)`](@ref): - -```julia-repl -julia> Pkg.free("Distributions") -INFO: Freeing Distributions... -INFO: No packages to install, update or remove. - -julia> Pkg.status() -Required packages: - - Distributions 0.2.9 -Additional packages: - - NumericExtensions 0.2.17 - - Stats 0.2.7 -``` - -After this, since the package is on a registered version and not on a branch, its version will -be updated as new registered versions of the package are published. - -If you want to pin a package at a specific version so that calling [`Pkg.update()`](@ref) won't -change the version the package is on, you can use the [`Pkg.pin()`](@ref) function: - -```julia-repl -julia> Pkg.pin("Stats") -INFO: Creating Stats branch pinned.47c198b1.tmp - -julia> Pkg.status() -Required packages: - - Distributions 0.2.9 -Additional packages: - - NumericExtensions 0.2.17 - - Stats 0.2.7 pinned.47c198b1.tmp -``` - -After this, the `Stats` package will remain pinned at version `0.2.7` – or more specifically, -at commit `47c198b1`, but since versions are permanently associated a given git hash, this is -the same thing. [`Pkg.pin()`](@ref) works by creating a throw-away branch for the commit you want -to pin the package at and then checking that branch out. By default, it pins a package at the -current commit, but you can choose a different version by passing a second argument: - -```julia-repl -julia> Pkg.pin("Stats",v"0.2.5") -INFO: Creating Stats branch pinned.1fd0983b.tmp -INFO: No packages to install, update or remove. - -julia> Pkg.status() -Required packages: - - Distributions 0.2.9 -Additional packages: - - NumericExtensions 0.2.17 - - Stats 0.2.5 pinned.1fd0983b.tmp -``` - -Now the `Stats` package is pinned at commit `1fd0983b`, which corresponds to version `0.2.5`. -When you decide to "unpin" a package and let the package manager update it again, you can use -[`Pkg.free()`](@ref) like you would to move off of any branch: - -```julia-repl -julia> Pkg.free("Stats") -INFO: Freeing Stats... -INFO: No packages to install, update or remove. - -julia> Pkg.status() -Required packages: - - Distributions 0.2.9 -Additional packages: - - NumericExtensions 0.2.17 - - Stats 0.2.7 -``` - -After this, the `Stats` package is managed by the package manager again, and future calls to -[`Pkg.update()`](@ref) will upgrade it to newer versions when they are published. The throw-away -`pinned.1fd0983b.tmp` branch remains in your local `Stats` repo, but since git branches are extremely -lightweight, this doesn't really matter; if you feel like cleaning them up, you can go into the -repo and delete those branches [^2]. - -[^2]: - Packages that aren't on branches will also be marked as dirty if you make changes in the repo, - but that's a less common thing to do. - -## Custom METADATA Repository - -By default, Julia assumes you will be using the [official METADATA.jl](https://github.com/JuliaLang/METADATA.jl) -repository for downloading and installing packages. You can also provide a different metadata -repository location. A common approach is to keep your `metadata-v2` branch up to date with the -Julia official branch and add another branch with your custom packages. You can initialize your -local metadata repository using that custom location and branch and then periodically rebase your -custom branch with the official `metadata-v2` branch. In order to use a custom repository and -branch, issue the following command: - -```julia-repl -julia> Pkg.init("https://me.example.com/METADATA.jl.git", "branch") -``` - -The branch argument is optional and defaults to `metadata-v2`. Once initialized, a file named -`META_BRANCH` in your `~/.julia/vX.Y/` path will track the branch that your METADATA repository -was initialized with. If you want to change branches, you will need to either modify the `META_BRANCH` -file directly (be careful!) or remove the `vX.Y` directory and re-initialize your METADATA repository -using the `Pkg.init` command. - -# Package Development - -Julia's package manager is designed so that when you have a package installed, you are already -in a position to look at its source code and full development history. You are also able to make -changes to packages, commit them using git, and easily contribute fixes and enhancements upstream. -Similarly, the system is designed so that if you want to create a new package, the simplest way -to do so is within the infrastructure provided by the package manager. - -## [Initial Setup](@id man-initial-setup) - -Since packages are git repositories, before doing any package development you should setup the -following standard global git configuration settings: - -``` -$ git config --global user.name "FULL NAME" -$ git config --global user.email "EMAIL" -``` - -where `FULL NAME` is your actual full name (spaces are allowed between the double quotes) and -`EMAIL` is your actual email address. Although it isn't necessary to use [GitHub](https://github.com/) -to create or publish Julia packages, most Julia packages as of writing this are hosted on GitHub -and the package manager knows how to format origin URLs correctly and otherwise work with the -service smoothly. We recommend that you create a [free account](https://github.com/join) on GitHub -and then do: - -``` -$ git config --global github.user "USERNAME" -``` - -where `USERNAME` is your actual GitHub user name. Once you do this, the package manager knows -your GitHub user name and can configure things accordingly. You should also [upload](https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2Fsettings%2Fssh) -your public SSH key to GitHub and set up an [SSH agent](https://linux.die.net/man/1/ssh-agent) -on your development machine so that you can push changes with minimal hassle. In the future, we -will make this system extensible and support other common git hosting options like [BitBucket](https://bitbucket.org) -and allow developers to choose their favorite. Since the package development functions has been -moved to the [PkgDev](https://github.com/JuliaLang/PkgDev.jl) package, you need to run `Pkg.add("PkgDev"); import PkgDev` -to access the functions starting with `PkgDev.` in the document below. - -## Making changes to an existing package - -### Documentation changes - -If you want to improve the online documentation of a package, the easiest approach (at least for -small changes) is to use GitHub's online editing functionality. First, navigate to the repository's -GitHub "home page," find the file (e.g., `README.md`) within the repository's folder structure, -and click on it. You'll see the contents displayed, along with a small "pencil" icon in the upper -right hand corner. Clicking that icon opens the file in edit mode. Make your changes, write a -brief summary describing the changes you want to make (this is your *commit message*), and then -hit "Propose file change." Your changes will be submitted for consideration by the package owner(s) -and collaborators. - -For larger documentation changes--and especially ones that you expect to have to update in response -to feedback--you might find it easier to use the procedure for code changes described below. - -### Code changes - -#### Executive summary - -Here we assume you've already set up git on your local machine and have a GitHub account (see -above). Let's imagine you're fixing a bug in the Images package: - -``` -Pkg.checkout("Images") # check out the master branch - -cd(Pkg.dir("Images")) -;git checkout -b myfixes # create a branch for your changes - # be sure to add a test for your bug -Pkg.test("Images") # make sure everything works now -;git commit -a -m "Fix foo by calling bar" # write a descriptive message -using PkgDev -PkgDev.submit("Images") -``` - -The last line will present you with a link to submit a pull request to incorporate your changes. - -#### Detailed description - -If you want to fix a bug or add new functionality, you want to be able to test your changes before -you submit them for consideration. You also need to have an easy way to update your proposal in -response to the package owner's feedback. Consequently, in this case the strategy is to work locally -on your own machine; once you are satisfied with your changes, you submit them for consideration. - This process is called a *pull request* because you are asking to "pull" your changes into the -project's main repository. Because the online repository can't see the code on your private machine, -you first *push* your changes to a publicly-visible location, your own online *fork* of the package -(hosted on your own personal GitHub account). - -Let's assume you already have the `Foo` package installed. In the description below, anything -starting with `Pkg.` or `PkgDev.` is meant to be typed at the Julia prompt; anything starting -with `git` is meant to be typed in [julia's shell mode](@ref man-shell-mode) (or using the shell that comes with -your operating system). Within Julia, you can combine these two modes: - -```julia-repl -julia> cd(Pkg.dir("Foo")) # go to Foo's folder - -shell> git command arguments... # command will apply to Foo -``` - -Now suppose you're ready to make some changes to `Foo`. While there are several possible approaches, -here is one that is widely used: - - * From the Julia prompt, type [`Pkg.checkout("Foo")`](@ref). This ensures you're running the latest - code (the `master` branch), rather than just whatever "official release" version you have installed. - (If you're planning to fix a bug, at this point it's a good idea to check again whether the bug - has already been fixed by someone else. If it has, you can request that a new official release - be tagged so that the fix gets distributed to the rest of the community.) If you receive an error - `Foo is dirty, bailing`, see [Dirty packages](@ref) below. - * Create a branch for your changes: navigate to the package folder (the one that Julia reports from - [`Pkg.dir("Foo")`](@ref)) and (in shell mode) create a new branch using `git checkout -b `, - where `` might be some descriptive name (e.g., `fixbar`). By creating a branch, you - ensure that you can easily go back and forth between your new work and the current `master` branch - (see [https://git-scm.com/book/en/v2/Git-Branching-Branches-in-a-Nutshell](https://git-scm.com/book/en/v2/Git-Branching-Branches-in-a-Nutshell)). - - If you forget to do this step until after you've already made some changes, don't worry: see - [more detail about branching](@ref man-branch-post-hoc) below. - * Make your changes. Whether it's fixing a bug or adding new functionality, in most cases your change - should include updates to both the `src/` and `test/` folders. If you're fixing a bug, add your - minimal example demonstrating the bug (on the current code) to the test suite; by contributing - a test for the bug, you ensure that the bug won't accidentally reappear at some later time due - to other changes. If you're adding new functionality, creating tests demonstrates to the package - owner that you've made sure your code works as intended. - * Run the package's tests and make sure they pass. There are several ways to run the tests: - - * From Julia, run [`Pkg.test("Foo")`](@ref): this will run your tests in a separate (new) `julia` - process. - * From Julia, `include("runtests.jl")` from the package's `test/` folder (it's possible the file - has a different name, look for one that runs all the tests): this allows you to run the tests - repeatedly in the same session without reloading all the package code; for packages that take - a while to load, this can be much faster. With this approach, you do have to do some extra work - to make [changes in the package code](@ref man-workflow-tips). - * From the shell, run `julia ../test/runtests.jl` from within the package's `src/` folder. - * Commit your changes: see [https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository](https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository). - * Submit your changes: From the Julia prompt, type `PkgDev.submit("Foo")`. This will push your changes - to your GitHub fork, creating it if it doesn't already exist. (If you encounter an error, [make sure you've set up your SSH keys](@ref man-initial-setup).) - Julia will then give you a hyperlink; open that link, edit the message, and then click "submit." - At that point, the package owner will be notified of your changes and may initiate discussion. - (If you are comfortable with git, you can also do these steps manually from the shell.) - * The package owner may suggest additional improvements. To respond to those suggestions, you can - easily update the pull request (this only works for changes that have not already been merged; - for merged pull requests, make new changes by starting a new branch): - - * If you've changed branches in the meantime, make sure you go back to the same branch with `git checkout fixbar` - (from shell mode) or [`Pkg.checkout("Foo", "fixbar")`](@ref) (from the Julia prompt). - * As above, make your changes, run the tests, and commit your changes. - * From the shell, type `git push`. This will add your new commit(s) to the same pull request; you - should see them appear automatically on the page holding the discussion of your pull request. - - One potential type of change the owner may request is that you squash your commits. See [Squashing](@ref man-squashing-and-rebasing) - below. - -### Dirty packages - -If you can't change branches because the package manager complains that your package is dirty, -it means you have some changes that have not been committed. From the shell, use `git diff` to -see what these changes are; you can either discard them (`git checkout changedfile.jl`) or commit -them before switching branches. If you can't easily resolve the problems manually, as a last -resort you can delete the entire `"Foo"` folder and reinstall a fresh copy with [`Pkg.add("Foo")`](@ref). -Naturally, this deletes any changes you've made. - -### [Making a branch *post hoc*](@id man-branch-post-hoc) - -Especially for newcomers to git, one often forgets to create a new branch until after some changes -have already been made. If you haven't yet staged or committed your changes, you can create a -new branch with `git checkout -b ` just as usual--git will kindly show you that some -files have been modified and create the new branch for you. *Your changes have not yet been committed to this new branch*, -so the normal work rules still apply. - -However, if you've already made a commit to `master` but wish to go back to the official `master` -(called `origin/master`), use the following procedure: - - * Create a new branch. This branch will hold your changes. - * Make sure everything is committed to this branch. - * `git checkout master`. If this fails, *do not* proceed further until you have resolved the problems, - or you may lose your changes. - * *Reset*`master` (your current branch) back to an earlier state with `git reset --hard origin/master` - (see [https://git-scm.com/blog/2011/07/11/reset.html](https://git-scm.com/blog/2011/07/11/reset.html)). - -This requires a bit more familiarity with git, so it's much better to get in the habit of creating -a branch at the outset. - -### [Squashing and rebasing](@id man-squashing-and-rebasing) - -Depending on the tastes of the package owner (s)he may ask you to "squash" your commits. This -is especially likely if your change is quite simple but your commit history looks like this: - -``` -WIP: add new 1-line whizbang function (currently breaks package) -Finish whizbang function -Fix typo in variable name -Oops, don't forget to supply default argument -Split into two 1-line functions -Rats, forgot to export the second function -... -``` - -This gets into the territory of more advanced git usage, and you're encouraged to do some reading -([https://git-scm.com/book/en/v2/Git-Branching-Rebasing](https://git-scm.com/book/en/v2/Git-Branching-Rebasing)). - However, a brief summary of the procedure is as follows: - - * To protect yourself from error, start from your `fixbar` branch and create a new branch with - `git checkout -b fixbar_backup`. Since you started from `fixbar`, this will be a copy. Now go - back to the one you intend to modify with `git checkout fixbar`. - * From the shell, type `git rebase -i origin/master`. - * To combine commits, change `pick` to `squash` (for additional options, consult other sources). - Save the file and close the editor window. - * Edit the combined commit message. - -If the rebase goes badly, you can go back to the beginning to try again like this: - -``` -git checkout fixbar -git reset --hard fixbar_backup -``` - -Now let's assume you've rebased successfully. Since your `fixbar` repository has now diverged -from the one in your GitHub fork, you're going to have to do a *force push*: - - * To make it easy to refer to your GitHub fork, create a "handle" for it with `git remote add myfork https://github.com/myaccount/Foo.jl.git`, - where the URL comes from the "clone URL" on your GitHub fork's page. - * Force-push to your fork with `git push myfork +fixbar`. The `+` indicates that this should replace - the `fixbar` branch found at `myfork`. - -## Creating a new Package - -### REQUIRE speaks for itself - -You should have a `REQUIRE` file in your package repository, with a bare minimum directive of -what Julia version you expect your users to be running for the package to work. Putting a floor -on what Julia version your package supports is done by simply adding `julia 0.x` in this file. -While this line is partly informational, it also has the consequence of whether `Pkg.update()` -will update code found in `.julia` version directories. It will not update code found in version -directories beneath the floor of what's specified in your `REQUIRE`. - -As the development version `0.y` matures, you may find yourself using it more frequently, and -wanting your package to support it. Be warned, the development branch of Julia is the land of -breakage, and you can expect things to break. When you go about fixing whatever broke your package -in the development `0.y` branch, you will likely find that you just broke your package on the -stable version. - -There is a mechanism found in the [Compat](https://github.com/JuliaLang/Compat.jl) package that -will enable you to support both the stable version and breaking changes found in the development -version. Should you decide to use this solution, you will need to add `Compat` to your `REQUIRE` -file. In this case, you will still have `julia 0.x` in your `REQUIRE`. The `x` is the floor version -of what your package supports. - -You might also have no interest in supporting the development version of Julia. Just as you can -add a floor to the version you expect your users to be on, you can set an upper bound. In this -case, you would put `julia 0.x 0.y-` in your `REQUIRE` file. The `-` at the end of the version -number means pre-release versions of that specific version from the very first commit. By setting -it as the ceiling, you mean the code supports everything up to but not including the ceiling version. - -Another scenario is that you are writing the bulk of the code for your package with Julia `0.y` -and do not want to support the current stable version of Julia. If you choose to do this, simply -add `julia 0.y-` to your `REQUIRE`. Just remember to change the `julia 0.y-` to `julia 0.y` in -your `REQUIRE` file once `0.y` is officially released. If you don't edit the dash cruft you are -suggesting that you support both the development and stable versions of the same version number! -That would be madness. See the [Requirements Specification](@ref) for the full format of `REQUIRE`. - -Lastly, in many cases you may need extra packages for testing. Additional packages which -are only required for tests should be specified in the `test/REQUIRE` file. This `REQUIRE` -file has the same specification as the standard `REQUIRE` file. - -### Guidelines for naming a package - -Package names should be sensible to most Julia users, *even to those who are not domain experts*. -When you submit your package to METADATA, you can expect a little back and forth about the package -name with collaborators, especially if it's ambiguous or can be confused with something other -than what it is. During this bike-shedding, it's not uncommon to get a range of *different* name -suggestions. These are only suggestions though, with the intent being to keep a tidy namespace -in the curated METADATA repository. Since this repository belongs to the entire community, there -will likely be a few collaborators who care about your package name. Here are some guidelines -to follow in naming your package: - -1. Avoid jargon. In particular, avoid acronyms unless there is minimal possibility of confusion. - - * It's ok to say `USA` if you're talking about the USA. - * It's not ok to say `PMA`, even if you're talking about positive mental attitude. -2. Avoid using `Julia` in your package name. - - * It is usually clear from context and to your users that the package is a Julia package. - * Having Julia in the name can imply that the package is connected to, or endorsed by, contributors - to the Julia language itself. -3. Packages that provide most of their functionality in association with a new type should have pluralized - names. - - * `DataFrames` provides the `DataFrame` type. - * `BloomFilters` provides the `BloomFilter` type. - * In contrast, `JuliaParser` provides no new type, but instead new functionality in the `JuliaParser.parse()` - function. -4. Err on the side of clarity, even if clarity seems long-winded to you. - - * `RandomMatrices` is a less ambiguous name than `RndMat` or `RMT`, even though the latter are shorter. -5. A less systematic name may suit a package that implements one of several possible approaches to - its domain. - - * Julia does not have a single comprehensive plotting package. Instead, `Gadfly`, `PyPlot`, `Winston` - and other packages each implement a unique approach based on a particular design philosophy. - * In contrast, `SortingAlgorithms` provides a consistent interface to use many well-established - sorting algorithms. -6. Packages that wrap external libraries or programs should be named after those libraries or programs. - - * `CPLEX.jl` wraps the `CPLEX` library, which can be identified easily in a web search. - * `MATLAB.jl` provides an interface to call the MATLAB engine from within Julia. - -### Generating the package - -Suppose you want to create a new Julia package called `FooBar`. To get started, do `PkgDev.generate(pkg,license)` -where `pkg` is the new package name and `license` is the name of a license that the package generator -knows about: - -```julia-repl -julia> PkgDev.generate("FooBar","MIT") -INFO: Initializing FooBar repo: /Users/someone/.julia/v0.6/FooBar -INFO: Origin: git://github.com/someone/FooBar.jl.git -INFO: Generating LICENSE.md -INFO: Generating README.md -INFO: Generating src/FooBar.jl -INFO: Generating test/runtests.jl -INFO: Generating REQUIRE -INFO: Generating .travis.yml -INFO: Generating appveyor.yml -INFO: Generating .gitignore -INFO: Committing FooBar generated files -``` - -This creates the directory `~/.julia/v0.6/FooBar`, initializes it as a git repository, generates -a bunch of files that all packages should have, and commits them to the repository: - -``` -$ cd ~/.julia/v0.6/FooBar && git show --stat - -commit 84b8e266dae6de30ab9703150b3bf771ec7b6285 -Author: Some One -Date: Wed Oct 16 17:57:58 2013 -0400 - - FooBar.jl generated files. - - license: MIT - authors: Some One - years: 2013 - user: someone - - Julia Version 0.3.0-prerelease+3217 [5fcfb13*] - - .gitignore | 2 ++ - .travis.yml | 13 +++++++++++++ - LICENSE.md | 22 +++++++++++++++++++++++ - README.md | 3 +++ - REQUIRE | 1 + - appveyor.yml | 34 ++++++++++++++++++++++++++++++++++ - src/FooBar.jl | 5 +++++ - test/runtests.jl | 5 +++++ - 8 files changed, 85 insertions(+) -``` - -At the moment, the package manager knows about the MIT "Expat" License, indicated by `"MIT"`, -the Simplified BSD License, indicated by `"BSD"`, and version 2.0 of the Apache Software License, -indicated by `"ASL"`. If you want to use a different license, you can ask us to add it to the -package generator, or just pick one of these three and then modify the `~/.julia/v0.6/PACKAGE/LICENSE.md` -file after it has been generated. - -If you created a GitHub account and configured git to know about it, `PkgDev.generate()` will -set an appropriate origin URL for you. It will also automatically generate a `.travis.yml` file -for using the [Travis](https://travis-ci.org) automated testing service, and an `appveyor.yml` -file for using [AppVeyor](https://www.appveyor.com). You will have to enable testing on the Travis -and AppVeyor websites for your package repository, but once you've done that, it will already -have working tests. Of course, all the default testing does is verify that `using FooBar` in Julia -works. - -### Loading Static Non-Julia Files - -If your package code needs to load static files which are not Julia code, e.g. an external library -or data files, and are located within the package directory, use the `@__DIR__` macro to determine -the directory of the current source file. For example if `FooBar/src/FooBar.jl` needs to load -`FooBar/data/foo.csv`, use the following code: - -```julia -datapath = joinpath(@__DIR__, "..", "data") -foo = readdlm(joinpath(datapath, "foo.csv"), ',') -``` - -### Making Your Package Available - -Once you've made some commits and you're happy with how `FooBar` is working, you may want to get -some other people to try it out. First you'll need to create the remote repository and push your -code to it; we don't yet automatically do this for you, but we will in the future and it's not -too hard to figure out [^3]. Once you've done this, letting people try out your code is as simple -as sending them the URL of the published repo – in this case: - -``` -git://github.com/someone/FooBar.jl.git -``` - -For your package, it will be your GitHub user name and the name of your package, but you get the -idea. People you send this URL to can use [`Pkg.clone()`](@ref) to install the package and try -it out: - -```julia-repl -julia> Pkg.clone("git://github.com/someone/FooBar.jl.git") -INFO: Cloning FooBar from git@github.com:someone/FooBar.jl.git -``` - -[^3]: - Installing and using GitHub's ["hub" tool](https://github.com/github/hub) is highly recommended. - It allows you to do things like run `hub create` in the package repo and have it automatically - created via GitHub's API. - -### Tagging and Publishing Your Package - -!!! tip - If you are hosting your package on GitHub, you can use the [attobot integration](https://github.com/attobot/attobot) - to handle package registration, tagging and publishing. - -Once you've decided that `FooBar` is ready to be registered as an official package, you can add -it to your local copy of `METADATA` using `PkgDev.register()`: - -```julia-repl -julia> PkgDev.register("FooBar") -INFO: Registering FooBar at git://github.com/someone/FooBar.jl.git -INFO: Committing METADATA for FooBar -``` - -This creates a commit in the `~/.julia/v0.6/METADATA` repo: - -``` -$ cd ~/.julia/v0.6/METADATA && git show - -commit 9f71f4becb05cadacb983c54a72eed744e5c019d -Author: Some One -Date: Wed Oct 16 18:46:02 2013 -0400 - - Register FooBar - -diff --git a/FooBar/url b/FooBar/url -new file mode 100644 -index 0000000..30e525e ---- /dev/null -+++ b/FooBar/url -@@ -0,0 +1 @@ -+git://github.com/someone/FooBar.jl.git -``` - -This commit is only locally visible, however. To make it visible to the Julia community, you -need to merge your local `METADATA` upstream into the official repo. The `PkgDev.publish()` command -will fork the `METADATA` repository on GitHub, push your changes to your fork, and open a pull -request: - -```julia-repl -julia> PkgDev.publish() -INFO: Validating METADATA -INFO: No new package versions to publish -INFO: Submitting METADATA changes -INFO: Forking JuliaLang/METADATA.jl to someone -INFO: Pushing changes as branch pull-request/ef45f54b -INFO: To create a pull-request open: - - https://github.com/someone/METADATA.jl/compare/pull-request/ef45f54b -``` - -!!! tip - If `PkgDev.publish()` fails with error: - - ``` - ERROR: key not found: "token" - ``` - - then you may have encountered an issue from using the GitHub API on multiple systems. The solution - is to delete the "Julia Package Manager" personal access token [from your Github account](https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2Fsettings%2Ftokens) - and try again. - - Other failures may require you to circumvent `PkgDev.publish()` by [creating a pull request on GitHub](https://help.github.com/articles/creating-a-pull-request/). - See: [Publishing METADATA manually](@ref) below. - -Once the package URL for `FooBar` is registered in the official `METADATA` repo, people know where -to clone the package from, but there still aren't any registered versions available. You can tag -and register it with the `PkgDev.tag()` command: - -```julia-repl -julia> PkgDev.tag("FooBar") -INFO: Tagging FooBar v0.0.1 -INFO: Committing METADATA for FooBar -``` - -This tags `v0.0.1` in the `FooBar` repo: - -``` -$ cd ~/.julia/v0.6/FooBar && git tag -v0.0.1 -``` - -It also creates a new version entry in your local `METADATA` repo for `FooBar`: - -``` -$ cd ~/.julia/v0.6/FooBar && git show -commit de77ee4dc0689b12c5e8b574aef7f70e8b311b0e -Author: Some One -Date: Wed Oct 16 23:06:18 2013 -0400 - - Tag FooBar v0.0.1 - -diff --git a/FooBar/versions/0.0.1/sha1 b/FooBar/versions/0.0.1/sha1 -new file mode 100644 -index 0000000..c1cb1c1 ---- /dev/null -+++ b/FooBar/versions/0.0.1/sha1 -@@ -0,0 +1 @@ -+84b8e266dae6de30ab9703150b3bf771ec7b6285 -``` - -The `PkgDev.tag()` command takes an optional second argument that is either an explicit version -number object like `v"0.0.1"` or one of the symbols `:patch`, `:minor` or `:major`. These increment -the patch, minor or major version number of your package intelligently. - -Adding a tagged version of your package will expedite the official registration into METADATA.jl -by collaborators. It is strongly recommended that you complete this process, regardless if your -package is completely ready for an official release. - -As a general rule, packages should be tagged `0.0.1` first. Since Julia itself hasn't achieved -`1.0` status, it's best to be conservative in your package's tagged versions. - -As with `PkgDev.register()`, these changes to `METADATA` aren't available to anyone else until -they've been included upstream. Again, use the `PkgDev.publish()` command, which first makes sure -that individual package repos have been tagged, pushes them if they haven't already been, and -then opens a pull request to `METADATA`: - -```julia-repl -julia> PkgDev.publish() -INFO: Validating METADATA -INFO: Pushing FooBar permanent tags: v0.0.1 -INFO: Submitting METADATA changes -INFO: Forking JuliaLang/METADATA.jl to someone -INFO: Pushing changes as branch pull-request/3ef4f5c4 -INFO: To create a pull-request open: - - https://github.com/someone/METADATA.jl/compare/pull-request/3ef4f5c4 -``` - -#### Publishing METADATA manually - -If `PkgDev.publish()` fails you can follow these instructions to manually publish your package. - -By "forking" the main METADATA repository, you can create a personal copy (of METADATA.jl) under -your GitHub account. Once that copy exists, you can push your local changes to your copy (just -like any other GitHub project). - -1. Create a [fork of METADATA.jl](https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2FJuliaLang%2FMETADATA.jl%2Ffork). - -2. Add your fork as a remote repository for the METADATA repository on your local computer (in - the terminal where USERNAME is your github username): - - cd ~/.julia/v0.6/METADATA - git remote add USERNAME https://github.com/USERNAME/METADATA.jl.git - -3. Push your changes to your fork: - - git push USERNAME metadata-v2 - -4. If all of that works, then go back to the GitHub page for your fork, and click the "pull request" - link. - -## Fixing Package Requirements - -If you need to fix the registered requirements of an already-published package version, you can -do so just by editing the metadata for that version, which will still have the same commit hash -– the hash associated with a version is permanent: - -``` -$ cd ~/.julia/v0.6/METADATA/FooBar/versions/0.0.1 && cat requires -julia 0.3- -$ vi requires -``` - -Since the commit hash stays the same, the contents of the `REQUIRE` file that will be checked -out in the repo will **not** match the requirements in `METADATA` after such a change; this is -unavoidable. When you fix the requirements in `METADATA` for a previous version of a package, -however, you should also fix the `REQUIRE` file in the current version of the package. - -## Requirements Specification - -The `~/.julia/v0.6/REQUIRE` file, the `REQUIRE` file inside packages, and the `METADATA` package -`requires` files use a simple line-based format to express the ranges of package versions which -need to be installed. Package `REQUIRE` and `METADATA requires` files should also include the -range of versions of `julia` the package is expected to work with. Additionally, packages can -include a `test/REQUIRE` file to specify additional packages which are only required for testing. - -Here's how these files are parsed and interpreted. - - * Everything after a `#` mark is stripped from each line as a comment. - * If nothing but whitespace is left, the line is ignored. - * If there are non-whitespace characters remaining, the line is a requirement and the is split on - whitespace into words. - -The simplest possible requirement is just the name of a package name on a line by itself: - -```julia -Distributions -``` - -This requirement is satisfied by any version of the `Distributions` package. The package name -can be followed by zero or more version numbers in ascending order, indicating acceptable intervals -of versions of that package. One version opens an interval, while the next closes it, and the -next opens a new interval, and so on; if an odd number of version numbers are given, then arbitrarily -large versions will satisfy; if an even number of version numbers are given, the last one is an -upper limit on acceptable version numbers. For example, the line: - -``` -Distributions 0.1 -``` - -is satisfied by any version of `Distributions` greater than or equal to `0.1.0`. Suffixing a version -with `-` allows any pre-release versions as well. For example: - -``` -Distributions 0.1- -``` - -is satisfied by pre-release versions such as `0.1-dev` or `0.1-rc1`, or by any version greater -than or equal to `0.1.0`. - -This requirement entry: - -``` -Distributions 0.1 0.2.5 -``` - -is satisfied by versions from `0.1.0` up to, but not including `0.2.5`. If you want to indicate -that any `0.1.x` version will do, you will want to write: - -``` -Distributions 0.1 0.2- -``` - -If you want to start accepting versions after `0.2.7`, you can write: - -``` -Distributions 0.1 0.2- 0.2.7 -``` - -If a requirement line has leading words that begin with `@`, it is a system-dependent requirement. -If your system matches these system conditionals, the requirement is included, if not, the requirement -is ignored. For example: - -``` -@osx Homebrew -``` - -will require the `Homebrew` package only on systems where the operating system is OS X. The system -conditions that are currently supported are (hierarchically): - - * `@unix` - - * `@linux` - * `@bsd` - - * `@osx` - * `@windows` - -The `@unix` condition is satisfied on all UNIX systems, including Linux and BSD. Negated system -conditionals are also supported by adding a `!` after the leading `@`. Examples: - -``` -@!windows -@unix @!osx -``` - -The first condition applies to any system but Windows and the second condition applies to any -UNIX system besides OS X. - -Runtime checks for the current version of Julia can be made using the built-in `VERSION` variable, -which is of type [`VersionNumber`](@ref). Such code is occasionally necessary to keep track of new or -deprecated functionality between various releases of Julia. Examples of runtime checks: - -```julia -VERSION < v"0.3-" #exclude all pre-release versions of 0.3 - -v"0.2-" <= VERSION < v"0.3-" #get all 0.2 versions, including pre-releases, up to the above - -v"0.2" <= VERSION < v"0.3-" #To get only stable 0.2 versions (Note v"0.2" == v"0.2.0") - -VERSION >= v"0.2.1" #get at least version 0.2.1 -``` - -See the section on [version number literals](@ref man-version-number-literals) for a more complete description. diff --git a/codex/manual/parallel-computing.md b/codex/manual/parallel-computing.md index 82cb498..640a3e3 100644 --- a/codex/manual/parallel-computing.md +++ b/codex/manual/parallel-computing.md @@ -457,7 +457,7 @@ we could compute the singular values of several large random matrices in paralle ```julia-repl julia> M = Matrix{Float64}[rand(1000,1000) for i = 1:10]; -julia> pmap(svd, M); +julia> pmap(svdvals, M); ``` Julia's [`pmap`](@ref) is designed for the case where each function call does a large amount @@ -486,7 +486,7 @@ As an example, consider computing the singular values of matrices of different s ```julia-repl julia> M = Matrix{Float64}[rand(800,800), rand(600,600), rand(800,800), rand(600,600)]; -julia> pmap(svd, M); +julia> pmap(svdvals, M); ``` If one process handles both 800×800 matrices and another handles both 600×600 matrices, we will diff --git a/codex/manual/performance-tips.md b/codex/manual/performance-tips.md index ff8ecd5..1ecac2d 100644 --- a/codex/manual/performance-tips.md +++ b/codex/manual/performance-tips.md @@ -544,7 +544,7 @@ function norm(A) if isa(A, Vector) return sqrt(real(dot(A,A))) elseif isa(A, Matrix) - return maximum(svd(A)[2]) + return maximum(svdvals(A)) else error("norm: invalid argument") end @@ -555,7 +555,7 @@ This can be written more concisely and efficiently as: ```julia norm(x::Vector) = sqrt(real(dot(x,x))) -norm(A::Matrix) = maximum(svd(A)[2]) +norm(A::Matrix) = maximum(svdvals(A)) ``` ## Write "type-stable" functions diff --git a/codex/stdlib/LinearAlgebra.md b/codex/stdlib/LinearAlgebra.md index 8ccffe5..a78fdfa 100644 --- a/codex/stdlib/LinearAlgebra.md +++ b/codex/stdlib/LinearAlgebra.md @@ -198,7 +198,7 @@ Legend: ### Matrix factorizations -| Matrix type | LAPACK | [`eig`](@ref) | [`eigvals`](@ref) | [`eigvecs`](@ref) | [`svd`](@ref) | [`svdvals`](@ref) | +| Matrix type | LAPACK | [`eigen`](@ref) | [`eigvals`](@ref) | [`eigvecs`](@ref) | [`svd`](@ref) | [`svdvals`](@ref) | |:------------------------- |:------ |:------------- |:----------------- |:----------------- |:------------- |:----------------- | | [`Symmetric`](@ref) | SY | | ARI | | | | | [`Hermitian`](@ref) | HE | | ARI | | | | @@ -312,47 +312,40 @@ LinearAlgebra.LowerTriangular LinearAlgebra.UpperTriangular LinearAlgebra.UniformScaling LinearAlgebra.lu -LinearAlgebra.lufact -LinearAlgebra.lufact! +LinearAlgebra.lu! LinearAlgebra.chol -LinearAlgebra.cholfact -LinearAlgebra.cholfact! +LinearAlgebra.cholesky +LinearAlgebra.cholesky! LinearAlgebra.lowrankupdate LinearAlgebra.lowrankdowndate LinearAlgebra.lowrankupdate! LinearAlgebra.lowrankdowndate! -LinearAlgebra.ldltfact -LinearAlgebra.ldltfact! +LinearAlgebra.ldlt +LinearAlgebra.ldlt! LinearAlgebra.qr LinearAlgebra.qr! -LinearAlgebra.qrfact -LinearAlgebra.qrfact! LinearAlgebra.QR LinearAlgebra.QRCompactWY LinearAlgebra.QRPivoted -LinearAlgebra.lqfact! -LinearAlgebra.lqfact +LinearAlgebra.lq! LinearAlgebra.lq -LinearAlgebra.bkfact -LinearAlgebra.bkfact! -LinearAlgebra.eig +LinearAlgebra.bunchkaufman +LinearAlgebra.bunchkaufman! LinearAlgebra.eigvals LinearAlgebra.eigvals! LinearAlgebra.eigmax LinearAlgebra.eigmin LinearAlgebra.eigvecs -LinearAlgebra.eigfact -LinearAlgebra.eigfact! -LinearAlgebra.hessfact -LinearAlgebra.hessfact! -LinearAlgebra.schurfact -LinearAlgebra.schurfact! +LinearAlgebra.eigen +LinearAlgebra.eigen! +LinearAlgebra.hessenberg +LinearAlgebra.hessenberg! +LinearAlgebra.schur! LinearAlgebra.schur LinearAlgebra.ordschur LinearAlgebra.ordschur! -LinearAlgebra.svdfact -LinearAlgebra.svdfact! LinearAlgebra.svd +LinearAlgebra.svd! LinearAlgebra.svdvals LinearAlgebra.svdvals! LinearAlgebra.Givens diff --git a/codex/stdlib/Pkg.md b/codex/stdlib/Pkg.md index 47f3f96..9d8651a 100644 --- a/codex/stdlib/Pkg.md +++ b/codex/stdlib/Pkg.md @@ -1,38 +1,411 @@ -# Package Manager Functions - -```@meta -DocTestSetup = :(using Pkg) -``` - -All package manager functions are defined in the `Pkg` module. None of the `Pkg` module's functions -are exported; to use them, you'll need to prefix each function call with an explicit `Pkg.`, e.g. -[`Pkg.status()`](@ref) or [`Pkg.dir()`](@ref). - -Functions for package development (e.g. `tag`, `publish`, etc.) have been moved to the [PkgDev](https://github.com/JuliaLang/PkgDev.jl) -package. See [PkgDev README](https://github.com/JuliaLang/PkgDev.jl/blob/master/README.md) for -the documentation of those functions. - -```@docs -Pkg.dir -Pkg.init -Pkg.resolve -Pkg.edit -Pkg.add -Pkg.rm -Pkg.clone -Pkg.setprotocol! -Pkg.available -Pkg.installed -Pkg.status -Pkg.update -Pkg.checkout -Pkg.pin -Pkg.free -Pkg.build -Pkg.test -Pkg.dependents -``` - -```@meta -DocTestSetup = nothing +# Pkg + +!!! warning + This documentation is a work in progress and the information in it might be or become outdated. + +## Introduction + +Pkg is the standard package manager for Julia 1.0 and newer. Unlike traditional +package managers, which install and manage a single global set of packages, Pkg +is designed around “environments”: independent sets of packages that can be +local to an individual project or shared and selected by name. The exact set of +packages and versions in an environment is captured in a _manifest file_ which +can be checked into a project repository and tracked in version control, +significantly improving reproducibility of projects. If you’ve ever tried to run +code you haven’t used in a while only to find that you can’t get anything to +work because you’ve updated or uninstalled some of the packages your project was +using, you’ll understand the motivation for this approach. In Pkg, since each +project maintains its own independent set of package versions, you’ll never have +this problem again. Moreover, if you check out a project on a new system, you +can simply materialize the environment described by its manifest file and +immediately be up and running with a known-good set of dependencies. + +Since environments are managed and updated independently from each other, +“dependency hell” is significantly alleviated in Pkg. If you want to use the +latest and greatest version of some package in a new project but you’re stuck on +an older version in a different project, that’s no problem – since they have +separate environments they can just use different versions, which are both +installed at the same time in different locations on your system. The location +of each package version is canonical, so when environments use the same versions +of packages, they can share installations, avoiding unnecessary duplication of +the package. Old package versions that are no longer used by any environments +are periodically “garbage collected” by the package manager. + +Pkg’s approach to local environments may be familiar to people who have used +Python’s `virtualenv` or Ruby’s `bundler`. In Julia, instead of hacking the +language’s code loading mechanisms to support environments, we have the benefit +that Julia natively understands them. In addition, Julia environments are +“stackable”: you can overlay one environment with another and thereby have +access to additional packages outside of the primary environment. This makes it +easy to work on a project, which provides the primary environment, while still +having access to all your usual dev tools like profilers, debuggers, and so on, +just by having an environment including these dev tools later in the load path. + +Last but not least, Pkg is designed to support federated package registries. +This means that it allows multiple registries managed by different parties to +interact seamlessly. In particular, this includes private registries which can +live behind corporate firewalls. You can install and update your own packages +from a private registry with exactly the same tools and workflows that you use +to install and manage official Julia packages. If you urgently need to apply a +hotfix for a public package that’s critical to your company’s product, you can +tag a private version of it in your company’s internal registry and get a fix to +your developers and ops teams quickly and easily without having to wait for an +upstream patch to be accepted and published. Once an official fix is published, +however, you can just upgrade your dependencies and you'll be back on an +official release again. + +## Glossary + +**Project:** a source tree with a standard layout, including a `src` directory +for the main body of Julia code, a `test` directory for testing the project, +`docs` for documentation files, and optionally a `build` directory for a build +script and its outputs. A project will typically also have a project file and +may optionally have a manifest file: + +- **Project file:** a file in the root directory of a project, named + `Project.toml` (or `JuliaProject.toml`) describing metadata about the project, + including its name, UUID (for packages), authors, license, and the names and + UUIDs of packages and libraries that it depends on. + +- **Manifest file:** a file in the root directory of a project, named + `Manifest.toml` (or `JuliaManifest.toml`) describing a complete dependency graph + and exact versions of each package and library used by a project. + +**Package:** a project which provides reusable functionality that can be used by +other Julia projects via `import X` or `using X`. A package should have a +project file with a `uuid` entry giving its package UUID. This UUID is used to +identify the package in projects that depend on it. + +!!! note + For legacy reasons it is possible to load a package without a project file or + UUID from the REPL or the top-level of a script. It is not possible, however, + to load a package without a project file or UUID from a project with them. Once + you've loaded from a project file, everything needs a project file and UUID. + +**Application:** a project which provides standalone functionality not intended +to be reused by other Julia projects. For example a web application or a +commmand-line utility. An application may have a UUID but does not need one. An +application may also provide global configuration options for packages it +depends on. Packages, on the other hand, may not provide global configuration +since that could conflict with the configuration of the main application. + +!!! note + **Projects _vs._ Packages _vs._ Applications:** + + 1. Project is an umbrella term: packages and applications are kinds of projects. + 2. Packages should have UUIDs, applications can have a UUIDs but don't need them. + 3. Applications can provide global configuration, whereas packages cannot. + +**Library (future work):** a compiled binary dependency (not written in Julia) +packaged to be used by a Julia project. These are currently typically built in- +place by a `deps/build.jl` script in a project’s source tree, but in the future +we plan to make libraries first-class entities directly installed and upgraded +by the package manager. + +**Environment:** the combination of the top-level name map provided by a project +file combined with the dependency graph and map from packages to their entry points +provided by a manifest file. For more detail see the manual section on code loading. + +- **Explicit environment:** an environment in the form of an explicit project + file and an optional corresponding manifest file together in a directory. If the + manifest file is absent then the implied dependency graph and location maps are + empty. + +- **Implicit environment:** an environment provided as a directory (without a + project file or manifest file) containing packages with entry points of the form + `X.jl`, `X.jl/src/X.jl` or `X/src/X.jl`. The top-level name map is implied by + these entry points. The dependency graph is implied by the existence of project + files inside of these package directories, e.g. `X.jl/Project.toml` or + `X/Project.toml`. The dependencies of the `X` package are the dependencies in + the corresponding project file if there is one. The location map is implied by + the entry points themselves. + +**Registry:** a source tree with a standard layout recording metadata about a +registered set of packages, the tagged versions of them which are available, and +which versions of packages are compatible or incompatible with each other. A +registry is indexed by package name and UUID, and has a directory for each +registered package providing the following metadata about it: + +- name – e.g. `DataFrames` +- UUID – e.g. `a93c6f00-e57d-5684-b7b6-d8193f3e46c0` +- authors – e.g. `Jane Q. Developer ` +- license – e.g. MIT, BSD3, or GPLv2 +- repository – e.g. `https://github.com/JuliaData/DataFrames.jl.git` +- description – a block of text summarizing the functionality of a package +- keywords – e.g. `data`, `tabular`, `analysis`, `statistics` +- versions – a list of all registered version tags + +For each registered version of a package, the following information is provided: + +- its semantic version number – e.g. `v1.2.3` +- its git tree SHA-1 hash – e.g. `7ffb18ea3245ef98e368b02b81e8a86543a11103` +- a map from names to UUIDs of dependencies +- which versions of other packages it is compatible/incompatible with + +Dependencies and compatibility are stored in a compressed but human-readable +format using ranges of package versions. + +**Depot:** a directory on a system where various package-related resources live, +including: + +- `environments`: shared named environments (e.g. `v0.7`, `devtools`) +- `clones`: bare clones of package repositories +- `compiled`: cached compiled package images (`.ji` files) +- `config`: global configuration files (e.g. `startup.jl`) +- `dev`: default directory for package development +- `logs`: log files (e.g. `manifest_usage.toml`, `repl_history.jl`) +- `packages`: installed package versions +- `registries`: clones of registries (e.g. `Uncurated`) + +**Load path:** a stack of environments where package identities, their +dependencies, and entry-points are searched for. The load path is controlled in +Julia by the `LOAD_PATH` global variable which is populated at startup based on +the value of the `JULIA_LOAD_PATH` environment variable. The first entry is your +primary environment, often the current project, while later entries provide +additional packages one may want to use from the REPL or top-level scripts. + +**Depot path:** a stack of depot locations where the package manager, as well as +Julia's code loading mechanisms, look for registries, installed packages, named +environments, repo clones, cached compiled package images, and configuration +files. The depot path is controlled by the Julia `DEPOT_PATH` global variable +which is populated at startup based on the value of the `JULIA_DEPOT_PATH` +environment variable. The first entry is the “user depot” and should be writable +by and owned by the current user. The user depot is where: registries are +cloned, new package versions are installed, named environments are created and +updated, package repos are cloned, new compiled package image files are saved, +log files are written, development packages are checked out by default, and +global configuration data is saved. Later entries in the depot path are treated +as read-only and are appropriate for registries, packages, etc. installed and +managed by system administrators. + +## Getting Started + +The Pkg REPL-mode is entered from the Julia REPL using the key `]`. + +``` +(v0.7) pkg> +``` + +The part inside the parenthesis of the prompt shows the name of the current project. +Since we haven't created our own project yet, we are in the default project, located at `~/.julia/environments/v0.7` +(or whatever version of Julia you happen to run). + +To return to the `julia>` prompt, either press backspace when the input line is empty or press Ctrl+C. +Help is available by calling `pkg> help`. + +To generate files for a new project, use `pkg> generate`. + +``` +(v0.7) pkg> generate HelloWorld +``` + +This creates a new project `HelloWorld` with the following files (visualized with the external [`tree` command](https://linux.die.net/man/1/tree)): + +```jl +julia> cd("HelloWorld") +shell> tree . +. +├── Project.toml +└── src + └── HelloWorld.jl + +1 directory, 2 files ``` + +The `Project.toml` file contains the name of the package, its unique UUID, its version, the author and eventual dependencies: + +```toml +name = "HelloWorld" +uuid = "b4cd1eb8-1e24-11e8-3319-93036a3eb9f3" +version = "0.1.0" +author = ["Some One "] + +[deps] +``` + +The content of `src/HelloWorld.jl` is: + +```jl +module HelloWorld + +greet() = print("Hello World!") + +end # module +``` + +We can now load the project and use it: + +```jl +julia> import HelloWorld + +julia> HelloWorld.greet() +Hello World! +``` + +### Adding packages to the project + +Let’s say we want to use the standard library package `Random` and the registered package `JSON` in our project. +We simply `add` these packages (note how the prompt now shows the name of the newly generated project, +since we are inside the `HelloWorld` project directory): + +``` +(HelloWorld) pkg> add Random JSON + Resolving package versions... + Updating "~/Documents/HelloWorld/Project.toml" + [682c06a0] + JSON v0.17.1 + [9a3f8284] + Random + Updating "~/Documents/HelloWorld/Manifest.toml" + [34da2185] + Compat v0.57.0 + [682c06a0] + JSON v0.17.1 + [4d1e1d77] + Nullables v0.0.4 + ... +``` + +Both `Random` and `JSON` got added to the project’s `Project.toml` file, and the resulting dependencies got added to the `Manifest.toml` file. +The resolver has installed each package with the highest possible version, while still respecting the compatibility that each package enforce on its dependencies. + +We can now use both `Random` and `JSON` in our project. Changing `src/HelloWorld.jl` to + +``` +module HelloWorld + +import Random +import JSON + +greet() = print("Hello World!") +greet_alien() = print("Hello ", Random.randstring(8)) + +end # module +``` + +and reloading the package, the new `greet_alien` function that uses `Random` can be used: + +``` +julia> HelloWorld.greet_alien() +Hello aT157rHV +``` + +Sometimes we might want to use the very latest, unreleased version of a package, or perhaps a specific branch in the package +git repository. We can use e.g. the `master` branch of `JSON` by specifying the branch after a `#` when adding the package: + +``` +(HelloWorld) pkg> add JSON#master + Cloning package from https://github.com/JuliaIO/JSON.jl.git + Resolving package versions... + Updating "~/Documents/HelloWorld/Project.toml" + [682c06a0] ~ JSON v0.17.1 ⇒ v0.17.1+ #master + Updating "~/Documents/HelloWorld/Manifest.toml" + [682c06a0] ~ JSON v0.17.1 ⇒ v0.17.1+ #master +``` + +If we want to use a package that has not been registered in a registry, we can `add` its git repository url: + +``` +(HelloWorld) pkg> add https://github.com/fredrikekre/ImportMacros.jl + Cloning package from https://github.com/fredrikekre/ImportMacros.jl + Resolving package versions... +Downloaded MacroTools ─ v0.4.0 + Updating "~/Documents/HelloWorld/Project.toml" + [5adcef86] + ImportMacros v0.1.0 #master + Updating "~/Documents/HelloWorld/Manifest.toml" + [5adcef86] + ImportMacros v0.1.0 #master + [1914dd2f] + MacroTools v0.4.0 +``` + +The dependencies of the unregistered package (here `MacroTools`) got installed. +For unregistered packages we could have given a branch (or commit SHA) to track using `#`, just like for registered packages. + + +## Developing packages + +Let’s say we found a bug in one of our dependencies, e.g. `JSON` that we want to fix. We can get the full git-repo using the `develop` command + +``` +(HelloWorld) pkg> develop JSON + Cloning package from https://github.com/JuliaIO/JSON.jl.git + Resolving package versions... + Updating "~/Documents/HelloWorld/Project.toml" + [682c06a0] + JSON v0.17.1+ [~/.julia/dev/JSON] +... +``` + +By default, the package get cloned to the `~/.julia/dev` folder but can also be set by the `JULIA_PKG_DEVDIR` environment variable. +When we have fixed the bug and checked that `JSON` now works correctly with our project, we can make a PR to the `JSON` repository. +When the PR has been merged we can go over to track the master branch and finally, when a new release of `JSON` is made, we can go back to using the versioned `JSON` using the command `free` and `update` (see next section): + +``` +(HelloWorld) pkg> free JSON + Resolving package versions... + Updating "~/Documents/HelloWorld/Project.toml" + [682c06a0] ~ JSON v0.17.1+ #master ⇒ v0.17.1 + Updating "~/Documents/HelloWorld/Manifest.toml" + [682c06a0] ~ JSON v0.17.1+ #master ⇒ v0.17.1 +``` + +It is also possible to give a local path as the argument to `develop` which will not clone anything but simply use that directory for the package. + +Overriding the dependency path for a non registered package is done by giving the git-repo url as an argument to `develop`. + +## Updating dependencies + +When new versions of packages the project is using are released, it is a good idea to update. Simply calling `up` will try to update *all* the dependencies of the project. Sometimes this is not what you want. You can specify a subset of the dependencies to upgrade by giving them as arguments to `up`, e.g: + +``` +(HelloWorld) pkg> up JSON +``` + +The version of all other direct dependencies will stay the same. If you only want to update the minor version of packages, to reduce the risk that your project breaks, you can give the `--minor` flag, e.g: + +``` +(HelloWorld) pkg> up --minor JSON +``` + +Packages that track a branch are not updated when a minor upgrade is done. +Developed packages are never touched by the package manager. + +If you just want install the packages that are given by the current `Manifest.toml` use + +``` +(HelloWorld) pkg> instantiate +``` + +## Precompiling the project + +The REPL command `precompile` can be used to precompile all the dependencies in the project. You can for example do + +``` +(HelloWorld) pkg> update; precompile +``` + +do update the dependencies and then precompile them. + +## Preview mode + +If you just want to see the effects of running a command, but not change your state you can `preview` a command. +For example: + +``` +(HelloWorld) pkg> preview add Plots +``` + +or + +``` +(HelloWorld) pkg> preview up +``` + +will show you the effects adding `Plots`, or doing a full upgrade, respectively, would have on your project. +However, nothing would be installed and your `Project.toml` and `Manfiest.toml` are untouched. + +## Using someone elses project + +Simple clone their project using e.g. `git clone`, `cd` to the project directory and call + +``` +(SomeProject) pkg> instantiate +``` + +If the project contains a manifest, this will install the packages at the same state that is given by that manifest. +Otherwise it will resolve the latest versions of the dependencies compatible with the project. + + diff --git a/codex/stdlib/Pkg3.md b/codex/stdlib/Pkg3.md deleted file mode 100644 index 26e98f8..0000000 --- a/codex/stdlib/Pkg3.md +++ /dev/null @@ -1,418 +0,0 @@ -# Pkg3.jl - -!!! warning - This documentation is a work in progress and the information in it might be or become outdated. - -Sections: - -```@contents -Pages = [ - "index.md"] -``` - -## Introduction - -Pkg3 is the standard package manager for Julia 1.0 and newer. Unlike traditional -package managers, which install and manage a single global set of packages, Pkg3 -is designed around “environments”: independent sets of packages that can be -local to an individual project or shared and selected by name. The exact set of -packages and versions in an environment is captured in a _manifest file_ which -can be checked into a project repository and tracked in version control, -significantly improving reproducibility of projects. If you’ve ever tried to run -code you haven’t used in a while only to find that you can’t get anything to -work because you’ve updated or uninstalled some of the packages your project was -using, you’ll understand the motivation for this approach. In Pkg3, since each -project maintains its own independent set of package versions, you’ll never have -this problem again. Moreover, if you check out a project on a new system, you -can simply materialize the environment described by its manifest file and -immediately be up and running with a known-good set of dependencies. - -Since environments are managed and updated independently from each other, -“dependency hell” is significantly alleviated in Pkg3. If you want to use the -latest and greatest version of some package in a new project but you’re stuck on -an older version in a different project, that’s no problem – since they have -separate environments they can just use different versions, which are both -installed at the same time in different locations on your system. The location -of each package version is canonical, so when environments use the same versions -of packages, they can share installations, avoiding unnecessary duplication of -the package. Old package versions that are no longer used by any environments -are periodically “garbage collected” by the package manager. - -Pkg3’s approach to local environments may be familiar to people who have used -Python’s `virtualenv` or Ruby’s `bundler`. In Julia, instead of hacking the -language’s code loading mechanisms to support environments, we have the benefit -that Julia natively understands them. In addition, Julia environments are -“stackable”: you can overlay one environment with another and thereby have -access to additional packages outside of the primary environment. This makes it -easy to work on a project, which provides the primary environment, while still -having access to all your usual dev tools like profilers, debuggers, and so on, -just by having an environment including these dev tools later in the load path. - -Last but not least, Pkg3 is designed to support federated package registries. -This means that it allows multiple registries managed by different parties to -interact seamlessly. In particular, this includes private registries which can -live behind corporate firewalls. You can install and update your own packages -from a private registry with exactly the same tools and workflows that you use -to install and manage official Julia packages. If you urgently need to apply a -hotfix for a public package that’s critical to your company’s product, you can -tag a private version of it in your company’s internal registry and get a fix to -your developers and ops teams quickly and easily without having to wait for an -upstream patch to be accepted and published. Once an official fix is published, -however, you can just upgrade your dependencies and you'll be back on an -official release again. - -## Glossary - -**Project:** a source tree with a standard layout, including a `src` directory -for the main body of Julia code, a `test` directory for testing the project, -`docs` for documentation files, and optionally a `build` directory for a build -script and its outputs. A project will typically also have a project file and -may optionally have a manifest file: - -- **Project file:** a file in the root directory of a project, named - `Project.toml` (or `JuliaProject.toml`) describing metadata about the project, - including its name, UUID (for packages), authors, license, and the names and - UUIDs of packages and libraries that it depends on. - -- **Manifest file:** a file in the root directory of a project, named - `Manifest.toml` (or `JuliaManifest.toml`) describing a complete dependency graph - and exact versions of each package and library used by a project. - -**Package:** a project which provides reusable functionality that can be used by -other Julia projects via `import X` or `using X`. A package should have a -project file with a `uuid` entry giving its package UUID. This UUID is used to -identify the package in projects that depend on it. - -!!! note - For legacy reasons it is possible to load a package without a project file or - UUID from the REPL or the top-level of a script. It is not possible, however, - to load a package without a project file or UUID from a project with them. Once - you've loaded from a project file, everything needs a project file and UUID. - -**Application:** a project which provides standalone functionality not intended -to be reused by other Julia projects. For example a web application or a -commmand-line utility. An application may have a UUID but does not need one. An -application may also provide global configuration options for packages it -depends on. Packages, on the other hand, may not provide global configuration -since that could conflict with the configuration of the main application. - -!!! note - **Projects _vs._ Packages _vs._ Applications:** - - 1. Project is an umbrella term: packages and applications are kinds of projects. - 2. Packages should have UUIDs, applications can have a UUIDs but don't need them. - 3. Applications can provide global configuration, whereas packages cannot. - -**Library (future work):** a compiled binary dependency (not written in Julia) -packaged to be used by a Julia project. These are currently typically built in- -place by a `deps/build.jl` script in a project’s source tree, but in the future -we plan to make libraries first-class entities directly installed and upgraded -by the package manager. - -**Environment:** the combination of the top-level name map provided by a project -file combined with the dependency graph and map from packages to their entry points -provided by a manifest file. For more detail see the manual section on code loading. - -- **Explicit environment:** an environment in the form of an explicit project - file and an optional corresponding manifest file together in a directory. If the - manifest file is absent then the implied dependency graph and location maps are - empty. - -- **Implicit environment:** an environment provided as a directory (without a - project file or manifest file) containing packages with entry points of the form - `X.jl`, `X.jl/src/X.jl` or `X/src/X.jl`. The top-level name map is implied by - these entry points. The dependency graph is implied by the existence of project - files inside of these package directories, e.g. `X.jl/Project.toml` or - `X/Project.toml`. The dependencies of the `X` package are the dependencies in - the corresponding project file if there is one. The location map is implied by - the entry points themselves. - -**Registry:** a source tree with a standard layout recording metadata about a -registered set of packages, the tagged versions of them which are available, and -which versions of packages are compatible or incompatible with each other. A -registry is indexed by package name and UUID, and has a directory for each -registered package providing the following metadata about it: - -- name – e.g. `DataFrames` -- UUID – e.g. `a93c6f00-e57d-5684-b7b6-d8193f3e46c0` -- authors – e.g. `Jane Q. Developer ` -- license – e.g. MIT, BSD3, or GPLv2 -- repository – e.g. `https://github.com/JuliaData/DataFrames.jl.git` -- description – a block of text summarizing the functionality of a package -- keywords – e.g. `data`, `tabular`, `analysis`, `statistics` -- versions – a list of all registered version tags - -For each registered version of a package, the following information is provided: - -- its semantic version number – e.g. `v1.2.3` -- its git tree SHA-1 hash – e.g. `7ffb18ea3245ef98e368b02b81e8a86543a11103` -- a map from names to UUIDs of dependencies -- which versions of other packages it is compatible/incompatible with - -Dependencies and compatibility are stored in a compressed but human-readable -format using ranges of package versions. - -**Depot:** a directory on a system where various package-related resources live, -including: - -- `environments`: shared named environments (e.g. `v0.7`, `devtools`) -- `clones`: bare clones of package repositories -- `compiled`: cached compiled package images (`.ji` files) -- `config`: global configuration files (e.g. `startup.jl`) -- `dev`: default directory for package development -- `logs`: log files (e.g. `manifest_usage.toml`, `repl_history.jl`) -- `packages`: installed package versions -- `registries`: clones of registries (e.g. `Uncurated`) - -**Load path:** a stack of environments where package identities, their -dependencies, and entry-points are searched for. The load path is controlled in -Julia by the `LOAD_PATH` global variable which is populated at startup based on -the value of the `JULIA_LOAD_PATH` environment variable. The first entry is your -primary environment, often the current project, while later entries provide -additional packages one may want to use from the REPL or top-level scripts. - -**Depot path:** a stack of depot locations where the package manager, as well as -Julia's code loading mechanisms, look for registries, installed packages, named -environments, repo clones, cached compiled package images, and configuration -files. The depot path is controlled by the Julia `DEPOT_PATH` global variable -which is populated at startup based on the value of the `JULIA_DEPOT_PATH` -environment variable. The first entry is the “user depot” and should be writable -by and owned by the current user. The user depot is where: registries are -cloned, new package versions are installed, named environments are created and -updated, package repos are cloned, new compiled package image files are saved, -log files are written, development packages are checked out by default, and -global configuration data is saved. Later entries in the depot path are treated -as read-only and are appropriate for registries, packages, etc. installed and -managed by system administrators. - -## Getting Started - -The Pkg REPL-mode is entered from the Julia REPL using the key `]`. - -``` -(v0.7) pkg> -``` - -The part inside the parenthesis of the prompt shows the name of the current project. -Since we haven't created our own project yet, we are in the default project, located at `~/.julia/environments/v0.7` -(or whatever version of Julia you happen to run). - -To return to the `julia>` prompt, either press backspace when the input line is empty or press Ctrl+C. -Help is available by calling `pkg> help`. - -To generate files for a new project, use `pkg> generate`. - -``` -(v0.7) pkg> generate HelloWorld -``` - -This creates a new project `HelloWorld` with the following files (visualized with the external [`tree` command](https://linux.die.net/man/1/tree)): - -```jl -julia> cd("HelloWorld") -shell> tree . -. -├── Project.toml -└── src - └── HelloWorld.jl - -1 directory, 2 files -``` - -The `Project.toml` file contains the name of the package, its unique UUID, its version, the author and eventual dependencies: - -```toml -name = "HelloWorld" -uuid = "b4cd1eb8-1e24-11e8-3319-93036a3eb9f3" -version = "0.1.0" -author = ["Some One "] - -[deps] -``` - -The content of `src/HelloWorld.jl` is: - -```jl -module HelloWorld - -greet() = print("Hello World!") - -end # module -``` - -We can now load the project and use it: - -```jl -julia> import HelloWorld - -julia> HelloWorld.greet() -Hello World! -``` - -### Adding packages to the project - -Let’s say we want to use the standard library package `Random` and the registered package `JSON` in our project. -We simply `add` these packages (note how the prompt now shows the name of the newly generated project, -since we are inside the `HelloWorld` project directory): - -``` -(HelloWorld) pkg> add Random JSON - Resolving package versions... - Updating "~/Documents/HelloWorld/Project.toml" - [682c06a0] + JSON v0.17.1 - [9a3f8284] + Random - Updating "~/Documents/HelloWorld/Manifest.toml" - [34da2185] + Compat v0.57.0 - [682c06a0] + JSON v0.17.1 - [4d1e1d77] + Nullables v0.0.4 - ... -``` - -Both `Random` and `JSON` got added to the project’s `Project.toml` file, and the resulting dependencies got added to the `Manifest.toml` file. -The resolver has installed each package with the highest possible version, while still respecting the compatibility that each package enforce on its dependencies. - -We can now use both `Random` and `JSON` in our project. Changing `src/HelloWorld.jl` to - -``` -module HelloWorld - -import Random -import JSON - -greet() = print("Hello World!") -greet_alien() = print("Hello ", Random.randstring(8)) - -end # module -``` - -and reloading the package, the new `greet_alien` function that uses `Random` can be used: - -``` -julia> HelloWorld.greet_alien() -Hello aT157rHV -``` - -Sometimes we might want to use the very latest, unreleased version of a package, or perhaps a specific branch in the package -git repository. We can use e.g. the `master` branch of `JSON` by specifying the branch after a `#` when adding the package: - -``` -(HelloWorld) pkg> add JSON#master - Cloning package from https://github.com/JuliaIO/JSON.jl.git - Resolving package versions... - Updating "~/Documents/HelloWorld/Project.toml" - [682c06a0] ~ JSON v0.17.1 ⇒ v0.17.1+ #master - Updating "~/Documents/HelloWorld/Manifest.toml" - [682c06a0] ~ JSON v0.17.1 ⇒ v0.17.1+ #master -``` - -If we want to use a package that has not been registered in a registry, we can `add` its git repository url: - -``` -(HelloWorld) pkg> add https://github.com/fredrikekre/ImportMacros.jl - Cloning package from https://github.com/fredrikekre/ImportMacros.jl - Resolving package versions... -Downloaded MacroTools ─ v0.4.0 - Updating "~/Documents/HelloWorld/Project.toml" - [5adcef86] + ImportMacros v0.1.0 #master - Updating "~/Documents/HelloWorld/Manifest.toml" - [5adcef86] + ImportMacros v0.1.0 #master - [1914dd2f] + MacroTools v0.4.0 -``` - -The dependencies of the unregistered package (here `MacroTools`) got installed. -For unregistered packages we could have given a branch (or commit SHA) to track using `#`, just like for registered packages. - - -## Developing packages - -Let’s say we found a bug in one of our dependencies, e.g. `JSON` that we want to fix. We can get the full git-repo using the `develop` command - -``` -(HelloWorld) pkg> develop JSON - Cloning package from https://github.com/JuliaIO/JSON.jl.git - Resolving package versions... - Updating "~/Documents/HelloWorld/Project.toml" - [682c06a0] + JSON v0.17.1+ [~/.julia/dev/JSON] -... -``` - -By default, the package get cloned to the `~/.julia/dev` folder but can also be set by the `JULIA_PKG_DEVDIR` environment variable. -When we have fixed the bug and checked that `JSON` now works correctly with our project, we can make a PR to the `JSON` repository. -When the PR has been merged we can go over to track the master branch and finally, when a new release of `JSON` is made, we can go back to using the versioned `JSON` using the command `free` and `update` (see next section): - -``` -(HelloWorld) pkg> free JSON - Resolving package versions... - Updating "~/Documents/HelloWorld/Project.toml" - [682c06a0] ~ JSON v0.17.1+ #master ⇒ v0.17.1 - Updating "~/Documents/HelloWorld/Manifest.toml" - [682c06a0] ~ JSON v0.17.1+ #master ⇒ v0.17.1 -``` - -It is also possible to give a local path as the argument to `develop` which will not clone anything but simply use that directory for the package. - -Overriding the dependency path for a non registered package is done by giving the git-repo url as an argument to `develop`. - -## Updating dependencies - -When new versions of packages the project is using are released, it is a good idea to update. Simply calling `up` will try to update *all* the dependencies of the project. Sometimes this is not what you want. You can specify a subset of the dependencies to upgrade by giving them as arguments to `up`, e.g: - -``` -(HelloWorld) pkg> up JSON -``` - -The version of all other direct dependencies will stay the same. If you only want to update the minor version of packages, to reduce the risk that your project breaks, you can give the `--minor` flag, e.g: - -``` -(HelloWorld) pkg> up --minor JSON -``` - -Packages that track a branch are not updated when a minor upgrade is done. -Developed packages are never touched by the package manager. - -If you just want install the packages that are given by the current `Manifest.toml` use - -``` -(HelloWorld) pkg> instantiate -``` - -## Precompiling the project - -The REPL command `precompile` can be used to precompile all the dependencies in the project. You can for example do - -``` -(HelloWorld) pkg> update; precompile -``` - -do update the dependencies and then precompile them. - -## Preview mode - -If you just want to see the effects of running a command, but not change your state you can `preview` a command. -For example: - -``` -(HelloWorld) pkg> preview add Plots -``` - -or - -``` -(HelloWorld) pkg> preview up -``` - -will show you the effects adding `Plots`, or doing a full upgrade, respectively, would have on your project. -However, nothing would be installed and your `Project.toml` and `Manfiest.toml` are untouched. - -## Using someone elses project - -Simple clone their project using e.g. `git clone`, `cd` to the project directory and call - -``` -(SomeProject) pkg> instantiate -``` - -If the project contains a manifest, this will install the packages at the same state that is given by that manifest. -Otherwise it will resolve the latest versions of the dependencies compatible with the project. - - diff --git a/codex/stdlib/REPL.md b/codex/stdlib/REPL.md index d9080cf..59494a4 100644 --- a/codex/stdlib/REPL.md +++ b/codex/stdlib/REPL.md @@ -306,8 +306,10 @@ completion to be able to remove non-matching methods. Tab completion can also help completing fields: ```julia-repl -julia> Pkg.a[TAB] -add available +julia> import UUIDs + +julia> UUIDs.uuid[TAB] +uuid1 uuid4 uuid_version ``` Fields for output from functions can also be completed: diff --git a/codex/stdlib/linearalgebra.md b/codex/stdlib/linearalgebra.md index 8ccffe5..a78fdfa 100644 --- a/codex/stdlib/linearalgebra.md +++ b/codex/stdlib/linearalgebra.md @@ -198,7 +198,7 @@ Legend: ### Matrix factorizations -| Matrix type | LAPACK | [`eig`](@ref) | [`eigvals`](@ref) | [`eigvecs`](@ref) | [`svd`](@ref) | [`svdvals`](@ref) | +| Matrix type | LAPACK | [`eigen`](@ref) | [`eigvals`](@ref) | [`eigvecs`](@ref) | [`svd`](@ref) | [`svdvals`](@ref) | |:------------------------- |:------ |:------------- |:----------------- |:----------------- |:------------- |:----------------- | | [`Symmetric`](@ref) | SY | | ARI | | | | | [`Hermitian`](@ref) | HE | | ARI | | | | @@ -312,47 +312,40 @@ LinearAlgebra.LowerTriangular LinearAlgebra.UpperTriangular LinearAlgebra.UniformScaling LinearAlgebra.lu -LinearAlgebra.lufact -LinearAlgebra.lufact! +LinearAlgebra.lu! LinearAlgebra.chol -LinearAlgebra.cholfact -LinearAlgebra.cholfact! +LinearAlgebra.cholesky +LinearAlgebra.cholesky! LinearAlgebra.lowrankupdate LinearAlgebra.lowrankdowndate LinearAlgebra.lowrankupdate! LinearAlgebra.lowrankdowndate! -LinearAlgebra.ldltfact -LinearAlgebra.ldltfact! +LinearAlgebra.ldlt +LinearAlgebra.ldlt! LinearAlgebra.qr LinearAlgebra.qr! -LinearAlgebra.qrfact -LinearAlgebra.qrfact! LinearAlgebra.QR LinearAlgebra.QRCompactWY LinearAlgebra.QRPivoted -LinearAlgebra.lqfact! -LinearAlgebra.lqfact +LinearAlgebra.lq! LinearAlgebra.lq -LinearAlgebra.bkfact -LinearAlgebra.bkfact! -LinearAlgebra.eig +LinearAlgebra.bunchkaufman +LinearAlgebra.bunchkaufman! LinearAlgebra.eigvals LinearAlgebra.eigvals! LinearAlgebra.eigmax LinearAlgebra.eigmin LinearAlgebra.eigvecs -LinearAlgebra.eigfact -LinearAlgebra.eigfact! -LinearAlgebra.hessfact -LinearAlgebra.hessfact! -LinearAlgebra.schurfact -LinearAlgebra.schurfact! +LinearAlgebra.eigen +LinearAlgebra.eigen! +LinearAlgebra.hessenberg +LinearAlgebra.hessenberg! +LinearAlgebra.schur! LinearAlgebra.schur LinearAlgebra.ordschur LinearAlgebra.ordschur! -LinearAlgebra.svdfact -LinearAlgebra.svdfact! LinearAlgebra.svd +LinearAlgebra.svd! LinearAlgebra.svdvals LinearAlgebra.svdvals! LinearAlgebra.Givens diff --git a/make.jl b/make.jl index 37b92e6..9cf68fa 100644 --- a/make.jl +++ b/make.jl @@ -61,7 +61,6 @@ const PAGES = [ "manual/handling-operating-system-variation.md", "manual/environment-variables.md", "manual/embedding.md", - "manual/packages.md", "manual/code-loading.md", "manual/profile.md", "manual/stacktraces.md", diff --git a/src/NEWS.md b/src/NEWS.md index bf48697..e1b3e36 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -207,6 +207,9 @@ Breaking changes This section lists changes that do not have deprecation warnings. + * The package manager `Pkg` has been replaced with a new one. See the manual entries on + "Code Loading" and "Pkg" for documentation. + * `replace(s::AbstractString, pat=>repl)` for function `repl` arguments formerly passed a substring to `repl` in all cases. It now passes substrings for string patterns `pat`, but a `Char` for character patterns (when `pat` is a @@ -215,6 +218,21 @@ This section lists changes that do not have deprecation warnings. * `readuntil` now does *not* include the delimiter in its result, matching the behavior of `readline`. Pass `keep=true` to get the old behavior ([#25633](https://github.com/JuliaLang/julia/issues/25633)). + * `lu` methods now return decomposition objects such as `LU` rather than + tuples of arrays or tuples of numbers ([#26997](https://github.com/JuliaLang/julia/issues/26997), [#27159](https://github.com/JuliaLang/julia/issues/27159), [#27212](https://github.com/JuliaLang/julia/issues/27212)). + + * `schur` methods now return decomposition objects such as `Schur` and + `GeneralizedSchur` rather than tuples of arrays ([#26997](https://github.com/JuliaLang/julia/issues/26997), [#27159](https://github.com/JuliaLang/julia/issues/27159), [#27212](https://github.com/JuliaLang/julia/issues/27212)). + + * `lq` methods now return decomposition objects such as `LQ` + rather than tuples of arrays ([#26997](https://github.com/JuliaLang/julia/issues/26997), [#27159](https://github.com/JuliaLang/julia/issues/27159), [#27212](https://github.com/JuliaLang/julia/issues/27212)). + + * `qr` methods now return decomposition objects such as `QR`, `QRPivoted`, + and `QRCompactWY` rather than tuples of arrays ([#26997](https://github.com/JuliaLang/julia/issues/26997), [#27159](https://github.com/JuliaLang/julia/issues/27159), [#27212](https://github.com/JuliaLang/julia/issues/27212)). + + * `svd` methods now return decomposition objects such as `SVD` and + `GeneralizedSVD` rather than tuples of arrays or tuples of numbers ([#26997](https://github.com/JuliaLang/julia/issues/26997), [#27159](https://github.com/JuliaLang/julia/issues/27159), [#27212](https://github.com/JuliaLang/julia/issues/27212)). + * `countlines` now always counts the last non-empty line even if it does not end with EOL, matching the behavior of `eachline` and `readlines` ([#25845](https://github.com/JuliaLang/julia/issues/25845)). @@ -683,6 +701,31 @@ Deprecated or removed * The keyword `immutable` is fully deprecated to `struct`, and `type` is fully deprecated to `mutable struct` ([#19157](https://github.com/JuliaLang/julia/issues/19157), [#20418](https://github.com/JuliaLang/julia/issues/20418)). + * `lufact`, `schurfact`, `lqfact`, `qrfact`, `ldltfact`, `svdfact`, + `bkfact`, `hessfact`, `eigfact`, and `cholfact` have respectively been + deprecated to `lu`, `schur`, `lq`, `qr`, `ldlt`, `svd`, `bunchkaufman`, + `hessenberg`, `eigen`, and `cholesky` ([#26997](https://github.com/JuliaLang/julia/issues/26997), [#27159](https://github.com/JuliaLang/julia/issues/27159), [#27212](https://github.com/JuliaLang/julia/issues/27212)). + + * `lufact!`, `schurfact!`, `lqfact!`, `qrfact!`, `ldltfact!`, `svdfact!`, + `bkfact!`, `hessfact!`, and `eigfact!` have respectively been deprecated to + `lu!`, `schur!`, `lq!`, `qr!`, `ldlt!`, `svd!`, `bunchkaufman!`, + `hessenberg!`, and `eigen!` ([#26997](https://github.com/JuliaLang/julia/issues/26997), [#27159](https://github.com/JuliaLang/julia/issues/27159), [#27212](https://github.com/JuliaLang/julia/issues/27212)). + + * `eig(A[, args...])` has been deprecated in favor of `eigen(A[, args...])`. + Whereas the former returns a tuple of arrays, the latter returns an `Eigen` object. + So for a direct replacement, use `(eigen(A[, args...])...,)`. But going forward, + consider using the direct result of `eigen(A[, args...])` instead, either + destructured into its components (`vals, vecs = eigen(A[, args...])`) or + as an `Eigen` object (`X = eigen(A[, args...])`) ([#26997](https://github.com/JuliaLang/julia/issues/26997), [#27159](https://github.com/JuliaLang/julia/issues/27159), [#27212](https://github.com/JuliaLang/julia/issues/27212)). + + * `eig(A::AbstractMatrix, B::AbstractMatrix)` and `eig(A::Number, B::Number)` + have been deprecated in favor of `eigen(A, B)`. Whereas the former each return + a tuple of arrays, the latter returns a `GeneralizedEigen` object. So for a direct + replacement, use `(eigen(A, B)...,)`. But going forward, consider using the + direct result of `eigen(A, B)` instead, either destructured into its components + (`vals, vecs = eigen(A, B)`), or as a `GeneralizedEigen` object + (`X = eigen(A, B)`) ([#26997](https://github.com/JuliaLang/julia/issues/26997), [#27159](https://github.com/JuliaLang/julia/issues/27159), [#27212](https://github.com/JuliaLang/julia/issues/27212)). + * Indexing into multidimensional arrays with more than one index but fewer indices than there are dimensions is no longer permitted when those trailing dimensions have lengths greater than 1. Instead, reshape the array or add trailing indices so the dimensionality and number of indices diff --git a/src/devdocs/functions.md b/src/devdocs/functions.md index 294b0fb..d20db2f 100644 --- a/src/devdocs/functions.md +++ b/src/devdocs/functions.md @@ -135,7 +135,7 @@ or "keyword sorter", or "kwsorter", and is stored in the `kwsorter` field of `Me Every definition in the kwsorter function has the same arguments as some definition in the normal method table, except with a single `Array` argument prepended. This array contains alternating symbols and values that represent the passed keyword arguments. The kwsorter's job is to move -keyword arguments into their canonical positions based on name, plus evaluate and substite any +keyword arguments into their canonical positions based on name, plus evaluate and substitute any needed default value expressions. The result is a normal positional argument list, which is then passed to yet another function. @@ -248,6 +248,6 @@ constructor generation), and using `new` directly to create closure instances. N thing ever, but you do what you gotta do. The next problem was the `@test` macro, which generated a 0-argument closure for each test case. -This is not really necessary, since each test case is simply run once in place. Therefore I modified -`@test` to expand to a try-catch block that records the test result (true, false, or exception +This is not really necessary, since each test case is simply run once in place. Therefore, `@test` +was modified to expand to a try-catch block that records the test result (true, false, or exception raised) and calls the test suite handler on it. diff --git a/src/manual/arrays.md b/src/manual/arrays.md index 573dbdf..2ff682a 100644 --- a/src/manual/arrays.md +++ b/src/manual/arrays.md @@ -690,37 +690,37 @@ call highly tuned and optimized BLAS and LAPACK functions using just the pointer 다음 예시에서는 임시 배열을 만들지 않고 적절한 LAPACK 함수를 차원 크기와 스트라이드를 사용하여 호출하여 큰 배열의 작은 섹션의 QR 분해를 계산한다. ```julia-repl -julia> a = rand(10,10) +julia> a = rand(10, 10) 10×10 Array{Float64,2}: - 0.561255 0.226678 0.203391 0.308912 … 0.750307 0.235023 0.217964 - 0.718915 0.537192 0.556946 0.996234 0.666232 0.509423 0.660788 - 0.493501 0.0565622 0.118392 0.493498 0.262048 0.940693 0.252965 - 0.0470779 0.736979 0.264822 0.228787 0.161441 0.897023 0.567641 - 0.343935 0.32327 0.795673 0.452242 0.468819 0.628507 0.511528 - 0.935597 0.991511 0.571297 0.74485 … 0.84589 0.178834 0.284413 - 0.160706 0.672252 0.133158 0.65554 0.371826 0.770628 0.0531208 - 0.306617 0.836126 0.301198 0.0224702 0.39344 0.0370205 0.536062 - 0.890947 0.168877 0.32002 0.486136 0.096078 0.172048 0.77672 - 0.507762 0.573567 0.220124 0.165816 0.211049 0.433277 0.539476 + 0.517515 0.0348206 0.749042 0.0979679 … 0.75984 0.950481 0.579513 + 0.901092 0.873479 0.134533 0.0697848 0.0586695 0.193254 0.726898 + 0.976808 0.0901881 0.208332 0.920358 0.288535 0.705941 0.337137 + 0.657127 0.0317896 0.772837 0.534457 0.0966037 0.700694 0.675999 + 0.471777 0.144969 0.0718405 0.0827916 0.527233 0.173132 0.694304 + 0.160872 0.455168 0.489254 0.827851 … 0.62226 0.0995456 0.946522 + 0.291857 0.769492 0.68043 0.629461 0.727558 0.910796 0.834837 + 0.775774 0.700731 0.700177 0.0126213 0.00822304 0.327502 0.955181 + 0.9715 0.64354 0.848441 0.241474 0.591611 0.792573 0.194357 + 0.646596 0.575456 0.0995212 0.038517 0.709233 0.477657 0.0507231 julia> b = view(a, 2:2:8,2:2:4) -4×2 SubArray{Float64,2,Array{Float64,2},Tuple{StepRange{Int64,Int64},StepRange{Int64,Int64}},false}: - 0.537192 0.996234 - 0.736979 0.228787 - 0.991511 0.74485 - 0.836126 0.0224702 +4×2 view(::Array{Float64,2}, 2:2:8, 2:2:4) with eltype Float64: + 0.873479 0.0697848 + 0.0317896 0.534457 + 0.455168 0.827851 + 0.700731 0.0126213 -julia> (q,r) = qr(b); +julia> (q, r) = qr(b); julia> q -4×2 Array{Float64,2}: - -0.338809 0.78934 - -0.464815 -0.230274 - -0.625349 0.194538 - -0.527347 -0.534856 +4×4 LinearAlgebra.QRCompactWYQ{Float64,Array{Float64,2}}: + -0.722358 0.227524 -0.247784 -0.604181 + -0.0262896 -0.575919 -0.804227 0.144377 + -0.376419 -0.75072 0.540177 -0.0541979 + -0.579497 0.230151 -0.00552346 0.781782 julia> r 2×2 Array{Float64,2}: - -1.58553 -0.921517 - 0.0 0.866567 + -1.20921 -0.383393 + 0.0 -0.910506 ``` diff --git a/src/manual/calling-c-and-fortran-code.md b/src/manual/calling-c-and-fortran-code.md index affc89b..7eeac82 100644 --- a/src/manual/calling-c-and-fortran-code.md +++ b/src/manual/calling-c-and-fortran-code.md @@ -934,7 +934,7 @@ function qsort(a::Vector{T}, cmp) where T # Here, `callback` isa Base.CFunction, which will be converted to Ptr{Cvoid} # (and protected against finalization) by the ccall ccall(:qsort, Cvoid, (Ptr{T}, Csize_t, Csize_t, Ptr{Cvoid}), - a, length(A), Base.elsize(A), callback) + a, length(a), Base.elsize(a), callback) # We could instead use: # GC.@preserve callback begin # use(Base.unsafe_convert(Ptr{Cvoid}, callback)) diff --git a/src/manual/code-loading.md b/src/manual/code-loading.md index e95c37f..2140306 100644 --- a/src/manual/code-loading.md +++ b/src/manual/code-loading.md @@ -19,7 +19,7 @@ Understanding how Julia answers these questions is key to understanding package ## Federation of packages -Julia supports federated management of packages. This means that multiple independent parties can maintain both public and private packages and registries of them, and that projects can depend on a mix of public and private packages from different registries. Packages from various registries are installed and managed using a common set of tools and workflows. The Pkg3 next-generation package manager [[docs](https://julialang.org/Pkg3.jl/latest/), [repo](https://github.com/JuliaLang/Pkg3.jl)] ships with Julia 0.7/1.0 and lets you install and manage dependencies of your projects, by creating and manipulating project files, which describe what your project depends on, and manifest files that snapshot exact versions of your project's complete dependency graph. +Julia supports federated management of packages. This means that multiple independent parties can maintain both public and private packages and registries of them, and that projects can depend on a mix of public and private packages from different registries. Packages from various registries are installed and managed using a common set of tools and workflows. The `Pkg` package manager ships with Julia 0.7/1.0 and lets you install and manage dependencies of your projects, by creating and manipulating project files, which describe what your project depends on, and manifest files that snapshot exact versions of your project's complete dependency graph. One consequence of federation is that there cannot be a central authority for package naming. Different entities may use the same name to refer to unrelated packages. This possibility is unavoidable since these entities do not coordinate and may not even know about each other. Because of the lack of a central naming authority, a single project can quite possibly end up depending on different packages with the same name. Julia's package loading mechanism handles this by not requiring package names to be globally unique, even within the dependency graph of a single project. Instead, packages are identified by [universally unique identifiers](https://en.wikipedia.org/wiki/Universally_unique_identifier) (UUIDs) which are assigned to them before they are registered. The question *"what is `X`?"* is answered by determining the UUID of `X`. diff --git a/src/manual/environment-variables.md b/src/manual/environment-variables.md index 739335b..6d6286d 100644 --- a/src/manual/environment-variables.md +++ b/src/manual/environment-variables.md @@ -76,36 +76,6 @@ the absolute path e.g., version 0.7 of Julia on a Linux system with a Julia executable at `/bin/julia` will have a default `LOAD_PATH` of `/share/julia/stdlib/v0.7`. -### `JULIA_PKGDIR` - -The path of the parent directory `Pkg.Dir._pkgroot()` for the version-specific -Julia package repositories. If the path is relative, then it is taken with -respect to the working directory. If `$JULIA_PKGDIR` is not set, then -`Pkg.Dir._pkgroot()` defaults to - -``` -$HOME/.julia -``` - -Then the repository location `Pkg.dir` for a given Julia version is - -``` -$JULIA_PKGDIR/v$(VERSION.major).$(VERSION.minor) -``` - -For example, for a Linux user whose home directory is `/home/alice`, the directory -containing the package repositories would by default be - -``` -/home/alice/.julia -``` - -and the package repository for version 0.6 of Julia would be - -``` -/home/alice/.julia/v0.6 -``` - ### `JULIA_HISTORY` The absolute path `REPL.find_hist_file()` of the REPL's history file. If @@ -118,7 +88,7 @@ $HOME/.julia/logs/repl_history.jl ### `JULIA_PKGRESOLVE_ACCURACY` A positive `Int` that determines how much time the max-sum subroutine -`MaxSum.maxsum()` of the package dependency resolver `Pkg.resolve` +`MaxSum.maxsum()` of the package dependency resolver will devote to attempting satisfying constraints before giving up: this value is by default `1`, and larger values correspond to larger amounts of time. @@ -154,7 +124,7 @@ exists, or `emacs` otherwise. !!! note `$JULIA_EDITOR` is *not* used in the determination of the editor for - `Pkg.edit`: this function checks `$VISUAL` and `$EDITOR` alone. + `OldPkg.edit`: this function checks `$VISUAL` and `$EDITOR` alone. ## Parallelization diff --git a/src/manual/index.md b/src/manual/index.md index 5f79a98..3ae00cf 100644 --- a/src/manual/index.md +++ b/src/manual/index.md @@ -28,8 +28,6 @@ * [Handling Operating System Variation](@ref) * [Environment Variables](@ref) * [Embedding Julia](@ref) - * [Packages](@ref) - * [Package Development](@ref) * [Profiling](@ref) * [Memory allocation analysis](@ref) * [Stack Traces](@ref) diff --git a/src/manual/modules.md b/src/manual/modules.md index a12f873..c6c6840 100644 --- a/src/manual/modules.md +++ b/src/manual/modules.md @@ -363,7 +363,7 @@ code to help the user avoid other wrong-behavior situations: 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`](@ref)), and no cleanup is done after [`Pkg.rm`](@ref) + (including by [`Pkg.update`], and no cleanup is done after [`Pkg.rm`] 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__`](@ref)/`source_path()` @@ -383,5 +383,5 @@ command line flag `--compiled-modules={yes|no}` enables you to toggle module pre off. When Julia is started with `--compiled-modules=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`](@ref) to disable automatic precompilation triggering when installing, +line flag is passed to [`Pkg.build`] to disable automatic precompilation triggering when installing, updating, and explicitly building packages. diff --git a/src/manual/packages.md b/src/manual/packages.md deleted file mode 100644 index f10edc1..0000000 --- a/src/manual/packages.md +++ /dev/null @@ -1,1118 +0,0 @@ -# Packages - -Julia has a built-in package manager for installing add-on functionality written in Julia. It -can also install external libraries using your operating system's standard system for doing so, -or by compiling from source. The list of registered Julia packages can be found at [http://pkg.julialang.org](http://pkg.julialang.org). -All package manager commands are found in the `Pkg` standard library which becomes available after using -`import Pkg`. - -First we'll go over the mechanics of the `Pkg` family of commands and then we'll provide some -guidance on how to get your package registered. Be sure to read the section below on package naming -conventions, tagging versions and the importance of a `REQUIRE` file for when you're ready to -add your code to the curated METADATA repository. - -## Package Status - -The [`Pkg.status()`](@ref) function prints out a summary of the state of packages you have installed. -Initially, you'll have no packages installed: - -```julia-repl -julia> Pkg.status() -INFO: Initializing package repository /Users/someone/.julia/v0.6 -INFO: Cloning METADATA from git://github.com/JuliaLang/METADATA.jl -No packages installed. -``` - -Your package directory is automatically initialized the first time you run a `Pkg` command -that expects it to exist – which includes [`Pkg.status()`](@ref). Here's an example non-trivial -set of required and additional packages: - -```julia-repl -julia> Pkg.status() -Required packages: - - Distributions 0.2.8 - - SHA 0.3.2 -Additional packages: - - NumericExtensions 0.2.17 - - Stats 0.2.6 -``` - -These packages are all on registered versions, managed by `Pkg`. Packages can be in more -complicated states, indicated by annotations to the right of the installed package version; we -will explain these states and annotations as we encounter them. For programmatic usage, [`Pkg.installed()`](@ref) -returns a dictionary, mapping installed package names to the version of that package which is -installed: - -```julia-repl -julia> Pkg.installed() -Dict{String,VersionNumber} with 4 entries: -"Distributions" => v"0.2.8" -"Stats" => v"0.2.6" -"SHA" => v"0.3.2" -"NumericExtensions" => v"0.2.17" -``` - -## Adding and Removing Packages - -Julia's package manager is a little unusual in that it is declarative rather than imperative. -This means that you tell it what you want and it figures out what versions to install (or remove) -to satisfy those requirements optimally – and minimally. So rather than installing a package, -you just add it to the list of requirements and then "resolve" what needs to be installed. In -particular, this means that if some package had been installed because it was needed by a previous -version of something you wanted, and a newer version doesn't have that requirement anymore, updating -will actually remove that package. - -Your package requirements are in the file `~/.julia/v0.6/REQUIRE`. You can edit this file by hand -and then call [`Pkg.resolve()`](@ref) to install, upgrade or remove packages to optimally satisfy -the requirements, or you can do [`Pkg.edit()`](@ref), which will open `REQUIRE` in your editor -(configured via the `EDITOR` or `VISUAL` environment variables), and then automatically call -[`Pkg.resolve()`](@ref) afterwards if necessary. If you only want to add or remove the requirement -for a single package, you can also use the non-interactive [`Pkg.add()`](@ref) and [`Pkg.rm()`](@ref) -commands, which add or remove a single requirement to `REQUIRE` and then call [`Pkg.resolve()`](@ref). - -You can add a package to the list of requirements with the [`Pkg.add()`](@ref) function, and the -package and all the packages that it depends on will be installed: - -```julia-repl -julia> Pkg.status() -No packages installed. - -julia> Pkg.add("Distributions") -INFO: Cloning cache of Distributions from git://github.com/JuliaStats/Distributions.jl.git -INFO: Cloning cache of NumericExtensions from git://github.com/lindahua/NumericExtensions.jl.git -INFO: Cloning cache of Stats from git://github.com/JuliaStats/Stats.jl.git -INFO: Installing Distributions v0.2.7 -INFO: Installing NumericExtensions v0.2.17 -INFO: Installing Stats v0.2.6 -INFO: REQUIRE updated. - -julia> Pkg.status() -Required packages: - - Distributions 0.2.7 -Additional packages: - - NumericExtensions 0.2.17 - - Stats 0.2.6 -``` - -What this is doing is first adding `Distributions` to your `~/.julia/v0.6/REQUIRE` file: - -``` -$ cat ~/.julia/v0.6/REQUIRE -Distributions -``` - -It then runs [`Pkg.resolve()`](@ref) using these new requirements, which leads to the conclusion -that the `Distributions` package should be installed since it is required but not installed. As -stated before, you can accomplish the same thing by editing your `~/.julia/v0.6/REQUIRE` file -by hand and then running [`Pkg.resolve()`](@ref) yourself: - -```julia-repl -$ echo SHA >> ~/.julia/v0.6/REQUIRE - -julia> Pkg.resolve() -INFO: Cloning cache of SHA from git://github.com/staticfloat/SHA.jl.git -INFO: Installing SHA v0.3.2 - -julia> Pkg.status() -Required packages: - - Distributions 0.2.7 - - SHA 0.3.2 -Additional packages: - - NumericExtensions 0.2.17 - - Stats 0.2.6 -``` - -This is functionally equivalent to calling [`Pkg.add("SHA")`](@ref), except that [`Pkg.add()`](@ref) -doesn't change `REQUIRE` until *after* installation has completed, so if there are problems, -`REQUIRE` will be left as it was before calling [`Pkg.add()`](@ref). The format of the `REQUIRE` -file is described in [Requirements Specification](@ref); it allows, among other things, requiring -specific ranges of versions of packages. - -When you decide that you don't want to have a package around any more, you can use [`Pkg.rm()`](@ref) -to remove the requirement for it from the `REQUIRE` file: - -```julia-repl -julia> Pkg.rm("Distributions") -INFO: Removing Distributions v0.2.7 -INFO: Removing Stats v0.2.6 -INFO: Removing NumericExtensions v0.2.17 -INFO: REQUIRE updated. - -julia> Pkg.status() -Required packages: - - SHA 0.3.2 - -julia> Pkg.rm("SHA") -INFO: Removing SHA v0.3.2 -INFO: REQUIRE updated. - -julia> Pkg.status() -No packages installed. -``` - -Once again, this is equivalent to editing the `REQUIRE` file to remove the line with each package -name on it then running [`Pkg.resolve()`](@ref) to update the set of installed packages to match. -While [`Pkg.add()`](@ref) and [`Pkg.rm()`](@ref) are convenient for adding and removing requirements -for a single package, when you want to add or remove multiple packages, you can call [`Pkg.edit()`](@ref) -to manually change the contents of `REQUIRE` and then update your packages accordingly. [`Pkg.edit()`](@ref) -does not roll back the contents of `REQUIRE` if [`Pkg.resolve()`](@ref) fails – rather, you -have to run [`Pkg.edit()`](@ref) again to fix the files contents yourself. - -Because the package manager uses libgit2 internally to manage the package git repositories, users -may run into protocol issues (if behind a firewall, for example), when running [`Pkg.add()`](@ref). -By default, all GitHub-hosted packages wil be accessed via 'https'; this default can be modified -by calling [`Pkg.setprotocol!()`](@ref). The following command can be run from the command line -in order to tell git to use 'https' instead of the 'git' protocol when cloning all repositories, -wherever they are hosted: - -``` -git config --global url."https://".insteadOf git:// -``` - -However, this change will be system-wide and thus the use of [`Pkg.setprotocol!()`](@ref) is preferable. - -!!! note - The package manager functions also accept the `.jl` suffix on package names, though the suffix is - stripped internally. For example: - - ```julia - Pkg.add("Distributions.jl") - Pkg.rm("Distributions.jl") - ``` - -## Offline Installation of Packages - -For machines with no Internet connection, packages may be installed by copying the package root -directory (given by [`Pkg.dir()`](@ref)) from a machine with the same operating system and environment. - -[`Pkg.add()`](@ref) does the following within the package root directory: - -1. Adds the name of the package to `REQUIRE`. -2. Downloads the package to `.cache`, then copies the package to the package root directory. -3. Recursively performs step 2 against all the packages listed in the package's `REQUIRE` file. -4. Runs [`Pkg.build()`](@ref) - -!!! warning - Copying installed packages from a different machine is brittle for packages requiring binary external - dependencies. Such packages may break due to differences in operating system versions, build environments, - and/or absolute path dependencies. - -## Installing Unregistered Packages - -Julia packages are simply git repositories, clonable via any of the [protocols](https://www.kernel.org/pub/software/scm/git/docs/git-clone.html#URLS) -that git supports, and containing Julia code that follows certain layout conventions. Official -Julia packages are registered in the [METADATA.jl](https://github.com/JuliaLang/METADATA.jl) repository, -available at a well-known location [^1]. The [`Pkg.add()`](@ref) and [`Pkg.rm()`](@ref) commands -in the previous section interact with registered packages, but the package manager can install -and work with unregistered packages too. To install an unregistered package, use [`Pkg.clone(url)`](@ref), -where `url` is a git URL from which the package can be cloned: - -```julia-repl -julia> Pkg.clone("git://example.com/path/to/Package.jl.git") -INFO: Cloning Package from git://example.com/path/to/Package.jl.git -Cloning into 'Package'... -remote: Counting objects: 22, done. -remote: Compressing objects: 100% (10/10), done. -remote: Total 22 (delta 8), reused 22 (delta 8) -Receiving objects: 100% (22/22), 2.64 KiB, done. -Resolving deltas: 100% (8/8), done. -``` - -By convention, Julia repository names end with `.jl` (the additional `.git` indicates a "bare" -git repository), which keeps them from colliding with repositories for other languages, and also -makes Julia packages easy to find in search engines. When packages are installed in your `.julia/v0.6` -directory, however, the extension is redundant so we leave it off. - -If unregistered packages contain a `REQUIRE` file at the top of their source tree, that file will -be used to determine which registered packages the unregistered package depends on, and they will -automatically be installed. Unregistered packages participate in the same version resolution logic -as registered packages, so installed package versions will be adjusted as necessary to satisfy -the requirements of both registered and unregistered packages. - -[^1]: - The official set of packages is at [https://github.com/JuliaLang/METADATA.jl](https://github.com/JuliaLang/METADATA.jl), - but individuals and organizations can easily use a different metadata repository. This allows - control which packages are available for automatic installation. One can allow only audited and - approved package versions, and make private packages or forks available. See [Custom METADATA Repository](@ref) - for details. - -## Updating Packages - -When package developers publish new registered versions of packages that you're using, you will, -of course, want the new shiny versions. To get the latest and greatest versions of all your packages, -just do [`Pkg.update()`](@ref): - -```julia-repl -julia> Pkg.update() -INFO: Updating METADATA... -INFO: Computing changes... -INFO: Upgrading Distributions: v0.2.8 => v0.2.10 -INFO: Upgrading Stats: v0.2.7 => v0.2.8 -``` - -The first step of updating packages is to pull new changes to `~/.julia/v0.6/METADATA` and see -if any new registered package versions have been published. After this, [`Pkg.update()`](@ref) -attempts to update packages that are checked out on a branch and not dirty (i.e. no changes have -been made to files tracked by git) by pulling changes from the package's upstream repository. -Upstream changes will only be applied if no merging or rebasing is necessary – i.e. if the branch -can be ["fast-forwarded"](https://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging). -If the branch cannot be fast-forwarded, it is assumed that you're working on it and will update -the repository yourself. - -Finally, the update process recomputes an optimal set of package versions to have installed to -satisfy your top-level requirements and the requirements of "fixed" packages. A package is considered -fixed if it is one of the following: - -1. **Unregistered:** the package is not in `METADATA` – you installed it with [`Pkg.clone()`](@ref). -2. **Checked out:** the package repo is on a development branch. -3. **Dirty:** changes have been made to files in the repo. - -If any of these are the case, the package manager cannot freely change the installed version of -the package, so its requirements must be satisfied by whatever other package versions it picks. -The combination of top-level requirements in `~/.julia/v0.6/REQUIRE` and the requirement of fixed -packages are used to determine what should be installed. - -You can also update only a subset of the installed packages, by providing arguments to the [`Pkg.update`](@ref) -function. In that case, only the packages provided as arguments and their dependencies will be -updated: - -```julia-repl -julia> Pkg.update("Example") -INFO: Updating METADATA... -INFO: Computing changes... -INFO: Upgrading Example: v0.4.0 => 0.4.1 -``` - -This partial update process still computes the new set of package versions according to top-level -requirements and "fixed" packages, but it additionally considers all other packages except those -explicitly provided, and their dependencies, as fixed. - -## Checkout, Pin and Free - -You may want to use the `master` version of a package rather than one of its registered versions. -There might be fixes or functionality on master that you need that aren't yet published in any -registered versions, or you may be a developer of the package and need to make changes on `master` -or some other development branch. In such cases, you can do [`Pkg.checkout(pkg)`](@ref) to checkout -the `master` branch of `pkg` or [`Pkg.checkout(pkg,branch)`](@ref) to checkout some other branch: - -```julia-repl -julia> Pkg.add("Distributions") -INFO: Installing Distributions v0.2.9 -INFO: Installing NumericExtensions v0.2.17 -INFO: Installing Stats v0.2.7 -INFO: REQUIRE updated. - -julia> Pkg.status() -Required packages: - - Distributions 0.2.9 -Additional packages: - - NumericExtensions 0.2.17 - - Stats 0.2.7 - -julia> Pkg.checkout("Distributions") -INFO: Checking out Distributions master... -INFO: No packages to install, update or remove. - -julia> Pkg.status() -Required packages: - - Distributions 0.2.9+ master -Additional packages: - - NumericExtensions 0.2.17 - - Stats 0.2.7 -``` - -Immediately after installing `Distributions` with [`Pkg.add()`](@ref) it is on the current most -recent registered version – `0.2.9` at the time of writing this. Then after running [`Pkg.checkout("Distributions")`](@ref), -you can see from the output of [`Pkg.status()`](@ref) that `Distributions` is on an unregistered -version greater than `0.2.9`, indicated by the "pseudo-version" number `0.2.9+`. - -When you checkout an unregistered version of a package, the copy of the `REQUIRE` file in the -package repo takes precedence over any requirements registered in `METADATA`, so it is important -that developers keep this file accurate and up-to-date, reflecting the actual requirements of -the current version of the package. If the `REQUIRE` file in the package repo is incorrect or -missing, dependencies may be removed when the package is checked out. This file is also used to -populate newly published versions of the package if you use the API that `Pkg` provides -for this (described below). - -When you decide that you no longer want to have a package checked out on a branch, you can "free" -it back to the control of the package manager with [`Pkg.free(pkg)`](@ref): - -```julia-repl -julia> Pkg.free("Distributions") -INFO: Freeing Distributions... -INFO: No packages to install, update or remove. - -julia> Pkg.status() -Required packages: - - Distributions 0.2.9 -Additional packages: - - NumericExtensions 0.2.17 - - Stats 0.2.7 -``` - -After this, since the package is on a registered version and not on a branch, its version will -be updated as new registered versions of the package are published. - -If you want to pin a package at a specific version so that calling [`Pkg.update()`](@ref) won't -change the version the package is on, you can use the [`Pkg.pin()`](@ref) function: - -```julia-repl -julia> Pkg.pin("Stats") -INFO: Creating Stats branch pinned.47c198b1.tmp - -julia> Pkg.status() -Required packages: - - Distributions 0.2.9 -Additional packages: - - NumericExtensions 0.2.17 - - Stats 0.2.7 pinned.47c198b1.tmp -``` - -After this, the `Stats` package will remain pinned at version `0.2.7` – or more specifically, -at commit `47c198b1`, but since versions are permanently associated a given git hash, this is -the same thing. [`Pkg.pin()`](@ref) works by creating a throw-away branch for the commit you want -to pin the package at and then checking that branch out. By default, it pins a package at the -current commit, but you can choose a different version by passing a second argument: - -```julia-repl -julia> Pkg.pin("Stats",v"0.2.5") -INFO: Creating Stats branch pinned.1fd0983b.tmp -INFO: No packages to install, update or remove. - -julia> Pkg.status() -Required packages: - - Distributions 0.2.9 -Additional packages: - - NumericExtensions 0.2.17 - - Stats 0.2.5 pinned.1fd0983b.tmp -``` - -Now the `Stats` package is pinned at commit `1fd0983b`, which corresponds to version `0.2.5`. -When you decide to "unpin" a package and let the package manager update it again, you can use -[`Pkg.free()`](@ref) like you would to move off of any branch: - -```julia-repl -julia> Pkg.free("Stats") -INFO: Freeing Stats... -INFO: No packages to install, update or remove. - -julia> Pkg.status() -Required packages: - - Distributions 0.2.9 -Additional packages: - - NumericExtensions 0.2.17 - - Stats 0.2.7 -``` - -After this, the `Stats` package is managed by the package manager again, and future calls to -[`Pkg.update()`](@ref) will upgrade it to newer versions when they are published. The throw-away -`pinned.1fd0983b.tmp` branch remains in your local `Stats` repo, but since git branches are extremely -lightweight, this doesn't really matter; if you feel like cleaning them up, you can go into the -repo and delete those branches [^2]. - -[^2]: - Packages that aren't on branches will also be marked as dirty if you make changes in the repo, - but that's a less common thing to do. - -## Custom METADATA Repository - -By default, Julia assumes you will be using the [official METADATA.jl](https://github.com/JuliaLang/METADATA.jl) -repository for downloading and installing packages. You can also provide a different metadata -repository location. A common approach is to keep your `metadata-v2` branch up to date with the -Julia official branch and add another branch with your custom packages. You can initialize your -local metadata repository using that custom location and branch and then periodically rebase your -custom branch with the official `metadata-v2` branch. In order to use a custom repository and -branch, issue the following command: - -```julia-repl -julia> Pkg.init("https://me.example.com/METADATA.jl.git", "branch") -``` - -The branch argument is optional and defaults to `metadata-v2`. Once initialized, a file named -`META_BRANCH` in your `~/.julia/vX.Y/` path will track the branch that your METADATA repository -was initialized with. If you want to change branches, you will need to either modify the `META_BRANCH` -file directly (be careful!) or remove the `vX.Y` directory and re-initialize your METADATA repository -using the `Pkg.init` command. - -# Package Development - -Julia's package manager is designed so that when you have a package installed, you are already -in a position to look at its source code and full development history. You are also able to make -changes to packages, commit them using git, and easily contribute fixes and enhancements upstream. -Similarly, the system is designed so that if you want to create a new package, the simplest way -to do so is within the infrastructure provided by the package manager. - -## [Initial Setup](@id man-initial-setup) - -Since packages are git repositories, before doing any package development you should setup the -following standard global git configuration settings: - -``` -$ git config --global user.name "FULL NAME" -$ git config --global user.email "EMAIL" -``` - -where `FULL NAME` is your actual full name (spaces are allowed between the double quotes) and -`EMAIL` is your actual email address. Although it isn't necessary to use [GitHub](https://github.com/) -to create or publish Julia packages, most Julia packages as of writing this are hosted on GitHub -and the package manager knows how to format origin URLs correctly and otherwise work with the -service smoothly. We recommend that you create a [free account](https://github.com/join) on GitHub -and then do: - -``` -$ git config --global github.user "USERNAME" -``` - -where `USERNAME` is your actual GitHub user name. Once you do this, the package manager knows -your GitHub user name and can configure things accordingly. You should also [upload](https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2Fsettings%2Fssh) -your public SSH key to GitHub and set up an [SSH agent](https://linux.die.net/man/1/ssh-agent) -on your development machine so that you can push changes with minimal hassle. In the future, we -will make this system extensible and support other common git hosting options like [BitBucket](https://bitbucket.org) -and allow developers to choose their favorite. Since the package development functions has been -moved to the [PkgDev](https://github.com/JuliaLang/PkgDev.jl) package, you need to run `Pkg.add("PkgDev"); import PkgDev` -to access the functions starting with `PkgDev.` in the document below. - -## Making changes to an existing package - -### Documentation changes - -If you want to improve the online documentation of a package, the easiest approach (at least for -small changes) is to use GitHub's online editing functionality. First, navigate to the repository's -GitHub "home page," find the file (e.g., `README.md`) within the repository's folder structure, -and click on it. You'll see the contents displayed, along with a small "pencil" icon in the upper -right hand corner. Clicking that icon opens the file in edit mode. Make your changes, write a -brief summary describing the changes you want to make (this is your *commit message*), and then -hit "Propose file change." Your changes will be submitted for consideration by the package owner(s) -and collaborators. - -For larger documentation changes--and especially ones that you expect to have to update in response -to feedback--you might find it easier to use the procedure for code changes described below. - -### Code changes - -#### Executive summary - -Here we assume you've already set up git on your local machine and have a GitHub account (see -above). Let's imagine you're fixing a bug in the Images package: - -``` -Pkg.checkout("Images") # check out the master branch - -cd(Pkg.dir("Images")) -;git checkout -b myfixes # create a branch for your changes - # be sure to add a test for your bug -Pkg.test("Images") # make sure everything works now -;git commit -a -m "Fix foo by calling bar" # write a descriptive message -using PkgDev -PkgDev.submit("Images") -``` - -The last line will present you with a link to submit a pull request to incorporate your changes. - -#### Detailed description - -If you want to fix a bug or add new functionality, you want to be able to test your changes before -you submit them for consideration. You also need to have an easy way to update your proposal in -response to the package owner's feedback. Consequently, in this case the strategy is to work locally -on your own machine; once you are satisfied with your changes, you submit them for consideration. - This process is called a *pull request* because you are asking to "pull" your changes into the -project's main repository. Because the online repository can't see the code on your private machine, -you first *push* your changes to a publicly-visible location, your own online *fork* of the package -(hosted on your own personal GitHub account). - -Let's assume you already have the `Foo` package installed. In the description below, anything -starting with `Pkg.` or `PkgDev.` is meant to be typed at the Julia prompt; anything starting -with `git` is meant to be typed in [julia's shell mode](@ref man-shell-mode) (or using the shell that comes with -your operating system). Within Julia, you can combine these two modes: - -```julia-repl -julia> cd(Pkg.dir("Foo")) # go to Foo's folder - -shell> git command arguments... # command will apply to Foo -``` - -Now suppose you're ready to make some changes to `Foo`. While there are several possible approaches, -here is one that is widely used: - - * From the Julia prompt, type [`Pkg.checkout("Foo")`](@ref). This ensures you're running the latest - code (the `master` branch), rather than just whatever "official release" version you have installed. - (If you're planning to fix a bug, at this point it's a good idea to check again whether the bug - has already been fixed by someone else. If it has, you can request that a new official release - be tagged so that the fix gets distributed to the rest of the community.) If you receive an error - `Foo is dirty, bailing`, see [Dirty packages](@ref) below. - * Create a branch for your changes: navigate to the package folder (the one that Julia reports from - [`Pkg.dir("Foo")`](@ref)) and (in shell mode) create a new branch using `git checkout -b `, - where `` might be some descriptive name (e.g., `fixbar`). By creating a branch, you - ensure that you can easily go back and forth between your new work and the current `master` branch - (see [https://git-scm.com/book/en/v2/Git-Branching-Branches-in-a-Nutshell](https://git-scm.com/book/en/v2/Git-Branching-Branches-in-a-Nutshell)). - - If you forget to do this step until after you've already made some changes, don't worry: see - [more detail about branching](@ref man-branch-post-hoc) below. - * Make your changes. Whether it's fixing a bug or adding new functionality, in most cases your change - should include updates to both the `src/` and `test/` folders. If you're fixing a bug, add your - minimal example demonstrating the bug (on the current code) to the test suite; by contributing - a test for the bug, you ensure that the bug won't accidentally reappear at some later time due - to other changes. If you're adding new functionality, creating tests demonstrates to the package - owner that you've made sure your code works as intended. - * Run the package's tests and make sure they pass. There are several ways to run the tests: - - * From Julia, run [`Pkg.test("Foo")`](@ref): this will run your tests in a separate (new) `julia` - process. - * From Julia, `include("runtests.jl")` from the package's `test/` folder (it's possible the file - has a different name, look for one that runs all the tests): this allows you to run the tests - repeatedly in the same session without reloading all the package code; for packages that take - a while to load, this can be much faster. With this approach, you do have to do some extra work - to make [changes in the package code](@ref man-workflow-tips). - * From the shell, run `julia ../test/runtests.jl` from within the package's `src/` folder. - * Commit your changes: see [https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository](https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository). - * Submit your changes: From the Julia prompt, type `PkgDev.submit("Foo")`. This will push your changes - to your GitHub fork, creating it if it doesn't already exist. (If you encounter an error, [make sure you've set up your SSH keys](@ref man-initial-setup).) - Julia will then give you a hyperlink; open that link, edit the message, and then click "submit." - At that point, the package owner will be notified of your changes and may initiate discussion. - (If you are comfortable with git, you can also do these steps manually from the shell.) - * The package owner may suggest additional improvements. To respond to those suggestions, you can - easily update the pull request (this only works for changes that have not already been merged; - for merged pull requests, make new changes by starting a new branch): - - * If you've changed branches in the meantime, make sure you go back to the same branch with `git checkout fixbar` - (from shell mode) or [`Pkg.checkout("Foo", "fixbar")`](@ref) (from the Julia prompt). - * As above, make your changes, run the tests, and commit your changes. - * From the shell, type `git push`. This will add your new commit(s) to the same pull request; you - should see them appear automatically on the page holding the discussion of your pull request. - - One potential type of change the owner may request is that you squash your commits. See [Squashing](@ref man-squashing-and-rebasing) - below. - -### Dirty packages - -If you can't change branches because the package manager complains that your package is dirty, -it means you have some changes that have not been committed. From the shell, use `git diff` to -see what these changes are; you can either discard them (`git checkout changedfile.jl`) or commit -them before switching branches. If you can't easily resolve the problems manually, as a last -resort you can delete the entire `"Foo"` folder and reinstall a fresh copy with [`Pkg.add("Foo")`](@ref). -Naturally, this deletes any changes you've made. - -### [Making a branch *post hoc*](@id man-branch-post-hoc) - -Especially for newcomers to git, one often forgets to create a new branch until after some changes -have already been made. If you haven't yet staged or committed your changes, you can create a -new branch with `git checkout -b ` just as usual--git will kindly show you that some -files have been modified and create the new branch for you. *Your changes have not yet been committed to this new branch*, -so the normal work rules still apply. - -However, if you've already made a commit to `master` but wish to go back to the official `master` -(called `origin/master`), use the following procedure: - - * Create a new branch. This branch will hold your changes. - * Make sure everything is committed to this branch. - * `git checkout master`. If this fails, *do not* proceed further until you have resolved the problems, - or you may lose your changes. - * *Reset*`master` (your current branch) back to an earlier state with `git reset --hard origin/master` - (see [https://git-scm.com/blog/2011/07/11/reset.html](https://git-scm.com/blog/2011/07/11/reset.html)). - -This requires a bit more familiarity with git, so it's much better to get in the habit of creating -a branch at the outset. - -### [Squashing and rebasing](@id man-squashing-and-rebasing) - -Depending on the tastes of the package owner (s)he may ask you to "squash" your commits. This -is especially likely if your change is quite simple but your commit history looks like this: - -``` -WIP: add new 1-line whizbang function (currently breaks package) -Finish whizbang function -Fix typo in variable name -Oops, don't forget to supply default argument -Split into two 1-line functions -Rats, forgot to export the second function -... -``` - -This gets into the territory of more advanced git usage, and you're encouraged to do some reading -([https://git-scm.com/book/en/v2/Git-Branching-Rebasing](https://git-scm.com/book/en/v2/Git-Branching-Rebasing)). - However, a brief summary of the procedure is as follows: - - * To protect yourself from error, start from your `fixbar` branch and create a new branch with - `git checkout -b fixbar_backup`. Since you started from `fixbar`, this will be a copy. Now go - back to the one you intend to modify with `git checkout fixbar`. - * From the shell, type `git rebase -i origin/master`. - * To combine commits, change `pick` to `squash` (for additional options, consult other sources). - Save the file and close the editor window. - * Edit the combined commit message. - -If the rebase goes badly, you can go back to the beginning to try again like this: - -``` -git checkout fixbar -git reset --hard fixbar_backup -``` - -Now let's assume you've rebased successfully. Since your `fixbar` repository has now diverged -from the one in your GitHub fork, you're going to have to do a *force push*: - - * To make it easy to refer to your GitHub fork, create a "handle" for it with `git remote add myfork https://github.com/myaccount/Foo.jl.git`, - where the URL comes from the "clone URL" on your GitHub fork's page. - * Force-push to your fork with `git push myfork +fixbar`. The `+` indicates that this should replace - the `fixbar` branch found at `myfork`. - -## Creating a new Package - -### REQUIRE speaks for itself - -You should have a `REQUIRE` file in your package repository, with a bare minimum directive of -what Julia version you expect your users to be running for the package to work. Putting a floor -on what Julia version your package supports is done by simply adding `julia 0.x` in this file. -While this line is partly informational, it also has the consequence of whether `Pkg.update()` -will update code found in `.julia` version directories. It will not update code found in version -directories beneath the floor of what's specified in your `REQUIRE`. - -As the development version `0.y` matures, you may find yourself using it more frequently, and -wanting your package to support it. Be warned, the development branch of Julia is the land of -breakage, and you can expect things to break. When you go about fixing whatever broke your package -in the development `0.y` branch, you will likely find that you just broke your package on the -stable version. - -There is a mechanism found in the [Compat](https://github.com/JuliaLang/Compat.jl) package that -will enable you to support both the stable version and breaking changes found in the development -version. Should you decide to use this solution, you will need to add `Compat` to your `REQUIRE` -file. In this case, you will still have `julia 0.x` in your `REQUIRE`. The `x` is the floor version -of what your package supports. - -You might also have no interest in supporting the development version of Julia. Just as you can -add a floor to the version you expect your users to be on, you can set an upper bound. In this -case, you would put `julia 0.x 0.y-` in your `REQUIRE` file. The `-` at the end of the version -number means pre-release versions of that specific version from the very first commit. By setting -it as the ceiling, you mean the code supports everything up to but not including the ceiling version. - -Another scenario is that you are writing the bulk of the code for your package with Julia `0.y` -and do not want to support the current stable version of Julia. If you choose to do this, simply -add `julia 0.y-` to your `REQUIRE`. Just remember to change the `julia 0.y-` to `julia 0.y` in -your `REQUIRE` file once `0.y` is officially released. If you don't edit the dash cruft you are -suggesting that you support both the development and stable versions of the same version number! -That would be madness. See the [Requirements Specification](@ref) for the full format of `REQUIRE`. - -Lastly, in many cases you may need extra packages for testing. Additional packages which -are only required for tests should be specified in the `test/REQUIRE` file. This `REQUIRE` -file has the same specification as the standard `REQUIRE` file. - -### Guidelines for naming a package - -Package names should be sensible to most Julia users, *even to those who are not domain experts*. -When you submit your package to METADATA, you can expect a little back and forth about the package -name with collaborators, especially if it's ambiguous or can be confused with something other -than what it is. During this bike-shedding, it's not uncommon to get a range of *different* name -suggestions. These are only suggestions though, with the intent being to keep a tidy namespace -in the curated METADATA repository. Since this repository belongs to the entire community, there -will likely be a few collaborators who care about your package name. Here are some guidelines -to follow in naming your package: - -1. Avoid jargon. In particular, avoid acronyms unless there is minimal possibility of confusion. - - * It's ok to say `USA` if you're talking about the USA. - * It's not ok to say `PMA`, even if you're talking about positive mental attitude. -2. Avoid using `Julia` in your package name. - - * It is usually clear from context and to your users that the package is a Julia package. - * Having Julia in the name can imply that the package is connected to, or endorsed by, contributors - to the Julia language itself. -3. Packages that provide most of their functionality in association with a new type should have pluralized - names. - - * `DataFrames` provides the `DataFrame` type. - * `BloomFilters` provides the `BloomFilter` type. - * In contrast, `JuliaParser` provides no new type, but instead new functionality in the `JuliaParser.parse()` - function. -4. Err on the side of clarity, even if clarity seems long-winded to you. - - * `RandomMatrices` is a less ambiguous name than `RndMat` or `RMT`, even though the latter are shorter. -5. A less systematic name may suit a package that implements one of several possible approaches to - its domain. - - * Julia does not have a single comprehensive plotting package. Instead, `Gadfly`, `PyPlot`, `Winston` - and other packages each implement a unique approach based on a particular design philosophy. - * In contrast, `SortingAlgorithms` provides a consistent interface to use many well-established - sorting algorithms. -6. Packages that wrap external libraries or programs should be named after those libraries or programs. - - * `CPLEX.jl` wraps the `CPLEX` library, which can be identified easily in a web search. - * `MATLAB.jl` provides an interface to call the MATLAB engine from within Julia. - -### Generating the package - -Suppose you want to create a new Julia package called `FooBar`. To get started, do `PkgDev.generate(pkg,license)` -where `pkg` is the new package name and `license` is the name of a license that the package generator -knows about: - -```julia-repl -julia> PkgDev.generate("FooBar","MIT") -INFO: Initializing FooBar repo: /Users/someone/.julia/v0.6/FooBar -INFO: Origin: git://github.com/someone/FooBar.jl.git -INFO: Generating LICENSE.md -INFO: Generating README.md -INFO: Generating src/FooBar.jl -INFO: Generating test/runtests.jl -INFO: Generating REQUIRE -INFO: Generating .travis.yml -INFO: Generating appveyor.yml -INFO: Generating .gitignore -INFO: Committing FooBar generated files -``` - -This creates the directory `~/.julia/v0.6/FooBar`, initializes it as a git repository, generates -a bunch of files that all packages should have, and commits them to the repository: - -``` -$ cd ~/.julia/v0.6/FooBar && git show --stat - -commit 84b8e266dae6de30ab9703150b3bf771ec7b6285 -Author: Some One -Date: Wed Oct 16 17:57:58 2013 -0400 - - FooBar.jl generated files. - - license: MIT - authors: Some One - years: 2013 - user: someone - - Julia Version 0.3.0-prerelease+3217 [5fcfb13*] - - .gitignore | 2 ++ - .travis.yml | 13 +++++++++++++ - LICENSE.md | 22 +++++++++++++++++++++++ - README.md | 3 +++ - REQUIRE | 1 + - appveyor.yml | 34 ++++++++++++++++++++++++++++++++++ - src/FooBar.jl | 5 +++++ - test/runtests.jl | 5 +++++ - 8 files changed, 85 insertions(+) -``` - -At the moment, the package manager knows about the MIT "Expat" License, indicated by `"MIT"`, -the Simplified BSD License, indicated by `"BSD"`, and version 2.0 of the Apache Software License, -indicated by `"ASL"`. If you want to use a different license, you can ask us to add it to the -package generator, or just pick one of these three and then modify the `~/.julia/v0.6/PACKAGE/LICENSE.md` -file after it has been generated. - -If you created a GitHub account and configured git to know about it, `PkgDev.generate()` will -set an appropriate origin URL for you. It will also automatically generate a `.travis.yml` file -for using the [Travis](https://travis-ci.org) automated testing service, and an `appveyor.yml` -file for using [AppVeyor](https://www.appveyor.com). You will have to enable testing on the Travis -and AppVeyor websites for your package repository, but once you've done that, it will already -have working tests. Of course, all the default testing does is verify that `using FooBar` in Julia -works. - -### Loading Static Non-Julia Files - -If your package code needs to load static files which are not Julia code, e.g. an external library -or data files, and are located within the package directory, use the `@__DIR__` macro to determine -the directory of the current source file. For example if `FooBar/src/FooBar.jl` needs to load -`FooBar/data/foo.csv`, use the following code: - -```julia -datapath = joinpath(@__DIR__, "..", "data") -foo = readdlm(joinpath(datapath, "foo.csv"), ',') -``` - -### Making Your Package Available - -Once you've made some commits and you're happy with how `FooBar` is working, you may want to get -some other people to try it out. First you'll need to create the remote repository and push your -code to it; we don't yet automatically do this for you, but we will in the future and it's not -too hard to figure out [^3]. Once you've done this, letting people try out your code is as simple -as sending them the URL of the published repo – in this case: - -``` -git://github.com/someone/FooBar.jl.git -``` - -For your package, it will be your GitHub user name and the name of your package, but you get the -idea. People you send this URL to can use [`Pkg.clone()`](@ref) to install the package and try -it out: - -```julia-repl -julia> Pkg.clone("git://github.com/someone/FooBar.jl.git") -INFO: Cloning FooBar from git@github.com:someone/FooBar.jl.git -``` - -[^3]: - Installing and using GitHub's ["hub" tool](https://github.com/github/hub) is highly recommended. - It allows you to do things like run `hub create` in the package repo and have it automatically - created via GitHub's API. - -### Tagging and Publishing Your Package - -!!! tip - If you are hosting your package on GitHub, you can use the [attobot integration](https://github.com/attobot/attobot) - to handle package registration, tagging and publishing. - -Once you've decided that `FooBar` is ready to be registered as an official package, you can add -it to your local copy of `METADATA` using `PkgDev.register()`: - -```julia-repl -julia> PkgDev.register("FooBar") -INFO: Registering FooBar at git://github.com/someone/FooBar.jl.git -INFO: Committing METADATA for FooBar -``` - -This creates a commit in the `~/.julia/v0.6/METADATA` repo: - -``` -$ cd ~/.julia/v0.6/METADATA && git show - -commit 9f71f4becb05cadacb983c54a72eed744e5c019d -Author: Some One -Date: Wed Oct 16 18:46:02 2013 -0400 - - Register FooBar - -diff --git a/FooBar/url b/FooBar/url -new file mode 100644 -index 0000000..30e525e ---- /dev/null -+++ b/FooBar/url -@@ -0,0 +1 @@ -+git://github.com/someone/FooBar.jl.git -``` - -This commit is only locally visible, however. To make it visible to the Julia community, you -need to merge your local `METADATA` upstream into the official repo. The `PkgDev.publish()` command -will fork the `METADATA` repository on GitHub, push your changes to your fork, and open a pull -request: - -```julia-repl -julia> PkgDev.publish() -INFO: Validating METADATA -INFO: No new package versions to publish -INFO: Submitting METADATA changes -INFO: Forking JuliaLang/METADATA.jl to someone -INFO: Pushing changes as branch pull-request/ef45f54b -INFO: To create a pull-request open: - - https://github.com/someone/METADATA.jl/compare/pull-request/ef45f54b -``` - -!!! tip - If `PkgDev.publish()` fails with error: - - ``` - ERROR: key not found: "token" - ``` - - then you may have encountered an issue from using the GitHub API on multiple systems. The solution - is to delete the "Julia Package Manager" personal access token [from your Github account](https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2Fsettings%2Ftokens) - and try again. - - Other failures may require you to circumvent `PkgDev.publish()` by [creating a pull request on GitHub](https://help.github.com/articles/creating-a-pull-request/). - See: [Publishing METADATA manually](@ref) below. - -Once the package URL for `FooBar` is registered in the official `METADATA` repo, people know where -to clone the package from, but there still aren't any registered versions available. You can tag -and register it with the `PkgDev.tag()` command: - -```julia-repl -julia> PkgDev.tag("FooBar") -INFO: Tagging FooBar v0.0.1 -INFO: Committing METADATA for FooBar -``` - -This tags `v0.0.1` in the `FooBar` repo: - -``` -$ cd ~/.julia/v0.6/FooBar && git tag -v0.0.1 -``` - -It also creates a new version entry in your local `METADATA` repo for `FooBar`: - -``` -$ cd ~/.julia/v0.6/FooBar && git show -commit de77ee4dc0689b12c5e8b574aef7f70e8b311b0e -Author: Some One -Date: Wed Oct 16 23:06:18 2013 -0400 - - Tag FooBar v0.0.1 - -diff --git a/FooBar/versions/0.0.1/sha1 b/FooBar/versions/0.0.1/sha1 -new file mode 100644 -index 0000000..c1cb1c1 ---- /dev/null -+++ b/FooBar/versions/0.0.1/sha1 -@@ -0,0 +1 @@ -+84b8e266dae6de30ab9703150b3bf771ec7b6285 -``` - -The `PkgDev.tag()` command takes an optional second argument that is either an explicit version -number object like `v"0.0.1"` or one of the symbols `:patch`, `:minor` or `:major`. These increment -the patch, minor or major version number of your package intelligently. - -Adding a tagged version of your package will expedite the official registration into METADATA.jl -by collaborators. It is strongly recommended that you complete this process, regardless if your -package is completely ready for an official release. - -As a general rule, packages should be tagged `0.0.1` first. Since Julia itself hasn't achieved -`1.0` status, it's best to be conservative in your package's tagged versions. - -As with `PkgDev.register()`, these changes to `METADATA` aren't available to anyone else until -they've been included upstream. Again, use the `PkgDev.publish()` command, which first makes sure -that individual package repos have been tagged, pushes them if they haven't already been, and -then opens a pull request to `METADATA`: - -```julia-repl -julia> PkgDev.publish() -INFO: Validating METADATA -INFO: Pushing FooBar permanent tags: v0.0.1 -INFO: Submitting METADATA changes -INFO: Forking JuliaLang/METADATA.jl to someone -INFO: Pushing changes as branch pull-request/3ef4f5c4 -INFO: To create a pull-request open: - - https://github.com/someone/METADATA.jl/compare/pull-request/3ef4f5c4 -``` - -#### Publishing METADATA manually - -If `PkgDev.publish()` fails you can follow these instructions to manually publish your package. - -By "forking" the main METADATA repository, you can create a personal copy (of METADATA.jl) under -your GitHub account. Once that copy exists, you can push your local changes to your copy (just -like any other GitHub project). - -1. Create a [fork of METADATA.jl](https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2FJuliaLang%2FMETADATA.jl%2Ffork). - -2. Add your fork as a remote repository for the METADATA repository on your local computer (in - the terminal where USERNAME is your github username): - - cd ~/.julia/v0.6/METADATA - git remote add USERNAME https://github.com/USERNAME/METADATA.jl.git - -3. Push your changes to your fork: - - git push USERNAME metadata-v2 - -4. If all of that works, then go back to the GitHub page for your fork, and click the "pull request" - link. - -## Fixing Package Requirements - -If you need to fix the registered requirements of an already-published package version, you can -do so just by editing the metadata for that version, which will still have the same commit hash -– the hash associated with a version is permanent: - -``` -$ cd ~/.julia/v0.6/METADATA/FooBar/versions/0.0.1 && cat requires -julia 0.3- -$ vi requires -``` - -Since the commit hash stays the same, the contents of the `REQUIRE` file that will be checked -out in the repo will **not** match the requirements in `METADATA` after such a change; this is -unavoidable. When you fix the requirements in `METADATA` for a previous version of a package, -however, you should also fix the `REQUIRE` file in the current version of the package. - -## Requirements Specification - -The `~/.julia/v0.6/REQUIRE` file, the `REQUIRE` file inside packages, and the `METADATA` package -`requires` files use a simple line-based format to express the ranges of package versions which -need to be installed. Package `REQUIRE` and `METADATA requires` files should also include the -range of versions of `julia` the package is expected to work with. Additionally, packages can -include a `test/REQUIRE` file to specify additional packages which are only required for testing. - -Here's how these files are parsed and interpreted. - - * Everything after a `#` mark is stripped from each line as a comment. - * If nothing but whitespace is left, the line is ignored. - * If there are non-whitespace characters remaining, the line is a requirement and the is split on - whitespace into words. - -The simplest possible requirement is just the name of a package name on a line by itself: - -```julia -Distributions -``` - -This requirement is satisfied by any version of the `Distributions` package. The package name -can be followed by zero or more version numbers in ascending order, indicating acceptable intervals -of versions of that package. One version opens an interval, while the next closes it, and the -next opens a new interval, and so on; if an odd number of version numbers are given, then arbitrarily -large versions will satisfy; if an even number of version numbers are given, the last one is an -upper limit on acceptable version numbers. For example, the line: - -``` -Distributions 0.1 -``` - -is satisfied by any version of `Distributions` greater than or equal to `0.1.0`. Suffixing a version -with `-` allows any pre-release versions as well. For example: - -``` -Distributions 0.1- -``` - -is satisfied by pre-release versions such as `0.1-dev` or `0.1-rc1`, or by any version greater -than or equal to `0.1.0`. - -This requirement entry: - -``` -Distributions 0.1 0.2.5 -``` - -is satisfied by versions from `0.1.0` up to, but not including `0.2.5`. If you want to indicate -that any `0.1.x` version will do, you will want to write: - -``` -Distributions 0.1 0.2- -``` - -If you want to start accepting versions after `0.2.7`, you can write: - -``` -Distributions 0.1 0.2- 0.2.7 -``` - -If a requirement line has leading words that begin with `@`, it is a system-dependent requirement. -If your system matches these system conditionals, the requirement is included, if not, the requirement -is ignored. For example: - -``` -@osx Homebrew -``` - -will require the `Homebrew` package only on systems where the operating system is OS X. The system -conditions that are currently supported are (hierarchically): - - * `@unix` - - * `@linux` - * `@bsd` - - * `@osx` - * `@windows` - -The `@unix` condition is satisfied on all UNIX systems, including Linux and BSD. Negated system -conditionals are also supported by adding a `!` after the leading `@`. Examples: - -``` -@!windows -@unix @!osx -``` - -The first condition applies to any system but Windows and the second condition applies to any -UNIX system besides OS X. - -Runtime checks for the current version of Julia can be made using the built-in `VERSION` variable, -which is of type [`VersionNumber`](@ref). Such code is occasionally necessary to keep track of new or -deprecated functionality between various releases of Julia. Examples of runtime checks: - -```julia -VERSION < v"0.3-" #exclude all pre-release versions of 0.3 - -v"0.2-" <= VERSION < v"0.3-" #get all 0.2 versions, including pre-releases, up to the above - -v"0.2" <= VERSION < v"0.3-" #To get only stable 0.2 versions (Note v"0.2" == v"0.2.0") - -VERSION >= v"0.2.1" #get at least version 0.2.1 -``` - -See the section on [version number literals](@ref man-version-number-literals) for a more complete description. diff --git a/src/manual/parallel-computing.md b/src/manual/parallel-computing.md index 82cb498..640a3e3 100644 --- a/src/manual/parallel-computing.md +++ b/src/manual/parallel-computing.md @@ -457,7 +457,7 @@ we could compute the singular values of several large random matrices in paralle ```julia-repl julia> M = Matrix{Float64}[rand(1000,1000) for i = 1:10]; -julia> pmap(svd, M); +julia> pmap(svdvals, M); ``` Julia's [`pmap`](@ref) is designed for the case where each function call does a large amount @@ -486,7 +486,7 @@ As an example, consider computing the singular values of matrices of different s ```julia-repl julia> M = Matrix{Float64}[rand(800,800), rand(600,600), rand(800,800), rand(600,600)]; -julia> pmap(svd, M); +julia> pmap(svdvals, M); ``` If one process handles both 800×800 matrices and another handles both 600×600 matrices, we will diff --git a/src/manual/performance-tips.md b/src/manual/performance-tips.md index ff8ecd5..1ecac2d 100644 --- a/src/manual/performance-tips.md +++ b/src/manual/performance-tips.md @@ -544,7 +544,7 @@ function norm(A) if isa(A, Vector) return sqrt(real(dot(A,A))) elseif isa(A, Matrix) - return maximum(svd(A)[2]) + return maximum(svdvals(A)) else error("norm: invalid argument") end @@ -555,7 +555,7 @@ This can be written more concisely and efficiently as: ```julia norm(x::Vector) = sqrt(real(dot(x,x))) -norm(A::Matrix) = maximum(svd(A)[2]) +norm(A::Matrix) = maximum(svdvals(A)) ``` ## Write "type-stable" functions diff --git a/src/stdlib/LinearAlgebra.md b/src/stdlib/LinearAlgebra.md index 8ccffe5..a78fdfa 100644 --- a/src/stdlib/LinearAlgebra.md +++ b/src/stdlib/LinearAlgebra.md @@ -198,7 +198,7 @@ Legend: ### Matrix factorizations -| Matrix type | LAPACK | [`eig`](@ref) | [`eigvals`](@ref) | [`eigvecs`](@ref) | [`svd`](@ref) | [`svdvals`](@ref) | +| Matrix type | LAPACK | [`eigen`](@ref) | [`eigvals`](@ref) | [`eigvecs`](@ref) | [`svd`](@ref) | [`svdvals`](@ref) | |:------------------------- |:------ |:------------- |:----------------- |:----------------- |:------------- |:----------------- | | [`Symmetric`](@ref) | SY | | ARI | | | | | [`Hermitian`](@ref) | HE | | ARI | | | | @@ -312,47 +312,40 @@ LinearAlgebra.LowerTriangular LinearAlgebra.UpperTriangular LinearAlgebra.UniformScaling LinearAlgebra.lu -LinearAlgebra.lufact -LinearAlgebra.lufact! +LinearAlgebra.lu! LinearAlgebra.chol -LinearAlgebra.cholfact -LinearAlgebra.cholfact! +LinearAlgebra.cholesky +LinearAlgebra.cholesky! LinearAlgebra.lowrankupdate LinearAlgebra.lowrankdowndate LinearAlgebra.lowrankupdate! LinearAlgebra.lowrankdowndate! -LinearAlgebra.ldltfact -LinearAlgebra.ldltfact! +LinearAlgebra.ldlt +LinearAlgebra.ldlt! LinearAlgebra.qr LinearAlgebra.qr! -LinearAlgebra.qrfact -LinearAlgebra.qrfact! LinearAlgebra.QR LinearAlgebra.QRCompactWY LinearAlgebra.QRPivoted -LinearAlgebra.lqfact! -LinearAlgebra.lqfact +LinearAlgebra.lq! LinearAlgebra.lq -LinearAlgebra.bkfact -LinearAlgebra.bkfact! -LinearAlgebra.eig +LinearAlgebra.bunchkaufman +LinearAlgebra.bunchkaufman! LinearAlgebra.eigvals LinearAlgebra.eigvals! LinearAlgebra.eigmax LinearAlgebra.eigmin LinearAlgebra.eigvecs -LinearAlgebra.eigfact -LinearAlgebra.eigfact! -LinearAlgebra.hessfact -LinearAlgebra.hessfact! -LinearAlgebra.schurfact -LinearAlgebra.schurfact! +LinearAlgebra.eigen +LinearAlgebra.eigen! +LinearAlgebra.hessenberg +LinearAlgebra.hessenberg! +LinearAlgebra.schur! LinearAlgebra.schur LinearAlgebra.ordschur LinearAlgebra.ordschur! -LinearAlgebra.svdfact -LinearAlgebra.svdfact! LinearAlgebra.svd +LinearAlgebra.svd! LinearAlgebra.svdvals LinearAlgebra.svdvals! LinearAlgebra.Givens diff --git a/src/stdlib/Pkg.md b/src/stdlib/Pkg.md index 47f3f96..9d8651a 100644 --- a/src/stdlib/Pkg.md +++ b/src/stdlib/Pkg.md @@ -1,38 +1,411 @@ -# Package Manager Functions - -```@meta -DocTestSetup = :(using Pkg) -``` - -All package manager functions are defined in the `Pkg` module. None of the `Pkg` module's functions -are exported; to use them, you'll need to prefix each function call with an explicit `Pkg.`, e.g. -[`Pkg.status()`](@ref) or [`Pkg.dir()`](@ref). - -Functions for package development (e.g. `tag`, `publish`, etc.) have been moved to the [PkgDev](https://github.com/JuliaLang/PkgDev.jl) -package. See [PkgDev README](https://github.com/JuliaLang/PkgDev.jl/blob/master/README.md) for -the documentation of those functions. - -```@docs -Pkg.dir -Pkg.init -Pkg.resolve -Pkg.edit -Pkg.add -Pkg.rm -Pkg.clone -Pkg.setprotocol! -Pkg.available -Pkg.installed -Pkg.status -Pkg.update -Pkg.checkout -Pkg.pin -Pkg.free -Pkg.build -Pkg.test -Pkg.dependents -``` - -```@meta -DocTestSetup = nothing +# Pkg + +!!! warning + This documentation is a work in progress and the information in it might be or become outdated. + +## Introduction + +Pkg is the standard package manager for Julia 1.0 and newer. Unlike traditional +package managers, which install and manage a single global set of packages, Pkg +is designed around “environments”: independent sets of packages that can be +local to an individual project or shared and selected by name. The exact set of +packages and versions in an environment is captured in a _manifest file_ which +can be checked into a project repository and tracked in version control, +significantly improving reproducibility of projects. If you’ve ever tried to run +code you haven’t used in a while only to find that you can’t get anything to +work because you’ve updated or uninstalled some of the packages your project was +using, you’ll understand the motivation for this approach. In Pkg, since each +project maintains its own independent set of package versions, you’ll never have +this problem again. Moreover, if you check out a project on a new system, you +can simply materialize the environment described by its manifest file and +immediately be up and running with a known-good set of dependencies. + +Since environments are managed and updated independently from each other, +“dependency hell” is significantly alleviated in Pkg. If you want to use the +latest and greatest version of some package in a new project but you’re stuck on +an older version in a different project, that’s no problem – since they have +separate environments they can just use different versions, which are both +installed at the same time in different locations on your system. The location +of each package version is canonical, so when environments use the same versions +of packages, they can share installations, avoiding unnecessary duplication of +the package. Old package versions that are no longer used by any environments +are periodically “garbage collected” by the package manager. + +Pkg’s approach to local environments may be familiar to people who have used +Python’s `virtualenv` or Ruby’s `bundler`. In Julia, instead of hacking the +language’s code loading mechanisms to support environments, we have the benefit +that Julia natively understands them. In addition, Julia environments are +“stackable”: you can overlay one environment with another and thereby have +access to additional packages outside of the primary environment. This makes it +easy to work on a project, which provides the primary environment, while still +having access to all your usual dev tools like profilers, debuggers, and so on, +just by having an environment including these dev tools later in the load path. + +Last but not least, Pkg is designed to support federated package registries. +This means that it allows multiple registries managed by different parties to +interact seamlessly. In particular, this includes private registries which can +live behind corporate firewalls. You can install and update your own packages +from a private registry with exactly the same tools and workflows that you use +to install and manage official Julia packages. If you urgently need to apply a +hotfix for a public package that’s critical to your company’s product, you can +tag a private version of it in your company’s internal registry and get a fix to +your developers and ops teams quickly and easily without having to wait for an +upstream patch to be accepted and published. Once an official fix is published, +however, you can just upgrade your dependencies and you'll be back on an +official release again. + +## Glossary + +**Project:** a source tree with a standard layout, including a `src` directory +for the main body of Julia code, a `test` directory for testing the project, +`docs` for documentation files, and optionally a `build` directory for a build +script and its outputs. A project will typically also have a project file and +may optionally have a manifest file: + +- **Project file:** a file in the root directory of a project, named + `Project.toml` (or `JuliaProject.toml`) describing metadata about the project, + including its name, UUID (for packages), authors, license, and the names and + UUIDs of packages and libraries that it depends on. + +- **Manifest file:** a file in the root directory of a project, named + `Manifest.toml` (or `JuliaManifest.toml`) describing a complete dependency graph + and exact versions of each package and library used by a project. + +**Package:** a project which provides reusable functionality that can be used by +other Julia projects via `import X` or `using X`. A package should have a +project file with a `uuid` entry giving its package UUID. This UUID is used to +identify the package in projects that depend on it. + +!!! note + For legacy reasons it is possible to load a package without a project file or + UUID from the REPL or the top-level of a script. It is not possible, however, + to load a package without a project file or UUID from a project with them. Once + you've loaded from a project file, everything needs a project file and UUID. + +**Application:** a project which provides standalone functionality not intended +to be reused by other Julia projects. For example a web application or a +commmand-line utility. An application may have a UUID but does not need one. An +application may also provide global configuration options for packages it +depends on. Packages, on the other hand, may not provide global configuration +since that could conflict with the configuration of the main application. + +!!! note + **Projects _vs._ Packages _vs._ Applications:** + + 1. Project is an umbrella term: packages and applications are kinds of projects. + 2. Packages should have UUIDs, applications can have a UUIDs but don't need them. + 3. Applications can provide global configuration, whereas packages cannot. + +**Library (future work):** a compiled binary dependency (not written in Julia) +packaged to be used by a Julia project. These are currently typically built in- +place by a `deps/build.jl` script in a project’s source tree, but in the future +we plan to make libraries first-class entities directly installed and upgraded +by the package manager. + +**Environment:** the combination of the top-level name map provided by a project +file combined with the dependency graph and map from packages to their entry points +provided by a manifest file. For more detail see the manual section on code loading. + +- **Explicit environment:** an environment in the form of an explicit project + file and an optional corresponding manifest file together in a directory. If the + manifest file is absent then the implied dependency graph and location maps are + empty. + +- **Implicit environment:** an environment provided as a directory (without a + project file or manifest file) containing packages with entry points of the form + `X.jl`, `X.jl/src/X.jl` or `X/src/X.jl`. The top-level name map is implied by + these entry points. The dependency graph is implied by the existence of project + files inside of these package directories, e.g. `X.jl/Project.toml` or + `X/Project.toml`. The dependencies of the `X` package are the dependencies in + the corresponding project file if there is one. The location map is implied by + the entry points themselves. + +**Registry:** a source tree with a standard layout recording metadata about a +registered set of packages, the tagged versions of them which are available, and +which versions of packages are compatible or incompatible with each other. A +registry is indexed by package name and UUID, and has a directory for each +registered package providing the following metadata about it: + +- name – e.g. `DataFrames` +- UUID – e.g. `a93c6f00-e57d-5684-b7b6-d8193f3e46c0` +- authors – e.g. `Jane Q. Developer ` +- license – e.g. MIT, BSD3, or GPLv2 +- repository – e.g. `https://github.com/JuliaData/DataFrames.jl.git` +- description – a block of text summarizing the functionality of a package +- keywords – e.g. `data`, `tabular`, `analysis`, `statistics` +- versions – a list of all registered version tags + +For each registered version of a package, the following information is provided: + +- its semantic version number – e.g. `v1.2.3` +- its git tree SHA-1 hash – e.g. `7ffb18ea3245ef98e368b02b81e8a86543a11103` +- a map from names to UUIDs of dependencies +- which versions of other packages it is compatible/incompatible with + +Dependencies and compatibility are stored in a compressed but human-readable +format using ranges of package versions. + +**Depot:** a directory on a system where various package-related resources live, +including: + +- `environments`: shared named environments (e.g. `v0.7`, `devtools`) +- `clones`: bare clones of package repositories +- `compiled`: cached compiled package images (`.ji` files) +- `config`: global configuration files (e.g. `startup.jl`) +- `dev`: default directory for package development +- `logs`: log files (e.g. `manifest_usage.toml`, `repl_history.jl`) +- `packages`: installed package versions +- `registries`: clones of registries (e.g. `Uncurated`) + +**Load path:** a stack of environments where package identities, their +dependencies, and entry-points are searched for. The load path is controlled in +Julia by the `LOAD_PATH` global variable which is populated at startup based on +the value of the `JULIA_LOAD_PATH` environment variable. The first entry is your +primary environment, often the current project, while later entries provide +additional packages one may want to use from the REPL or top-level scripts. + +**Depot path:** a stack of depot locations where the package manager, as well as +Julia's code loading mechanisms, look for registries, installed packages, named +environments, repo clones, cached compiled package images, and configuration +files. The depot path is controlled by the Julia `DEPOT_PATH` global variable +which is populated at startup based on the value of the `JULIA_DEPOT_PATH` +environment variable. The first entry is the “user depot” and should be writable +by and owned by the current user. The user depot is where: registries are +cloned, new package versions are installed, named environments are created and +updated, package repos are cloned, new compiled package image files are saved, +log files are written, development packages are checked out by default, and +global configuration data is saved. Later entries in the depot path are treated +as read-only and are appropriate for registries, packages, etc. installed and +managed by system administrators. + +## Getting Started + +The Pkg REPL-mode is entered from the Julia REPL using the key `]`. + +``` +(v0.7) pkg> +``` + +The part inside the parenthesis of the prompt shows the name of the current project. +Since we haven't created our own project yet, we are in the default project, located at `~/.julia/environments/v0.7` +(or whatever version of Julia you happen to run). + +To return to the `julia>` prompt, either press backspace when the input line is empty or press Ctrl+C. +Help is available by calling `pkg> help`. + +To generate files for a new project, use `pkg> generate`. + +``` +(v0.7) pkg> generate HelloWorld +``` + +This creates a new project `HelloWorld` with the following files (visualized with the external [`tree` command](https://linux.die.net/man/1/tree)): + +```jl +julia> cd("HelloWorld") +shell> tree . +. +├── Project.toml +└── src + └── HelloWorld.jl + +1 directory, 2 files ``` + +The `Project.toml` file contains the name of the package, its unique UUID, its version, the author and eventual dependencies: + +```toml +name = "HelloWorld" +uuid = "b4cd1eb8-1e24-11e8-3319-93036a3eb9f3" +version = "0.1.0" +author = ["Some One "] + +[deps] +``` + +The content of `src/HelloWorld.jl` is: + +```jl +module HelloWorld + +greet() = print("Hello World!") + +end # module +``` + +We can now load the project and use it: + +```jl +julia> import HelloWorld + +julia> HelloWorld.greet() +Hello World! +``` + +### Adding packages to the project + +Let’s say we want to use the standard library package `Random` and the registered package `JSON` in our project. +We simply `add` these packages (note how the prompt now shows the name of the newly generated project, +since we are inside the `HelloWorld` project directory): + +``` +(HelloWorld) pkg> add Random JSON + Resolving package versions... + Updating "~/Documents/HelloWorld/Project.toml" + [682c06a0] + JSON v0.17.1 + [9a3f8284] + Random + Updating "~/Documents/HelloWorld/Manifest.toml" + [34da2185] + Compat v0.57.0 + [682c06a0] + JSON v0.17.1 + [4d1e1d77] + Nullables v0.0.4 + ... +``` + +Both `Random` and `JSON` got added to the project’s `Project.toml` file, and the resulting dependencies got added to the `Manifest.toml` file. +The resolver has installed each package with the highest possible version, while still respecting the compatibility that each package enforce on its dependencies. + +We can now use both `Random` and `JSON` in our project. Changing `src/HelloWorld.jl` to + +``` +module HelloWorld + +import Random +import JSON + +greet() = print("Hello World!") +greet_alien() = print("Hello ", Random.randstring(8)) + +end # module +``` + +and reloading the package, the new `greet_alien` function that uses `Random` can be used: + +``` +julia> HelloWorld.greet_alien() +Hello aT157rHV +``` + +Sometimes we might want to use the very latest, unreleased version of a package, or perhaps a specific branch in the package +git repository. We can use e.g. the `master` branch of `JSON` by specifying the branch after a `#` when adding the package: + +``` +(HelloWorld) pkg> add JSON#master + Cloning package from https://github.com/JuliaIO/JSON.jl.git + Resolving package versions... + Updating "~/Documents/HelloWorld/Project.toml" + [682c06a0] ~ JSON v0.17.1 ⇒ v0.17.1+ #master + Updating "~/Documents/HelloWorld/Manifest.toml" + [682c06a0] ~ JSON v0.17.1 ⇒ v0.17.1+ #master +``` + +If we want to use a package that has not been registered in a registry, we can `add` its git repository url: + +``` +(HelloWorld) pkg> add https://github.com/fredrikekre/ImportMacros.jl + Cloning package from https://github.com/fredrikekre/ImportMacros.jl + Resolving package versions... +Downloaded MacroTools ─ v0.4.0 + Updating "~/Documents/HelloWorld/Project.toml" + [5adcef86] + ImportMacros v0.1.0 #master + Updating "~/Documents/HelloWorld/Manifest.toml" + [5adcef86] + ImportMacros v0.1.0 #master + [1914dd2f] + MacroTools v0.4.0 +``` + +The dependencies of the unregistered package (here `MacroTools`) got installed. +For unregistered packages we could have given a branch (or commit SHA) to track using `#`, just like for registered packages. + + +## Developing packages + +Let’s say we found a bug in one of our dependencies, e.g. `JSON` that we want to fix. We can get the full git-repo using the `develop` command + +``` +(HelloWorld) pkg> develop JSON + Cloning package from https://github.com/JuliaIO/JSON.jl.git + Resolving package versions... + Updating "~/Documents/HelloWorld/Project.toml" + [682c06a0] + JSON v0.17.1+ [~/.julia/dev/JSON] +... +``` + +By default, the package get cloned to the `~/.julia/dev` folder but can also be set by the `JULIA_PKG_DEVDIR` environment variable. +When we have fixed the bug and checked that `JSON` now works correctly with our project, we can make a PR to the `JSON` repository. +When the PR has been merged we can go over to track the master branch and finally, when a new release of `JSON` is made, we can go back to using the versioned `JSON` using the command `free` and `update` (see next section): + +``` +(HelloWorld) pkg> free JSON + Resolving package versions... + Updating "~/Documents/HelloWorld/Project.toml" + [682c06a0] ~ JSON v0.17.1+ #master ⇒ v0.17.1 + Updating "~/Documents/HelloWorld/Manifest.toml" + [682c06a0] ~ JSON v0.17.1+ #master ⇒ v0.17.1 +``` + +It is also possible to give a local path as the argument to `develop` which will not clone anything but simply use that directory for the package. + +Overriding the dependency path for a non registered package is done by giving the git-repo url as an argument to `develop`. + +## Updating dependencies + +When new versions of packages the project is using are released, it is a good idea to update. Simply calling `up` will try to update *all* the dependencies of the project. Sometimes this is not what you want. You can specify a subset of the dependencies to upgrade by giving them as arguments to `up`, e.g: + +``` +(HelloWorld) pkg> up JSON +``` + +The version of all other direct dependencies will stay the same. If you only want to update the minor version of packages, to reduce the risk that your project breaks, you can give the `--minor` flag, e.g: + +``` +(HelloWorld) pkg> up --minor JSON +``` + +Packages that track a branch are not updated when a minor upgrade is done. +Developed packages are never touched by the package manager. + +If you just want install the packages that are given by the current `Manifest.toml` use + +``` +(HelloWorld) pkg> instantiate +``` + +## Precompiling the project + +The REPL command `precompile` can be used to precompile all the dependencies in the project. You can for example do + +``` +(HelloWorld) pkg> update; precompile +``` + +do update the dependencies and then precompile them. + +## Preview mode + +If you just want to see the effects of running a command, but not change your state you can `preview` a command. +For example: + +``` +(HelloWorld) pkg> preview add Plots +``` + +or + +``` +(HelloWorld) pkg> preview up +``` + +will show you the effects adding `Plots`, or doing a full upgrade, respectively, would have on your project. +However, nothing would be installed and your `Project.toml` and `Manfiest.toml` are untouched. + +## Using someone elses project + +Simple clone their project using e.g. `git clone`, `cd` to the project directory and call + +``` +(SomeProject) pkg> instantiate +``` + +If the project contains a manifest, this will install the packages at the same state that is given by that manifest. +Otherwise it will resolve the latest versions of the dependencies compatible with the project. + + diff --git a/src/stdlib/Pkg3.md b/src/stdlib/Pkg3.md deleted file mode 100644 index 26e98f8..0000000 --- a/src/stdlib/Pkg3.md +++ /dev/null @@ -1,418 +0,0 @@ -# Pkg3.jl - -!!! warning - This documentation is a work in progress and the information in it might be or become outdated. - -Sections: - -```@contents -Pages = [ - "index.md"] -``` - -## Introduction - -Pkg3 is the standard package manager for Julia 1.0 and newer. Unlike traditional -package managers, which install and manage a single global set of packages, Pkg3 -is designed around “environments”: independent sets of packages that can be -local to an individual project or shared and selected by name. The exact set of -packages and versions in an environment is captured in a _manifest file_ which -can be checked into a project repository and tracked in version control, -significantly improving reproducibility of projects. If you’ve ever tried to run -code you haven’t used in a while only to find that you can’t get anything to -work because you’ve updated or uninstalled some of the packages your project was -using, you’ll understand the motivation for this approach. In Pkg3, since each -project maintains its own independent set of package versions, you’ll never have -this problem again. Moreover, if you check out a project on a new system, you -can simply materialize the environment described by its manifest file and -immediately be up and running with a known-good set of dependencies. - -Since environments are managed and updated independently from each other, -“dependency hell” is significantly alleviated in Pkg3. If you want to use the -latest and greatest version of some package in a new project but you’re stuck on -an older version in a different project, that’s no problem – since they have -separate environments they can just use different versions, which are both -installed at the same time in different locations on your system. The location -of each package version is canonical, so when environments use the same versions -of packages, they can share installations, avoiding unnecessary duplication of -the package. Old package versions that are no longer used by any environments -are periodically “garbage collected” by the package manager. - -Pkg3’s approach to local environments may be familiar to people who have used -Python’s `virtualenv` or Ruby’s `bundler`. In Julia, instead of hacking the -language’s code loading mechanisms to support environments, we have the benefit -that Julia natively understands them. In addition, Julia environments are -“stackable”: you can overlay one environment with another and thereby have -access to additional packages outside of the primary environment. This makes it -easy to work on a project, which provides the primary environment, while still -having access to all your usual dev tools like profilers, debuggers, and so on, -just by having an environment including these dev tools later in the load path. - -Last but not least, Pkg3 is designed to support federated package registries. -This means that it allows multiple registries managed by different parties to -interact seamlessly. In particular, this includes private registries which can -live behind corporate firewalls. You can install and update your own packages -from a private registry with exactly the same tools and workflows that you use -to install and manage official Julia packages. If you urgently need to apply a -hotfix for a public package that’s critical to your company’s product, you can -tag a private version of it in your company’s internal registry and get a fix to -your developers and ops teams quickly and easily without having to wait for an -upstream patch to be accepted and published. Once an official fix is published, -however, you can just upgrade your dependencies and you'll be back on an -official release again. - -## Glossary - -**Project:** a source tree with a standard layout, including a `src` directory -for the main body of Julia code, a `test` directory for testing the project, -`docs` for documentation files, and optionally a `build` directory for a build -script and its outputs. A project will typically also have a project file and -may optionally have a manifest file: - -- **Project file:** a file in the root directory of a project, named - `Project.toml` (or `JuliaProject.toml`) describing metadata about the project, - including its name, UUID (for packages), authors, license, and the names and - UUIDs of packages and libraries that it depends on. - -- **Manifest file:** a file in the root directory of a project, named - `Manifest.toml` (or `JuliaManifest.toml`) describing a complete dependency graph - and exact versions of each package and library used by a project. - -**Package:** a project which provides reusable functionality that can be used by -other Julia projects via `import X` or `using X`. A package should have a -project file with a `uuid` entry giving its package UUID. This UUID is used to -identify the package in projects that depend on it. - -!!! note - For legacy reasons it is possible to load a package without a project file or - UUID from the REPL or the top-level of a script. It is not possible, however, - to load a package without a project file or UUID from a project with them. Once - you've loaded from a project file, everything needs a project file and UUID. - -**Application:** a project which provides standalone functionality not intended -to be reused by other Julia projects. For example a web application or a -commmand-line utility. An application may have a UUID but does not need one. An -application may also provide global configuration options for packages it -depends on. Packages, on the other hand, may not provide global configuration -since that could conflict with the configuration of the main application. - -!!! note - **Projects _vs._ Packages _vs._ Applications:** - - 1. Project is an umbrella term: packages and applications are kinds of projects. - 2. Packages should have UUIDs, applications can have a UUIDs but don't need them. - 3. Applications can provide global configuration, whereas packages cannot. - -**Library (future work):** a compiled binary dependency (not written in Julia) -packaged to be used by a Julia project. These are currently typically built in- -place by a `deps/build.jl` script in a project’s source tree, but in the future -we plan to make libraries first-class entities directly installed and upgraded -by the package manager. - -**Environment:** the combination of the top-level name map provided by a project -file combined with the dependency graph and map from packages to their entry points -provided by a manifest file. For more detail see the manual section on code loading. - -- **Explicit environment:** an environment in the form of an explicit project - file and an optional corresponding manifest file together in a directory. If the - manifest file is absent then the implied dependency graph and location maps are - empty. - -- **Implicit environment:** an environment provided as a directory (without a - project file or manifest file) containing packages with entry points of the form - `X.jl`, `X.jl/src/X.jl` or `X/src/X.jl`. The top-level name map is implied by - these entry points. The dependency graph is implied by the existence of project - files inside of these package directories, e.g. `X.jl/Project.toml` or - `X/Project.toml`. The dependencies of the `X` package are the dependencies in - the corresponding project file if there is one. The location map is implied by - the entry points themselves. - -**Registry:** a source tree with a standard layout recording metadata about a -registered set of packages, the tagged versions of them which are available, and -which versions of packages are compatible or incompatible with each other. A -registry is indexed by package name and UUID, and has a directory for each -registered package providing the following metadata about it: - -- name – e.g. `DataFrames` -- UUID – e.g. `a93c6f00-e57d-5684-b7b6-d8193f3e46c0` -- authors – e.g. `Jane Q. Developer ` -- license – e.g. MIT, BSD3, or GPLv2 -- repository – e.g. `https://github.com/JuliaData/DataFrames.jl.git` -- description – a block of text summarizing the functionality of a package -- keywords – e.g. `data`, `tabular`, `analysis`, `statistics` -- versions – a list of all registered version tags - -For each registered version of a package, the following information is provided: - -- its semantic version number – e.g. `v1.2.3` -- its git tree SHA-1 hash – e.g. `7ffb18ea3245ef98e368b02b81e8a86543a11103` -- a map from names to UUIDs of dependencies -- which versions of other packages it is compatible/incompatible with - -Dependencies and compatibility are stored in a compressed but human-readable -format using ranges of package versions. - -**Depot:** a directory on a system where various package-related resources live, -including: - -- `environments`: shared named environments (e.g. `v0.7`, `devtools`) -- `clones`: bare clones of package repositories -- `compiled`: cached compiled package images (`.ji` files) -- `config`: global configuration files (e.g. `startup.jl`) -- `dev`: default directory for package development -- `logs`: log files (e.g. `manifest_usage.toml`, `repl_history.jl`) -- `packages`: installed package versions -- `registries`: clones of registries (e.g. `Uncurated`) - -**Load path:** a stack of environments where package identities, their -dependencies, and entry-points are searched for. The load path is controlled in -Julia by the `LOAD_PATH` global variable which is populated at startup based on -the value of the `JULIA_LOAD_PATH` environment variable. The first entry is your -primary environment, often the current project, while later entries provide -additional packages one may want to use from the REPL or top-level scripts. - -**Depot path:** a stack of depot locations where the package manager, as well as -Julia's code loading mechanisms, look for registries, installed packages, named -environments, repo clones, cached compiled package images, and configuration -files. The depot path is controlled by the Julia `DEPOT_PATH` global variable -which is populated at startup based on the value of the `JULIA_DEPOT_PATH` -environment variable. The first entry is the “user depot” and should be writable -by and owned by the current user. The user depot is where: registries are -cloned, new package versions are installed, named environments are created and -updated, package repos are cloned, new compiled package image files are saved, -log files are written, development packages are checked out by default, and -global configuration data is saved. Later entries in the depot path are treated -as read-only and are appropriate for registries, packages, etc. installed and -managed by system administrators. - -## Getting Started - -The Pkg REPL-mode is entered from the Julia REPL using the key `]`. - -``` -(v0.7) pkg> -``` - -The part inside the parenthesis of the prompt shows the name of the current project. -Since we haven't created our own project yet, we are in the default project, located at `~/.julia/environments/v0.7` -(or whatever version of Julia you happen to run). - -To return to the `julia>` prompt, either press backspace when the input line is empty or press Ctrl+C. -Help is available by calling `pkg> help`. - -To generate files for a new project, use `pkg> generate`. - -``` -(v0.7) pkg> generate HelloWorld -``` - -This creates a new project `HelloWorld` with the following files (visualized with the external [`tree` command](https://linux.die.net/man/1/tree)): - -```jl -julia> cd("HelloWorld") -shell> tree . -. -├── Project.toml -└── src - └── HelloWorld.jl - -1 directory, 2 files -``` - -The `Project.toml` file contains the name of the package, its unique UUID, its version, the author and eventual dependencies: - -```toml -name = "HelloWorld" -uuid = "b4cd1eb8-1e24-11e8-3319-93036a3eb9f3" -version = "0.1.0" -author = ["Some One "] - -[deps] -``` - -The content of `src/HelloWorld.jl` is: - -```jl -module HelloWorld - -greet() = print("Hello World!") - -end # module -``` - -We can now load the project and use it: - -```jl -julia> import HelloWorld - -julia> HelloWorld.greet() -Hello World! -``` - -### Adding packages to the project - -Let’s say we want to use the standard library package `Random` and the registered package `JSON` in our project. -We simply `add` these packages (note how the prompt now shows the name of the newly generated project, -since we are inside the `HelloWorld` project directory): - -``` -(HelloWorld) pkg> add Random JSON - Resolving package versions... - Updating "~/Documents/HelloWorld/Project.toml" - [682c06a0] + JSON v0.17.1 - [9a3f8284] + Random - Updating "~/Documents/HelloWorld/Manifest.toml" - [34da2185] + Compat v0.57.0 - [682c06a0] + JSON v0.17.1 - [4d1e1d77] + Nullables v0.0.4 - ... -``` - -Both `Random` and `JSON` got added to the project’s `Project.toml` file, and the resulting dependencies got added to the `Manifest.toml` file. -The resolver has installed each package with the highest possible version, while still respecting the compatibility that each package enforce on its dependencies. - -We can now use both `Random` and `JSON` in our project. Changing `src/HelloWorld.jl` to - -``` -module HelloWorld - -import Random -import JSON - -greet() = print("Hello World!") -greet_alien() = print("Hello ", Random.randstring(8)) - -end # module -``` - -and reloading the package, the new `greet_alien` function that uses `Random` can be used: - -``` -julia> HelloWorld.greet_alien() -Hello aT157rHV -``` - -Sometimes we might want to use the very latest, unreleased version of a package, or perhaps a specific branch in the package -git repository. We can use e.g. the `master` branch of `JSON` by specifying the branch after a `#` when adding the package: - -``` -(HelloWorld) pkg> add JSON#master - Cloning package from https://github.com/JuliaIO/JSON.jl.git - Resolving package versions... - Updating "~/Documents/HelloWorld/Project.toml" - [682c06a0] ~ JSON v0.17.1 ⇒ v0.17.1+ #master - Updating "~/Documents/HelloWorld/Manifest.toml" - [682c06a0] ~ JSON v0.17.1 ⇒ v0.17.1+ #master -``` - -If we want to use a package that has not been registered in a registry, we can `add` its git repository url: - -``` -(HelloWorld) pkg> add https://github.com/fredrikekre/ImportMacros.jl - Cloning package from https://github.com/fredrikekre/ImportMacros.jl - Resolving package versions... -Downloaded MacroTools ─ v0.4.0 - Updating "~/Documents/HelloWorld/Project.toml" - [5adcef86] + ImportMacros v0.1.0 #master - Updating "~/Documents/HelloWorld/Manifest.toml" - [5adcef86] + ImportMacros v0.1.0 #master - [1914dd2f] + MacroTools v0.4.0 -``` - -The dependencies of the unregistered package (here `MacroTools`) got installed. -For unregistered packages we could have given a branch (or commit SHA) to track using `#`, just like for registered packages. - - -## Developing packages - -Let’s say we found a bug in one of our dependencies, e.g. `JSON` that we want to fix. We can get the full git-repo using the `develop` command - -``` -(HelloWorld) pkg> develop JSON - Cloning package from https://github.com/JuliaIO/JSON.jl.git - Resolving package versions... - Updating "~/Documents/HelloWorld/Project.toml" - [682c06a0] + JSON v0.17.1+ [~/.julia/dev/JSON] -... -``` - -By default, the package get cloned to the `~/.julia/dev` folder but can also be set by the `JULIA_PKG_DEVDIR` environment variable. -When we have fixed the bug and checked that `JSON` now works correctly with our project, we can make a PR to the `JSON` repository. -When the PR has been merged we can go over to track the master branch and finally, when a new release of `JSON` is made, we can go back to using the versioned `JSON` using the command `free` and `update` (see next section): - -``` -(HelloWorld) pkg> free JSON - Resolving package versions... - Updating "~/Documents/HelloWorld/Project.toml" - [682c06a0] ~ JSON v0.17.1+ #master ⇒ v0.17.1 - Updating "~/Documents/HelloWorld/Manifest.toml" - [682c06a0] ~ JSON v0.17.1+ #master ⇒ v0.17.1 -``` - -It is also possible to give a local path as the argument to `develop` which will not clone anything but simply use that directory for the package. - -Overriding the dependency path for a non registered package is done by giving the git-repo url as an argument to `develop`. - -## Updating dependencies - -When new versions of packages the project is using are released, it is a good idea to update. Simply calling `up` will try to update *all* the dependencies of the project. Sometimes this is not what you want. You can specify a subset of the dependencies to upgrade by giving them as arguments to `up`, e.g: - -``` -(HelloWorld) pkg> up JSON -``` - -The version of all other direct dependencies will stay the same. If you only want to update the minor version of packages, to reduce the risk that your project breaks, you can give the `--minor` flag, e.g: - -``` -(HelloWorld) pkg> up --minor JSON -``` - -Packages that track a branch are not updated when a minor upgrade is done. -Developed packages are never touched by the package manager. - -If you just want install the packages that are given by the current `Manifest.toml` use - -``` -(HelloWorld) pkg> instantiate -``` - -## Precompiling the project - -The REPL command `precompile` can be used to precompile all the dependencies in the project. You can for example do - -``` -(HelloWorld) pkg> update; precompile -``` - -do update the dependencies and then precompile them. - -## Preview mode - -If you just want to see the effects of running a command, but not change your state you can `preview` a command. -For example: - -``` -(HelloWorld) pkg> preview add Plots -``` - -or - -``` -(HelloWorld) pkg> preview up -``` - -will show you the effects adding `Plots`, or doing a full upgrade, respectively, would have on your project. -However, nothing would be installed and your `Project.toml` and `Manfiest.toml` are untouched. - -## Using someone elses project - -Simple clone their project using e.g. `git clone`, `cd` to the project directory and call - -``` -(SomeProject) pkg> instantiate -``` - -If the project contains a manifest, this will install the packages at the same state that is given by that manifest. -Otherwise it will resolve the latest versions of the dependencies compatible with the project. - - diff --git a/src/stdlib/REPL.md b/src/stdlib/REPL.md index d9080cf..59494a4 100644 --- a/src/stdlib/REPL.md +++ b/src/stdlib/REPL.md @@ -306,8 +306,10 @@ completion to be able to remove non-matching methods. Tab completion can also help completing fields: ```julia-repl -julia> Pkg.a[TAB] -add available +julia> import UUIDs + +julia> UUIDs.uuid[TAB] +uuid1 uuid4 uuid_version ``` Fields for output from functions can also be completed: diff --git a/src/stdlib/linearalgebra.md b/src/stdlib/linearalgebra.md index 8ccffe5..a78fdfa 100644 --- a/src/stdlib/linearalgebra.md +++ b/src/stdlib/linearalgebra.md @@ -198,7 +198,7 @@ Legend: ### Matrix factorizations -| Matrix type | LAPACK | [`eig`](@ref) | [`eigvals`](@ref) | [`eigvecs`](@ref) | [`svd`](@ref) | [`svdvals`](@ref) | +| Matrix type | LAPACK | [`eigen`](@ref) | [`eigvals`](@ref) | [`eigvecs`](@ref) | [`svd`](@ref) | [`svdvals`](@ref) | |:------------------------- |:------ |:------------- |:----------------- |:----------------- |:------------- |:----------------- | | [`Symmetric`](@ref) | SY | | ARI | | | | | [`Hermitian`](@ref) | HE | | ARI | | | | @@ -312,47 +312,40 @@ LinearAlgebra.LowerTriangular LinearAlgebra.UpperTriangular LinearAlgebra.UniformScaling LinearAlgebra.lu -LinearAlgebra.lufact -LinearAlgebra.lufact! +LinearAlgebra.lu! LinearAlgebra.chol -LinearAlgebra.cholfact -LinearAlgebra.cholfact! +LinearAlgebra.cholesky +LinearAlgebra.cholesky! LinearAlgebra.lowrankupdate LinearAlgebra.lowrankdowndate LinearAlgebra.lowrankupdate! LinearAlgebra.lowrankdowndate! -LinearAlgebra.ldltfact -LinearAlgebra.ldltfact! +LinearAlgebra.ldlt +LinearAlgebra.ldlt! LinearAlgebra.qr LinearAlgebra.qr! -LinearAlgebra.qrfact -LinearAlgebra.qrfact! LinearAlgebra.QR LinearAlgebra.QRCompactWY LinearAlgebra.QRPivoted -LinearAlgebra.lqfact! -LinearAlgebra.lqfact +LinearAlgebra.lq! LinearAlgebra.lq -LinearAlgebra.bkfact -LinearAlgebra.bkfact! -LinearAlgebra.eig +LinearAlgebra.bunchkaufman +LinearAlgebra.bunchkaufman! LinearAlgebra.eigvals LinearAlgebra.eigvals! LinearAlgebra.eigmax LinearAlgebra.eigmin LinearAlgebra.eigvecs -LinearAlgebra.eigfact -LinearAlgebra.eigfact! -LinearAlgebra.hessfact -LinearAlgebra.hessfact! -LinearAlgebra.schurfact -LinearAlgebra.schurfact! +LinearAlgebra.eigen +LinearAlgebra.eigen! +LinearAlgebra.hessenberg +LinearAlgebra.hessenberg! +LinearAlgebra.schur! LinearAlgebra.schur LinearAlgebra.ordschur LinearAlgebra.ordschur! -LinearAlgebra.svdfact -LinearAlgebra.svdfact! LinearAlgebra.svd +LinearAlgebra.svd! LinearAlgebra.svdvals LinearAlgebra.svdvals! LinearAlgebra.Givens From 933e6e1f8191e9be88f63b10166564bb5e3d715a Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Thu, 31 May 2018 11:47:27 +0900 Subject: [PATCH 029/153] update Julia Version 0.7.0-alpha.0 --- codex/NEWS.md | 2 ++ codex/base/base.md | 1 + codex/base/iterators.md | 1 + codex/base/math.md | 6 ------ .../integers-and-floating-point-numbers.md | 18 ---------------- codex/manual/interfaces.md | 12 +++++------ codex/manual/strings.md | 21 +++++++++++++++++++ codex/stdlib/LinearAlgebra.md | 2 -- codex/stdlib/linearalgebra.md | 2 -- src/NEWS.md | 2 ++ src/base/base.md | 1 + src/base/iterators.md | 1 + src/base/math.md | 6 ------ .../integers-and-floating-point-numbers.md | 16 -------------- src/manual/interfaces.md | 12 +++++------ src/manual/strings.md | 21 +++++++++++++++++++ src/stdlib/LinearAlgebra.md | 2 -- src/stdlib/linearalgebra.md | 2 -- 18 files changed, 62 insertions(+), 66 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index 5bb85ee..e09d339 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -1248,6 +1248,8 @@ Deprecated or removed * `signif` has been deprecated in favor of the `sigdigits` keyword argument to `round`. + * `setrounding` has been deprecated for `Float32` and `Float64`, as the behaviour was too unreliable ([#26935](https://github.com/JuliaLang/julia/issues/26935)). + Command-line option changes --------------------------- diff --git a/codex/base/base.md b/codex/base/base.md index 71be16a..030ffe3 100644 --- a/codex/base/base.md +++ b/codex/base/base.md @@ -185,6 +185,7 @@ Base.Val Core.Vararg Core.Nothing Base.Some +Base.something Base.Enums.@enum ``` diff --git a/codex/base/iterators.md b/codex/base/iterators.md index 7fa782e..7f89b79 100644 --- a/codex/base/iterators.md +++ b/codex/base/iterators.md @@ -1,6 +1,7 @@ # Iteration utilities ```@docs +Base.Iterators.Stateful Base.Iterators.zip Base.Iterators.enumerate Base.Iterators.rest diff --git a/codex/base/math.md b/codex/base/math.md index df67d02..bc13127 100644 --- a/codex/base/math.md +++ b/codex/base/math.md @@ -189,15 +189,9 @@ Base.FastMath.@fastmath ```@docs Base.mean Base.mean! -Base.std -Base.stdm -Base.var -Base.varm Base.middle Base.median Base.median! Base.quantile Base.quantile! -Base.cov -Base.cor ``` diff --git a/codex/manual/integers-and-floating-point-numbers.md b/codex/manual/integers-and-floating-point-numbers.md index 80b0092..231df41 100644 --- a/codex/manual/integers-and-floating-point-numbers.md +++ b/codex/manual/integers-and-floating-point-numbers.md @@ -496,27 +496,9 @@ appropriate representable value. However, the manner in which this rounding is d changed if required according to the rounding modes presented in the [IEEE 754 standard](https://en.wikipedia.org/wiki/IEEE_754-2008). -```jldoctest -julia> x = 1.1; y = 0.1; - -julia> x + y -1.2000000000000002 - -julia> setrounding(Float64,RoundDown) do - x + y - end -1.2 -``` - The default mode used is always [`RoundNearest`](@ref), which rounds to the nearest representable value, with ties rounded towards the nearest value with an even least significant bit. -!!! warning - Rounding is generally only correct for basic arithmetic functions ([`+`](@ref), [`-`](@ref), - [`*`](@ref), [`/`](@ref) and [`sqrt`](@ref)) and type conversion operations. Many other - functions assume the default [`RoundNearest`](@ref) mode is set, and can give erroneous results - when operating under other rounding modes. - ### Background and References Floating-point arithmetic entails many subtleties which can be surprising to users who are unfamiliar diff --git a/codex/manual/interfaces.md b/codex/manual/interfaces.md index 8d4810f..2e859fe 100644 --- a/codex/manual/interfaces.md +++ b/codex/manual/interfaces.md @@ -14,7 +14,7 @@ to generically build upon those behaviors. | **Important optional methods** | **Default definition** | **Brief description** | | `IteratorSize(IterType)` | `HasLength()` | One of `HasLength()`, `HasShape{N}()`, `IsInfinite()`, or `SizeUnknown()` as appropriate | | `IteratorEltype(IterType)` | `HasEltype()` | Either `EltypeUnknown()` or `HasEltype()` as appropriate | -| `eltype(IterType)` | `Any` | The type of the items returned by `next()` | +| `eltype(IterType)` | `Any` | The type of the first entry of the tuple returned by `iterate()` | | `length(iter)` | (*undefined*) | The number of items, if known | | `size(iter, [dim...])` | (*undefined*) | The number of items in each dimension, if known | @@ -65,7 +65,6 @@ julia> struct Squares end julia> Base.iterate(S::Squares, state=1) = state > S.count ? nothing : (state*state, state+1) - ``` With only [`iterate`](@ref) definition, the `Squares` type is already pretty powerful. @@ -84,17 +83,18 @@ julia> for i in Squares(7) 49 ``` -We can use many of the builtin methods that work with iterables, like [`in`](@ref), [`mean`](@ref) and [`std`](@ref): +We can use many of the builtin methods that work with iterables, like [`in`](@ref), +[`sum`](@ref) and [`mean`](@ref): ```jldoctest squaretype julia> 25 in Squares(10) true +julia> sum(Squares(100)) +338350 + julia> mean(Squares(100)) 3383.5 - -julia> std(Squares(100)) -3024.355854282583 ``` There are a few more methods we can extend to give Julia more information about this iterable diff --git a/codex/manual/strings.md b/codex/manual/strings.md index 3fc8483..bd140ea 100644 --- a/codex/manual/strings.md +++ b/codex/manual/strings.md @@ -832,6 +832,27 @@ julia> match(r"a+.*b+.*?d$"ism, "Goodbye,\nOh, angry,\nBad world\n") RegexMatch("angry,\nBad world") ``` +The `r"..."` literal is constructed without interpolation and unescaping (except for +quotation mark `"` which still has to be escaped). Here is an example +showing the difference from standard string literals: + +```julia-repl +julia> x = 10 +10 + +julia> r"$x" +r"$x" + +julia> "$x" +"10" + +julia> r"\x" +r"\x" + +julia> "\x" +ERROR: syntax: invalid escape sequence +``` + Triple-quoted regex strings, of the form `r"""..."""`, are also supported (and may be convenient for regular expressions containing quotation marks or newlines). diff --git a/codex/stdlib/LinearAlgebra.md b/codex/stdlib/LinearAlgebra.md index a78fdfa..3b3d6c9 100644 --- a/codex/stdlib/LinearAlgebra.md +++ b/codex/stdlib/LinearAlgebra.md @@ -313,7 +313,6 @@ LinearAlgebra.UpperTriangular LinearAlgebra.UniformScaling LinearAlgebra.lu LinearAlgebra.lu! -LinearAlgebra.chol LinearAlgebra.cholesky LinearAlgebra.cholesky! LinearAlgebra.lowrankupdate @@ -372,7 +371,6 @@ Base.inv(::AbstractMatrix) LinearAlgebra.pinv LinearAlgebra.nullspace Base.kron -LinearAlgebra.linreg LinearAlgebra.exp(::StridedMatrix{<:LinearAlgebra.BlasFloat}) LinearAlgebra.log(::StridedMatrix) LinearAlgebra.sqrt(::StridedMatrix{<:Real}) diff --git a/codex/stdlib/linearalgebra.md b/codex/stdlib/linearalgebra.md index a78fdfa..3b3d6c9 100644 --- a/codex/stdlib/linearalgebra.md +++ b/codex/stdlib/linearalgebra.md @@ -313,7 +313,6 @@ LinearAlgebra.UpperTriangular LinearAlgebra.UniformScaling LinearAlgebra.lu LinearAlgebra.lu! -LinearAlgebra.chol LinearAlgebra.cholesky LinearAlgebra.cholesky! LinearAlgebra.lowrankupdate @@ -372,7 +371,6 @@ Base.inv(::AbstractMatrix) LinearAlgebra.pinv LinearAlgebra.nullspace Base.kron -LinearAlgebra.linreg LinearAlgebra.exp(::StridedMatrix{<:LinearAlgebra.BlasFloat}) LinearAlgebra.log(::StridedMatrix) LinearAlgebra.sqrt(::StridedMatrix{<:Real}) diff --git a/src/NEWS.md b/src/NEWS.md index e1b3e36..2aa44b8 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -1236,6 +1236,8 @@ Deprecated or removed * `signif` has been deprecated in favor of the `sigdigits` keyword argument to `round`. + * `setrounding` has been deprecated for `Float32` and `Float64`, as the behaviour was too unreliable ([#26935](https://github.com/JuliaLang/julia/issues/26935)). + Command-line option changes --------------------------- diff --git a/src/base/base.md b/src/base/base.md index 71be16a..030ffe3 100644 --- a/src/base/base.md +++ b/src/base/base.md @@ -185,6 +185,7 @@ Base.Val Core.Vararg Core.Nothing Base.Some +Base.something Base.Enums.@enum ``` diff --git a/src/base/iterators.md b/src/base/iterators.md index 7fa782e..7f89b79 100644 --- a/src/base/iterators.md +++ b/src/base/iterators.md @@ -1,6 +1,7 @@ # Iteration utilities ```@docs +Base.Iterators.Stateful Base.Iterators.zip Base.Iterators.enumerate Base.Iterators.rest diff --git a/src/base/math.md b/src/base/math.md index df67d02..bc13127 100644 --- a/src/base/math.md +++ b/src/base/math.md @@ -189,15 +189,9 @@ Base.FastMath.@fastmath ```@docs Base.mean Base.mean! -Base.std -Base.stdm -Base.var -Base.varm Base.middle Base.median Base.median! Base.quantile Base.quantile! -Base.cov -Base.cor ``` diff --git a/src/manual/integers-and-floating-point-numbers.md b/src/manual/integers-and-floating-point-numbers.md index 340b04e..66239de 100644 --- a/src/manual/integers-and-floating-point-numbers.md +++ b/src/manual/integers-and-floating-point-numbers.md @@ -452,24 +452,8 @@ julia> bitstring(nextfloat(x)) 만약 어떤 숫자가 정확한 부동 소수점 표현을 가지고 있지 않다면, 그 수는 반드시 어떤 표현 가능한 값으로 라운딩 되어야 한다. [IEEE 754 표준](https://en.wikipedia.org/wiki/IEEE_754-2008)에 나오는 라운딩 모드로 라운딩 방식을 바꿀 수 있다. -```jldoctest -julia> x = 1.1; y = 0.1; - -julia> x + y -1.2000000000000002 - -julia> setrounding(Float64, RoundDown) do - x + y - end -1.2 -``` - 기본 라운딩 모드는 항상 [`RoundNearest`](@ref)이다. 이는 가장 근접한 표현 가능한 값으로 라운딩 하지만, 만약 두 표현 값 중간에 주어진 값이 걸쳐 있으면 가수부 값 중 짝수(바이너리 임으로 0)로 라운딩 하는 모드이다. -!!! 경고 - : 라운딩은 일반적으로 기본 산술 함수([`+`](@ref), [`-`](@ref), - [`*`](@ref), [`/`](@ref), [`sqrt`](@ref))와 타입 변환 연산에서만 정확하다. 많은 다른 함수들은 기본 값인 [`RoundNearest`](@ref)를 가정하고 짜여져 있고, 이는 다른 라운딩 모드에서는 부정확한 값을 제공할 수 있다. - ### 부동 소수점 실수에 대해서 더 읽으면 좋은 문서들 부동 소수점 연산은 많은 미묘한 것들을 수반하고 있기 때문에 저수준(low-level) 구현에 익숙하지 않은 유저들은 당활할 수도 있다. 그러나 그 미묘한 점들은 과학적 연산과 관련된 많은 책들에서 잘 설명되고 있고, 아래에 나열하는 참고문헌도 참고하면 좋을 것이다: diff --git a/src/manual/interfaces.md b/src/manual/interfaces.md index 8d4810f..2e859fe 100644 --- a/src/manual/interfaces.md +++ b/src/manual/interfaces.md @@ -14,7 +14,7 @@ to generically build upon those behaviors. | **Important optional methods** | **Default definition** | **Brief description** | | `IteratorSize(IterType)` | `HasLength()` | One of `HasLength()`, `HasShape{N}()`, `IsInfinite()`, or `SizeUnknown()` as appropriate | | `IteratorEltype(IterType)` | `HasEltype()` | Either `EltypeUnknown()` or `HasEltype()` as appropriate | -| `eltype(IterType)` | `Any` | The type of the items returned by `next()` | +| `eltype(IterType)` | `Any` | The type of the first entry of the tuple returned by `iterate()` | | `length(iter)` | (*undefined*) | The number of items, if known | | `size(iter, [dim...])` | (*undefined*) | The number of items in each dimension, if known | @@ -65,7 +65,6 @@ julia> struct Squares end julia> Base.iterate(S::Squares, state=1) = state > S.count ? nothing : (state*state, state+1) - ``` With only [`iterate`](@ref) definition, the `Squares` type is already pretty powerful. @@ -84,17 +83,18 @@ julia> for i in Squares(7) 49 ``` -We can use many of the builtin methods that work with iterables, like [`in`](@ref), [`mean`](@ref) and [`std`](@ref): +We can use many of the builtin methods that work with iterables, like [`in`](@ref), +[`sum`](@ref) and [`mean`](@ref): ```jldoctest squaretype julia> 25 in Squares(10) true +julia> sum(Squares(100)) +338350 + julia> mean(Squares(100)) 3383.5 - -julia> std(Squares(100)) -3024.355854282583 ``` There are a few more methods we can extend to give Julia more information about this iterable diff --git a/src/manual/strings.md b/src/manual/strings.md index 3fc8483..bd140ea 100644 --- a/src/manual/strings.md +++ b/src/manual/strings.md @@ -832,6 +832,27 @@ julia> match(r"a+.*b+.*?d$"ism, "Goodbye,\nOh, angry,\nBad world\n") RegexMatch("angry,\nBad world") ``` +The `r"..."` literal is constructed without interpolation and unescaping (except for +quotation mark `"` which still has to be escaped). Here is an example +showing the difference from standard string literals: + +```julia-repl +julia> x = 10 +10 + +julia> r"$x" +r"$x" + +julia> "$x" +"10" + +julia> r"\x" +r"\x" + +julia> "\x" +ERROR: syntax: invalid escape sequence +``` + Triple-quoted regex strings, of the form `r"""..."""`, are also supported (and may be convenient for regular expressions containing quotation marks or newlines). diff --git a/src/stdlib/LinearAlgebra.md b/src/stdlib/LinearAlgebra.md index a78fdfa..3b3d6c9 100644 --- a/src/stdlib/LinearAlgebra.md +++ b/src/stdlib/LinearAlgebra.md @@ -313,7 +313,6 @@ LinearAlgebra.UpperTriangular LinearAlgebra.UniformScaling LinearAlgebra.lu LinearAlgebra.lu! -LinearAlgebra.chol LinearAlgebra.cholesky LinearAlgebra.cholesky! LinearAlgebra.lowrankupdate @@ -372,7 +371,6 @@ Base.inv(::AbstractMatrix) LinearAlgebra.pinv LinearAlgebra.nullspace Base.kron -LinearAlgebra.linreg LinearAlgebra.exp(::StridedMatrix{<:LinearAlgebra.BlasFloat}) LinearAlgebra.log(::StridedMatrix) LinearAlgebra.sqrt(::StridedMatrix{<:Real}) diff --git a/src/stdlib/linearalgebra.md b/src/stdlib/linearalgebra.md index a78fdfa..3b3d6c9 100644 --- a/src/stdlib/linearalgebra.md +++ b/src/stdlib/linearalgebra.md @@ -313,7 +313,6 @@ LinearAlgebra.UpperTriangular LinearAlgebra.UniformScaling LinearAlgebra.lu LinearAlgebra.lu! -LinearAlgebra.chol LinearAlgebra.cholesky LinearAlgebra.cholesky! LinearAlgebra.lowrankupdate @@ -372,7 +371,6 @@ Base.inv(::AbstractMatrix) LinearAlgebra.pinv LinearAlgebra.nullspace Base.kron -LinearAlgebra.linreg LinearAlgebra.exp(::StridedMatrix{<:LinearAlgebra.BlasFloat}) LinearAlgebra.log(::StridedMatrix) LinearAlgebra.sqrt(::StridedMatrix{<:Real}) From e2c2f0d7ee2ad4f8558cd1f1b99cd3e2ba91ac9b Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Sat, 2 Jun 2018 00:10:51 +0900 Subject: [PATCH 030/153] update Julia Commit a8b9995dc5 --- codex/NEWS.md | 4 +-- codex/manual/strings.md | 76 +++++++++++++++++++++++++++++++++++++++++ codex/manual/types.md | 2 +- contrib/html_writer.jl | 12 ++++--- make.jl | 40 ++++++++++++++-------- src/NEWS.md | 4 +-- src/manual/strings.md | 76 +++++++++++++++++++++++++++++++++++++++++ src/manual/types.md | 2 +- tools/check_codex.jl | 18 +++++----- 9 files changed, 200 insertions(+), 34 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index e09d339..012ff24 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -487,7 +487,7 @@ This section lists changes that do not have deprecation warnings. * `widen` on 8- and 16-bit integer types now widens to the platform word size (`Int`) instead of to a 32-bit type ([#26859](https://github.com/JuliaLang/julia/issues/26859)). - * `mv`,`cp`, `touch`, `mkdir`, `mkpath` now return the path that was created/modified + * `mv`,`cp`, `touch`, `mkdir`, `mkpath`, `chmod` and `chown` now return the path that was created/modified rather than `nothing` ([#27071](https://github.com/JuliaLang/julia/issues/27071)). * Regular expressions now default to UCP mode. Escape sequences such as `\w` @@ -592,7 +592,7 @@ Library improvements the test fails ([#22296](https://github.com/JuliaLang/julia/issues/22296)). * Uses of `Val{c}` in `Base` has been replaced with `Val{c}()`, which is now easily - accessible via the `@pure` constructor `Val(c)`. Functions are defined as + accessible via the efficient constructor `Val(c)`. Functions are defined as `f(::Val{c}) = ...` and called by `f(Val(c))`. Notable affected functions include: `ntuple`, `Base.literal_pow`, `sqrtm`, `lufact`, `lufact!`, `qrfact`, `qrfact!`, `cholfact`, `cholfact!`, `_broadcast!`, `reshape`, `cat` and `cat_t`. diff --git a/codex/manual/strings.md b/codex/manual/strings.md index bd140ea..5494e6a 100644 --- a/codex/manual/strings.md +++ b/codex/manual/strings.md @@ -348,6 +348,54 @@ x y ``` +Strings in Julia can contain invalid UTF-8 code unit sequences. This convention allows to +treat any byte sequence as a `String`. In such situations a rule is that when parsing +a sequence of code units from left to right characters are formed by the longest sequence of +8-bit code units that matches the start of one of the following bit patterns +(each `x` can be `0` or `1`): + +* `0xxxxxxx`; +* `110xxxxx` `10xxxxxx`; +* `1110xxxx` `10xxxxxx` `10xxxxxx`; +* `11110xxx` `10xxxxxx` `10xxxxxx` `10xxxxxx`; +* `10xxxxxx`; +* `11111xxx`. + +In particular this implies that overlong and too high code unit sequences are accepted. +This rule is best explained by an example: + +```julia-repl +julia> s = "\xc0\xa0\xe2\x88\xe2|" +"\xc0\xa0\xe2\x88\xe2|" + +julia> foreach(display, s) +'\xc0\xa0': [overlong] ASCII/Unicode U+0020 (category Zs: Separator, space) +'\xe2\x88': Malformed UTF-8 (category Ma: Malformed, bad data) +'\xe2': Malformed UTF-8 (category Ma: Malformed, bad data) +'|': ASCII/Unicode U+007c (category Sm: Symbol, math) + +julia> isvalid.(collect(s)) +4-element BitArray{1}: + false + false + false + true + +julia> s2 = "\xf7\xbf\xbf\xbf" +"\U1fffff" + +julia> foreach(display, s2) +'\U1fffff': Unicode U+1fffff (category In: Invalid, too high) +``` + +We can see that the first two code units in the string `s` form an overlong encoding of +space character. It is invalid, but is accepted in a string as a single character. +The next two code units form a valid start of a three-byte UTF-8 sequence. However, the fifth +code unit `\xe2` is not its valid continuation. Therefore code units 3 and 4 are also +interpreted as malformed characters in this string. Similarly code unit 5 forms a malformed +character because `|` is not a valid continuation to it. Finally the string `s2` contains +one too high code point. + Julia uses the UTF-8 encoding by default, and support for new encodings can be added by packages. For example, the [LegacyStrings.jl](https://github.com/JuliaArchive/LegacyStrings.jl) package implements `UTF16String` and `UTF32String` types. Additional discussion of other encodings and @@ -371,6 +419,34 @@ julia> string(greet, ", ", whom, ".\n") "Hello, world.\n" ``` +A situation which is important to be aware of is when invalid UTF-8 strings are concatenated. +In that case the resulting string may contain different characters than the input strings, +and its number of characters may be lower than sum of numbers of characters +of the concatenated strings, e.g.: + +```julia-repl +julia> a, b = "\xe2\x88", "\x80" +("\xe2\x88", "\x80") + +julia> c = a*b +"∀" + +julia> collect.([a, b, c]) +3-element Array{Array{Char,1},1}: + ['\xe2\x88'] + ['\x80'] + ['∀'] + +julia> length.([a, b, c]) +3-element Array{Int64,1}: + 1 + 1 + 1 +``` + +This situation can happen only for invalid UTF-8 strings. For valid UTF-8 strings +concatenation preserves all characters in strings and additivity of string lengths. + Julia also provides `*` for string concatenation: ```jldoctest stringconcat diff --git a/codex/manual/types.md b/codex/manual/types.md index 3527f19..514c5a0 100644 --- a/codex/manual/types.md +++ b/codex/manual/types.md @@ -1183,7 +1183,7 @@ Any If you apply [`supertype`](@ref) to other type objects (or non-type objects), a [`MethodError`](@ref) is raised: -```jldoctest +```jldoctest; filter = r"Closest candidates.*"s julia> supertype(Union{Float64,Int64}) ERROR: MethodError: no method matching supertype(::Type{Union{Float64, Int64}}) Closest candidates are: diff --git a/contrib/html_writer.jl b/contrib/html_writer.jl index c4057f2..fc353ce 100644 --- a/contrib/html_writer.jl +++ b/contrib/html_writer.jl @@ -47,7 +47,7 @@ function Documenter.Writers.HTMLWriter.render_head(ctx, navnode) link[:href => relhref(src, "assets/custom.css"), :rel => "stylesheet", :type => "text/css"], - # juliakorea 단어 word break + # juliakorea Korean word break script[:src => "/js/jquery-1.8.3.min.js"], script[:src => "/js/jquery.word-break-keep-all.min.js"], script("\$(document).ready(function() { \$('p').wordBreakKeepAll(); });") @@ -75,6 +75,10 @@ function Documenter.Writers.HTMLWriter.render_page(ctx, navnode) end end +const t_Previous = "이전글" +const t_Next = "다음글" +t_Edit_on(host) = " Edit on $host" + function Documenter.Writers.HTMLWriter.render_article(ctx, navnode) @tags article header footer nav ul li hr span a @@ -101,7 +105,7 @@ function Documenter.Writers.HTMLWriter.render_article(ctx, navnode) if !ctx.doc.user.html_disable_git url = Utilities.url(ctx.doc.user.repo, getpage(ctx, navnode).source, commit=ctx.doc.user.html_edit_branch) if url !== nothing - push!(topnav.nodes, a[".edit-page", :href => url](span[".fa"](logo), " Edit on $host")) + push!(topnav.nodes, a[".edit-page", :href => url](span[".fa"](logo), t_Edit_on(host))) end end art_header = header(topnav, hr(), render_topbar(ctx, navnode)) @@ -109,14 +113,14 @@ function Documenter.Writers.HTMLWriter.render_article(ctx, navnode) # build the footer with nav links art_footer = footer(hr()) if navnode.prev !== nothing - direction = span[".direction"]("이전글") # Previous + direction = span[".direction"](t_Previous) title = span[".title"](mdconvert(pagetitle(ctx, navnode.prev); droplinks=true)) link = a[".previous", :href => navhref(ctx, navnode.prev, navnode)](direction, title) push!(art_footer.nodes, link) end if navnode.next !== nothing - direction = span[".direction"]("다음글") # Next + direction = span[".direction"](t_Next) title = span[".title"](mdconvert(pagetitle(ctx, navnode.next); droplinks=true)) link = a[".next", :href => navhref(ctx, navnode.next, navnode)](direction, title) push!(art_footer.nodes, link) diff --git a/make.jl b/make.jl index 9cf68fa..057cf39 100644 --- a/make.jl +++ b/make.jl @@ -1,12 +1,14 @@ -# Install dependencies needed to build the documentation. -ENV["JULIA_PKGDIR"] = joinpath(@__DIR__, "deps") +# code from https://github.com/JuliaLang/julia/blob/master/doc/make.jl -if "deps" in ARGS +# Install dependencies needed to build the documentation. using Pkg -Pkg.init() -cp(joinpath(@__DIR__, "REQUIRE"), Pkg.dir("REQUIRE"); remove_destination = true) -Pkg.update() -Pkg.resolve() +empty!(DEPOT_PATH) +pushfirst!(DEPOT_PATH, joinpath(@__DIR__, "deps")) +pushfirst!(LOAD_PATH, @__DIR__) + +if !isdir(joinpath(@__DIR__, "deps", "packages", "Documenter")) || "deps" in ARGS + Pkg.instantiate() + Pkg.add("Documenter") end using Documenter @@ -31,10 +33,14 @@ const STDLIB_DOCS = filter(!ismissing, map(readdir(STDLIB_DIR)) do dir end end) +# Korean text in PAGES +const t_Home = "홈" +const t_Manual = "매뉴얼" + const PAGES = [ - "홈" => "index.md", + t_Home => "index.md", hide("NEWS.md"), - "매뉴얼" => [ + t_Manual => [ "manual/getting-started.md", "manual/variables.md", "manual/integers-and-floating-point-numbers.md", @@ -130,20 +136,26 @@ for stdlib in STDLIB_DOCS @eval using $(stdlib.stdlib) end +# Korean text for makedocs +const t_sitename = "줄리아 언어" +const t_analytics = "UA-110655381-2" # juliakorea analytic ID +const t_html_canonical = "https://juliakorea.github.io/ko/latest/" + makedocs( build = joinpath(pwd(), "local" in ARGS ? "_build_local" : "_build/html/ko/latest"), modules = [Base, Core, BuildSysImg, [Base.root_module(Base, stdlib.stdlib) for stdlib in STDLIB_DOCS]...], clean = false, # true - doctest = "doctest" in ARGS, - linkcheck = "linkcheck" in ARGS, + doctest = ("doctest=fix" in ARGS) ? (:fix) : ("doctest=true" in ARGS) ? true : false, + linkcheck = "linkcheck=true" in ARGS, linkcheck_ignore = ["https://bugs.kde.org/show_bug.cgi?id=136779"], # fails to load from nanosoldier? strict = true, checkdocs = :none, format = "pdf" in ARGS ? :latex : :html, - sitename = "줄리아 언어", + sitename = t_sitename, authors = "The Julia Project", - analytics = "UA-110655381-2", # juliakorea 추척 ID + analytics = t_analytics, pages = PAGES, html_prettyurls = !("local" in ARGS), - html_canonical = "https://juliakorea.github.io/ko/latest/" + html_canonical = t_html_canonical, + assets = ["assets/julia-manual.css", ] ) diff --git a/src/NEWS.md b/src/NEWS.md index 2aa44b8..1d4714e 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -475,7 +475,7 @@ This section lists changes that do not have deprecation warnings. * `widen` on 8- and 16-bit integer types now widens to the platform word size (`Int`) instead of to a 32-bit type ([#26859](https://github.com/JuliaLang/julia/issues/26859)). - * `mv`,`cp`, `touch`, `mkdir`, `mkpath` now return the path that was created/modified + * `mv`,`cp`, `touch`, `mkdir`, `mkpath`, `chmod` and `chown` now return the path that was created/modified rather than `nothing` ([#27071](https://github.com/JuliaLang/julia/issues/27071)). * Regular expressions now default to UCP mode. Escape sequences such as `\w` @@ -580,7 +580,7 @@ Library improvements the test fails ([#22296](https://github.com/JuliaLang/julia/issues/22296)). * Uses of `Val{c}` in `Base` has been replaced with `Val{c}()`, which is now easily - accessible via the `@pure` constructor `Val(c)`. Functions are defined as + accessible via the efficient constructor `Val(c)`. Functions are defined as `f(::Val{c}) = ...` and called by `f(Val(c))`. Notable affected functions include: `ntuple`, `Base.literal_pow`, `sqrtm`, `lufact`, `lufact!`, `qrfact`, `qrfact!`, `cholfact`, `cholfact!`, `_broadcast!`, `reshape`, `cat` and `cat_t`. diff --git a/src/manual/strings.md b/src/manual/strings.md index bd140ea..5494e6a 100644 --- a/src/manual/strings.md +++ b/src/manual/strings.md @@ -348,6 +348,54 @@ x y ``` +Strings in Julia can contain invalid UTF-8 code unit sequences. This convention allows to +treat any byte sequence as a `String`. In such situations a rule is that when parsing +a sequence of code units from left to right characters are formed by the longest sequence of +8-bit code units that matches the start of one of the following bit patterns +(each `x` can be `0` or `1`): + +* `0xxxxxxx`; +* `110xxxxx` `10xxxxxx`; +* `1110xxxx` `10xxxxxx` `10xxxxxx`; +* `11110xxx` `10xxxxxx` `10xxxxxx` `10xxxxxx`; +* `10xxxxxx`; +* `11111xxx`. + +In particular this implies that overlong and too high code unit sequences are accepted. +This rule is best explained by an example: + +```julia-repl +julia> s = "\xc0\xa0\xe2\x88\xe2|" +"\xc0\xa0\xe2\x88\xe2|" + +julia> foreach(display, s) +'\xc0\xa0': [overlong] ASCII/Unicode U+0020 (category Zs: Separator, space) +'\xe2\x88': Malformed UTF-8 (category Ma: Malformed, bad data) +'\xe2': Malformed UTF-8 (category Ma: Malformed, bad data) +'|': ASCII/Unicode U+007c (category Sm: Symbol, math) + +julia> isvalid.(collect(s)) +4-element BitArray{1}: + false + false + false + true + +julia> s2 = "\xf7\xbf\xbf\xbf" +"\U1fffff" + +julia> foreach(display, s2) +'\U1fffff': Unicode U+1fffff (category In: Invalid, too high) +``` + +We can see that the first two code units in the string `s` form an overlong encoding of +space character. It is invalid, but is accepted in a string as a single character. +The next two code units form a valid start of a three-byte UTF-8 sequence. However, the fifth +code unit `\xe2` is not its valid continuation. Therefore code units 3 and 4 are also +interpreted as malformed characters in this string. Similarly code unit 5 forms a malformed +character because `|` is not a valid continuation to it. Finally the string `s2` contains +one too high code point. + Julia uses the UTF-8 encoding by default, and support for new encodings can be added by packages. For example, the [LegacyStrings.jl](https://github.com/JuliaArchive/LegacyStrings.jl) package implements `UTF16String` and `UTF32String` types. Additional discussion of other encodings and @@ -371,6 +419,34 @@ julia> string(greet, ", ", whom, ".\n") "Hello, world.\n" ``` +A situation which is important to be aware of is when invalid UTF-8 strings are concatenated. +In that case the resulting string may contain different characters than the input strings, +and its number of characters may be lower than sum of numbers of characters +of the concatenated strings, e.g.: + +```julia-repl +julia> a, b = "\xe2\x88", "\x80" +("\xe2\x88", "\x80") + +julia> c = a*b +"∀" + +julia> collect.([a, b, c]) +3-element Array{Array{Char,1},1}: + ['\xe2\x88'] + ['\x80'] + ['∀'] + +julia> length.([a, b, c]) +3-element Array{Int64,1}: + 1 + 1 + 1 +``` + +This situation can happen only for invalid UTF-8 strings. For valid UTF-8 strings +concatenation preserves all characters in strings and additivity of string lengths. + Julia also provides `*` for string concatenation: ```jldoctest stringconcat diff --git a/src/manual/types.md b/src/manual/types.md index 3527f19..514c5a0 100644 --- a/src/manual/types.md +++ b/src/manual/types.md @@ -1183,7 +1183,7 @@ Any If you apply [`supertype`](@ref) to other type objects (or non-type objects), a [`MethodError`](@ref) is raised: -```jldoctest +```jldoctest; filter = r"Closest candidates.*"s julia> supertype(Union{Float64,Int64}) ERROR: MethodError: no method matching supertype(::Type{Union{Float64, Int64}}) Closest candidates are: diff --git a/tools/check_codex.jl b/tools/check_codex.jl index cd371a6..402a3e1 100644 --- a/tools/check_codex.jl +++ b/tools/check_codex.jl @@ -1,15 +1,16 @@ # check_codex.jl -# translate-doc/codex와 ../julia/doc을 비교하는 스크립트 +# diff between translate-doc/codex and ../julia/doc const TOP_PATH = abspath(dirname(@__FILE__), "..") const JULIA_PATH = abspath(TOP_PATH, "..", "julia") -if !(VERSION >= v"0.7.0-DEV") - println("Julia ", v"0.7.0-DEV", " 버젼으로 실행하세요") +const required_julia_version = v"0.7.0-alpha" +if !(VERSION >= required_julia_version) + println("Run with Julia ", required_julia_version) end if !isdir(JULIA_PATH) - println("줄리아 리파지토리 경로를 지정해 주세요 $JULIA_PATH") + println("Requires Julia repository at $JULIA_PATH") end const codex_path = abspath(TOP_PATH, "codex") @@ -32,7 +33,6 @@ function check_src_and_codex(path1, path2) elseif kind == "Only" (_,_,dircolon,filename) = chunk dir = replace(dircolon, ":" => "/") - # src에만 있으면 src에 있는 파일 지우기 if occursin(src_path, dir) if endswith(filename, ".swp") continue @@ -107,7 +107,6 @@ function check_julia_doc_src_and_codex(path1, path2) continue end dir = replace(dircolon, ":" => "/") - # codex에만 있으면 codex, src에 있는 파일 지우기 if occursin(codex_path, dir) for d in (dir, replace(dir, codex_path => src_path)) #print_with_color(:red, "rm ") @@ -116,7 +115,6 @@ function check_julia_doc_src_and_codex(path1, path2) print("rm ", d, filename) println() end - # julia_doc_src에만 있으면 codex, src에 복사 elseif occursin(julia_doc_src_path, dir) copy_julia_doc_src_to_codex_and_src(dir, filename) end @@ -138,9 +136,9 @@ function check_pages() julia_doc_makejl_path = abspath(JULIA_PATH, "doc", "make.jl") pages1 = get_pages(julia_doc_makejl_path) do s; s end pages2 = get_pages(makejl_path) do s - for (a,b) in [("홈", "Home"), - ("매뉴얼", "Manual"), - ("\"devdocs/ssair.md\", # Julia SSA-form IR", ""), # 임시 + for (a,b) in [("t_Home", "\"Home\""), + ("t_Manual", "\"Manual\""), + ("\"devdocs/ssair.md\", # Julia SSA-form IR", ""), # temporal ] s = replace(s, a => b) end From 3b6c9f8364293e6369a52ec7e1de37076b475b8e Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Sun, 3 Jun 2018 02:15:29 +0900 Subject: [PATCH 031/153] update Julia Commit c8ce43ad17 --- codex/devdocs/ast.md | 7 +++++++ codex/manual/integers-and-floating-point-numbers.md | 10 +++++++++- make.jl | 2 +- src/devdocs/ast.md | 7 +++++++ src/devdocs/ssair.md | 6 +++--- src/manual/integers-and-floating-point-numbers.md | 10 +++++++++- 6 files changed, 36 insertions(+), 6 deletions(-) diff --git a/codex/devdocs/ast.md b/codex/devdocs/ast.md index d299e7c..e019d7a 100644 --- a/codex/devdocs/ast.md +++ b/codex/devdocs/ast.md @@ -544,3 +544,10 @@ component is optional (and omitted when the current line number, but not file na changes). These expressions are represented as `LineNumberNode`s in Julia. + +### Macros + +Macro hygiene is represented through the expression head pair `escape` and `hygienic-scope`. +The result of a macro expansion is automatically wrapped in `(hygienic-scope block module)`, +to represent the result of the new scope. The user can insert `(escape block)` inside +to interpolate code from the caller. diff --git a/codex/manual/integers-and-floating-point-numbers.md b/codex/manual/integers-and-floating-point-numbers.md index 231df41..ab2f2a6 100644 --- a/codex/manual/integers-and-floating-point-numbers.md +++ b/codex/manual/integers-and-floating-point-numbers.md @@ -671,11 +671,19 @@ where syntactic conflicts arise: `0` multiplied by the variable `xff`. * The floating-point literal expression `1e10` could be interpreted as the numeric literal `1` multiplied by the variable `e10`, and similarly with the equivalent `E` form. + * The 32-bit floating-point literal expression `1.5f22` could be interpreted as the numeric literal + `1.5` multiplied by the variable `f22`. -In both cases, we resolve the ambiguity in favor of interpretation as numeric literals: +In all cases, we resolve the ambiguity in favor of interpretation as numeric literals: * Expressions starting with `0x` are always hexadecimal literals. * Expressions starting with a numeric literal followed by `e` or `E` are always floating-point literals. + * Expressions starting with a numeric literal followed by `f` are always 32-bit floating-point literals. + +Unlike `E`, which is equivalent to `e` in numeric literals for historical reasons, `F` is just another +letter and does not behave like `f` in numeric literals. Hence, expressions starting with a numeric literal +followed by `F` are interpreted as the numerical literal multiplied by a variable, which means that, for +example, `1.5F22` is equal to `1.5 * F22`. ## Literal zero and one diff --git a/make.jl b/make.jl index 057cf39..6c921e0 100644 --- a/make.jl +++ b/make.jl @@ -121,13 +121,13 @@ const PAGES = [ "devdocs/offset-arrays.md", "devdocs/require.md", "devdocs/inference.md", + "devdocs/ssair.md", # Julia SSA-form IR ], "Developing/debugging Julia's C code" => [ "devdocs/backtraces.md", "devdocs/debuggingtips.md", "devdocs/valgrind.md", "devdocs/sanitizers.md", - "devdocs/ssair.md", # Julia SSA-form IR ] ], ] diff --git a/src/devdocs/ast.md b/src/devdocs/ast.md index d299e7c..e019d7a 100644 --- a/src/devdocs/ast.md +++ b/src/devdocs/ast.md @@ -544,3 +544,10 @@ component is optional (and omitted when the current line number, but not file na changes). These expressions are represented as `LineNumberNode`s in Julia. + +### Macros + +Macro hygiene is represented through the expression head pair `escape` and `hygienic-scope`. +The result of a macro expansion is automatically wrapped in `(hygienic-scope block module)`, +to represent the result of the new scope. The user can insert `(escape block)` inside +to interpolate code from the caller. diff --git a/src/devdocs/ssair.md b/src/devdocs/ssair.md index 75231ca..11828ea 100644 --- a/src/devdocs/ssair.md +++ b/src/devdocs/ssair.md @@ -8,7 +8,7 @@ AST. This form had most syntactic abstractions removed, but still looked a lot l Over time, in order to facilitate optimizations, SSA values were introduced to this IR and the IR was linearized (i.e. a form where function arguments may only be SSA values or constants). However, non-ssa values (slots) remained in the IR due to the lack of Phi nodes in the IR (necessary for back-edges and re-merging of -conditional control flow), negating much of the usefulfulness of the SSA form representation to perform +conditional control flow), negating much of the usefulness of the SSA form representation to perform middle end optimizations. Some heroic effort was put into making these optimizations work without a complete SSA form representation, but the lack of such a representation ultimately proved prohibitive. @@ -90,7 +90,7 @@ catch: However, this is problematic in a language like julia where at the start of the optimization pipeline, we do not now which calls throw. We would have to conservatively assume that every call (which in julia is every statement) throws. This would have several negative effects. -On the one hand, it would essentially recuce the scope of every basic block to a single call, +On the one hand, it would essentially reduce the scope of every basic block to a single call, defeating the purpose of having operations be performed at the basic block level. On the other hand, every catch basic block would have `n*m` phi node arguments (`n`, the number of statements in the critical region, `m` the number of live values through the catch block). To work around @@ -168,7 +168,7 @@ Instead, we do the following: - We keep a separate buffer of nodes to insert (including the position to insert them at, the type of the corresponding value and the node itself). These nodes are numbered by their occurrence in the insertion - buffer, allowing their values to be immediately used elesewhere in the IR (i.e. if there is 12 statements in + buffer, allowing their values to be immediately used elsewhere in the IR (i.e. if there is 12 statements in the original statement list, the first new statement will be accessible as `SSAValue(13)`) - RAUW style operations are performed by setting the corresponding statement index to the replacement value. diff --git a/src/manual/integers-and-floating-point-numbers.md b/src/manual/integers-and-floating-point-numbers.md index 66239de..a3b43b6 100644 --- a/src/manual/integers-and-floating-point-numbers.md +++ b/src/manual/integers-and-floating-point-numbers.md @@ -588,11 +588,19 @@ ERROR: MethodError: objects of type Int64 are not callable * 16진수 리터럴 표현식 `0xff`는 수치형 리터럴 `0`과 변수 `xff`의 곱셈으로 해석될 수 있다. * 부동 소수점 리터럴 표현식 `1e10`은 수치형 리터럴 `1`이 변수 `e10`에 곱해지는 걸로 해석될 수 있고 이는 `e`가 아닌 `E`를 쓸 때에도 마찬가지이다. + * The 32-bit floating-point literal expression `1.5f22` could be interpreted as the numeric literal + `1.5` multiplied by the variable `f22`. -이 두 가지 경우에, 우리는 수치형 리터러를 해석하는데 있어서 다음과 같은 방식으로 모호함을 해결했다: +이와 같은 경우에, 우리는 수치형 리터러를 해석하는데 있어서 다음과 같은 방식으로 모호함을 해결했다: * `0x`로 시작하는 표현식은 항상 16진수 리터럴이다. * 수치형 리터럴으로 시작하는 표현식에서 수치형 리터럴 다음에 `e`또는 `E`가 뒤따라오면 항상 부동소수점 리터럴이다. + * Expressions starting with a numeric literal followed by `f` are always 32-bit floating-point literals. + +Unlike `E`, which is equivalent to `e` in numeric literals for historical reasons, `F` is just another +letter and does not behave like `f` in numeric literals. Hence, expressions starting with a numeric literal +followed by `F` are interpreted as the numerical literal multiplied by a variable, which means that, for +example, `1.5F22` is equal to `1.5 * F22`. ## 리터럴 0과 1 From 05c65b013b5814b8f0073fce12c00fafcb497d7e Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Fri, 8 Jun 2018 12:42:14 +0900 Subject: [PATCH 032/153] update Julia Commit 2e0a54d8da --- codex/NEWS.md | 8 + codex/base/math.md | 1 - codex/devdocs/ast.md | 45 +- codex/devdocs/reflection.md | 24 +- codex/manual/arrays.md | 104 +++- codex/manual/mathematical-operations.md | 7 +- codex/manual/performance-tips.md | 658 ++++++++++++------------ src/NEWS.md | 8 + src/base/math.md | 1 - src/devdocs/ast.md | 45 +- src/devdocs/reflection.md | 24 +- src/manual/arrays.md | 106 +++- src/manual/mathematical-operations.md | 7 +- src/manual/performance-tips.md | 658 ++++++++++++------------ 14 files changed, 907 insertions(+), 789 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index 012ff24..3a38ea3 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -214,6 +214,10 @@ Language changes * `…` (`\dots`) and `⁝` (`\tricolon`) are now parsed as binary operators ([#26262](https://github.com/JuliaLang/julia/issues/26262)). + * Assignment syntax (`a=b`) inside square bracket expressions (e.g. `A[...]`, `[x, y]`) + is deprecated. It will likely be reclaimed in a later version for passing keyword + arguments. Note this does not affect updating operators like `+=` ([#25631](https://github.com/JuliaLang/julia/issues/25631)). + Breaking changes ---------------- @@ -1248,8 +1252,12 @@ Deprecated or removed * `signif` has been deprecated in favor of the `sigdigits` keyword argument to `round`. + * `Base.IntSet` has been deprecated in favor of `Base.BitSet` ([#24282](https://github.com/JuliaLang/julia/issues/24282)). + * `setrounding` has been deprecated for `Float32` and `Float64`, as the behaviour was too unreliable ([#26935](https://github.com/JuliaLang/julia/issues/26935)). + * `atan2` is now a 2-argument method of `atan` ([#27248](https://github.com/JuliaLang/julia/issues/27248)). + Command-line option changes --------------------------- diff --git a/codex/base/math.md b/codex/base/math.md index bc13127..1359b11 100644 --- a/codex/base/math.md +++ b/codex/base/math.md @@ -72,7 +72,6 @@ Base.tanh(::Number) Base.asin(::Number) Base.acos(::Number) Base.atan(::Number) -Base.Math.atan2 Base.Math.asind Base.Math.acosd Base.Math.atand diff --git a/codex/devdocs/ast.md b/codex/devdocs/ast.md index e019d7a..8837b92 100644 --- a/codex/devdocs/ast.md +++ b/codex/devdocs/ast.md @@ -19,6 +19,8 @@ The following data types exist in lowered form: Has a node type indicated by the `head` field, and an `args` field which is a `Vector{Any}` of subexpressions. + While almost every part of a surface AST is represented by an `Expr`, the IR uses only a + limited number of `Expr`s, mostly for calls, conditional branches (`gotoifnot`), and returns. * `Slot` @@ -31,19 +33,12 @@ The following data types exist in lowered form: * `CodeInfo` - Wraps the IR of a method. - - * `LineNumberNode` - - Contains a number and a file name, specifying the line number the next statement came from. - - * `LabelNode` - - Branch target, a consecutively-numbered integer starting at 0. + Wraps the IR of a method. Its `code` field is an array of expressions to execute. * `GotoNode` - Unconditional branch. + Unconditional branch. The argument is the branch target, represented as an index in + the code array to jump to. * `QuoteNode` @@ -57,12 +52,13 @@ The following data types exist in lowered form: * `SSAValue` - Refers to a consecutively-numbered (starting at 0) static single assignment (SSA) variable inserted - by the compiler. + Refers to a consecutively-numbered (starting at 1) static single assignment (SSA) variable inserted + by the compiler. The number (`id`) of an `SSAValue` is the code array index of the expression whose + value it represents. * `NewvarNode` - Marks a point where a variable is created. This has the effect of resetting a variable to undefined. + Marks a point where a variable (slot) is created. This has the effect of resetting a variable to undefined. ### Expr types @@ -84,11 +80,11 @@ These symbols appear in the `head` field of `Expr`s in lowered form. * `gotoifnot` - Conditional branch. If `args[1]` is false, goes to label identified in `args[2]`. + Conditional branch. If `args[1]` is false, goes to the index identified in `args[2]`. * `=` - Assignment. + Assignment. In the IR, the first argument is always a Slot or a GlobalRef. * `method` @@ -181,16 +177,6 @@ These symbols appear in the `head` field of `Expr`s in lowered form. * `:inline` and `:noinline`: Inlining hints. - * `:push_loc`: enters a sequence of statements from a specified source location. - - * `args[2]` specifies a filename, as a symbol. - * `args[3]` optionally specifies the name of an (inlined) function that originally contained the - code. - - * `:pop_loc`: returns to the source location before the matching `:push_loc`. - - * `args[2]::Int` (optional) specifies the number of `push_loc` to pop - ### Method @@ -312,6 +298,15 @@ A temporary container for holding lowered source code. If an `Int`, it gives the number of compiler-inserted temporary locations in the function. If an array, specifies a type for each location. + * `linetable` + + An array of source location objects + + * `codelocs` + + An array of integer indices into the `linetable`, giving the location associated + with each statement. + Boolean properties: * `inferred` diff --git a/codex/devdocs/reflection.md b/codex/devdocs/reflection.md index f8af9b6..b4abeb4 100644 --- a/codex/devdocs/reflection.md +++ b/codex/devdocs/reflection.md @@ -90,23 +90,17 @@ The functions `Base.Meta.show_sexpr` and [`dump`](@ref) are used to display S-ex and depth-nested detail views for any expression. Finally, the [`Meta.lower`](@ref) function gives the `lowered` form of any expression and is of -particular interest for understanding both macros and top-level statements such as function declarations -and variable assignments: +particular interest for understanding how language constructs map to primitive operations such +as assignments, branches, and calls: ```jldoctest -julia> Meta.lower(@__MODULE__, :(f() = 1) ) -:($(Expr(:thunk, CodeInfo(:(begin - $(Expr(:method, :f)) - Core.SSAValue(0) = (Core.Typeof)(f) - Core.SSAValue(1) = (Core.svec)(Core.SSAValue(0)) - Core.SSAValue(2) = (Core.svec)() - Core.SSAValue(3) = (Core.svec)(Core.SSAValue(1), Core.SSAValue(2)) - $(Expr(:method, :f, Core.SSAValue(3), CodeInfo(:(begin - #= none:1 =# - return 1 - end)))) - return f - end))))) +julia> Meta.lower(@__MODULE__, :([1+2, sin(0.5)]) ) +:($(Expr(:thunk, CodeInfo( + 1 ─ %1 = :+(1, 2)::Any + │ %2 = :sin(0.5)::Any + │ %3 = Base.vect(%1, %2)::Any + └── return %3 +)))) ``` ## Intermediate and compiled representations diff --git a/codex/manual/arrays.md b/codex/manual/arrays.md index 521d160..f53271c 100644 --- a/codex/manual/arrays.md +++ b/codex/manual/arrays.md @@ -23,11 +23,11 @@ sharing](https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing) while this prevents accidental modification by callees of a value in the caller, it makes avoiding unwanted copying of arrays difficult. By convention, a function name ending with a `!` indicates that it will mutate or destroy the -value of one or more of its arguments. Callees must make explicit copies to -ensure that they don't modify inputs that they don't intend to change. Many non- -mutating functions are implemented by calling a function of the same name with -an added `!` at the end on an explicit copy of the input, and returning that -copy. +value of one or more of its arguments (see, for example, [`sort`](@ref) and [`sort!`](@ref). +Callees must make explicit copies to ensure that they don't modify inputs that +they don't intend to change. Many non- mutating functions are implemented by +calling a function of the same name with an added `!` at the end on an explicit +copy of the input, and returning that copy. ## Arrays @@ -79,6 +79,25 @@ The syntax `[A, B, C, ...]` constructs a 1-d array (vector) of its arguments. If arguments have a common [promotion type](@ref conversion-and-promotion) then they get converted to that type using [`convert`](@ref). +To see the various ways we can pass dimensions to these constructors, consider the following examples: +```jldoctest +julia> zeros(Int8, 2, 2) +2×2 Array{Int8,2}: + 0 0 + 0 0 + +julia> zeros(Int8, (2, 2)) +2×2 Array{Int8,2}: + 0 0 + 0 0 + +julia> zeros((2, 2)) +2×2 Array{Float64,2}: + 0.0 0.0 + 0.0 0.0 +``` +Here, `(2, 2)` is a [`Tuple`](@ref). + ### Concatenation Arrays can be constructed and also concatenated using the following functions: @@ -89,7 +108,18 @@ Arrays can be constructed and also concatenated using the following functions: | [`vcat(A...)`](@ref) | shorthand for `cat(A...; dims=1)` | | [`hcat(A...)`](@ref) | shorthand for `cat(A...; dims=2)` | -Scalar values passed to these functions are treated as 1-element arrays. +Scalar values passed to these functions are treated as 1-element arrays. For example, +```jldoctest +julia> vcat([1, 2], 3) +3-element Array{Int64,1}: + 1 + 2 + 3 + +julia> hcat([1 2], 3) +1×3 Array{Int64,2}: + 1 2 3 +``` The concatenation functions are used so often that they have special syntax: @@ -100,6 +130,24 @@ The concatenation functions are used so often that they have special syntax: | `[A B; C D; ...]` | [`hvcat`](@ref) | [`hvcat`](@ref) concatenates in both dimension 1 (with semicolons) and dimension 2 (with spaces). +Consider these examples of this syntax: +```jldoctest +julia> [[1; 2]; [3, 4]] +4-element Array{Int64,1}: + 1 + 2 + 3 + 4 + +julia> [[1 2] [3 4]] +1×4 Array{Int64,2}: + 1 2 3 4 + +julia> [[1 2]; [3 4]] +2×2 Array{Int64,2}: + 1 2 + 3 4 +``` ### Typed array initializers @@ -422,6 +470,50 @@ indices and can be converted to such by [`to_indices`](@ref): * [`Colon()`](@ref) (`:`), which represents all indices within an entire dimension or across the entire array * Arrays of booleans, which select elements at their `true` indices (see below for more details) +Some examples: +```jldoctest +julia> A = reshape(collect(1:2:18), (3, 3)) +3×3 Array{Int64,2}: + 1 7 13 + 3 9 15 + 5 11 17 + +julia> A[4] +7 + +julia> A[[2, 5, 8]] +3-element Array{Int64,1}: + 3 + 9 + 15 + +julia> A[[1 4; 3 8]] +2×2 Array{Int64,2}: + 1 7 + 5 15 + +julia> A[[]] +0-element Array{Int64,1} + +julia> A[1:2:5] +3-element Array{Int64,1}: + 1 + 5 + 9 + +julia> A[2, :] +3-element Array{Int64,1}: + 3 + 9 + 15 + +julia> A[:, 3] +3-element Array{Int64,1}: + 13 + 15 + 17 +``` + #### Cartesian indices The special `CartesianIndex{N}` object represents a scalar index that behaves diff --git a/codex/manual/mathematical-operations.md b/codex/manual/mathematical-operations.md index 1e8ccca..aae4ce1 100644 --- a/codex/manual/mathematical-operations.md +++ b/codex/manual/mathematical-operations.md @@ -528,12 +528,11 @@ sin cos tan cot sec csc sinh cosh tanh coth sech csch asin acos atan acot asec acsc asinh acosh atanh acoth asech acsch -sinc cosc atan2 +sinc cosc ``` -These are all single-argument functions, with the exception of [atan2](https://en.wikipedia.org/wiki/Atan2), -which gives the angle in [radians](https://en.wikipedia.org/wiki/Radian) between the *x*-axis -and the point specified by its arguments, interpreted as *x* and *y* coordinates. +These are all single-argument functions, with [`atan`](@ref) also accepting two arguments +corresponding to a traditional [`atan2`](https://en.wikipedia.org/wiki/Atan2) function. Additionally, [`sinpi(x)`](@ref) and [`cospi(x)`](@ref) are provided for more accurate computations of [`sin(pi*x)`](@ref) and [`cos(pi*x)`](@ref) respectively. diff --git a/codex/manual/performance-tips.md b/codex/manual/performance-tips.md index 1ecac2d..a0c2d0b 100644 --- a/codex/manual/performance-tips.md +++ b/codex/manual/performance-tips.md @@ -21,16 +21,23 @@ const DEFAULT_VAL = 0 Uses of non-constant globals can be optimized by annotating their types at the point of use: ```julia -global x -y = f(x::Int + 1) +global x = rand(1000) + +function loop_over_global() + s = 0.0 + for i in x::Vector{Float64} + s += i + end + return s +end ``` -Writing functions is better style. It leads to more reusable code and clarifies what steps are -being done, and what their inputs and outputs are. +Passing arguments to functions is better style. It leads to more reusable code and clarifies what the inputs and outputs are. !!! note All code in the REPL is evaluated in global scope, so a variable defined and assigned - at toplevel will be a **global** variable. + at toplevel will be a **global** variable. Variables defined in at top level scope inside + modules are also global. In the following REPL session: @@ -48,79 +55,101 @@ so all the performance issues discussed previously apply. ## Measure performance with [`@time`](@ref) and pay attention to memory allocation -A useful tool for measuring performance is the [`@time`](@ref) macro. The following example -illustrates good working style: +A useful tool for measuring performance is the [`@time`](@ref) macro. We here repeat the example +with the global variable above, but this time with the type annotation removed: -```julia-repl -julia> function f(n) - s = 0 - for i = 1:n - s += i/2 +```jldoctest; setup = :(using Random; srand(1234)), filter = r"[0-9\.]+ seconds \(.*?\)" +julia> x = rand(1000); + +julia> function sum_global() + s = 0.0 + for i in x + s += i end - s - end -f (generic function with 1 method) + return s + end; -julia> @time f(1) - 0.012686 seconds (2.09 k allocations: 103.421 KiB) -0.5 +julia> @time sum_global() + 0.017705 seconds (15.28 k allocations: 694.484 KiB) +496.84883432553846 -julia> @time f(10^6) - 0.021061 seconds (3.00 M allocations: 45.777 MiB, 11.69% gc time) -2.5000025e11 +julia> @time sum_global() + 0.000140 seconds (3.49 k allocations: 70.313 KiB) +496.84883432553846 ``` -On the first call (`@time f(1)`), `f` gets compiled. (If you've not yet used [`@time`](@ref) +On the first call (`@time sum_global()`) the function gets compiled. (If you've not yet used [`@time`](@ref) in this session, it will also compile functions needed for timing.) You should not take the results of this run seriously. For the second run, note that in addition to reporting the time, it also -indicated that a large amount of memory was allocated. +indicated that a significant amount of memory was allocated. We are here just computing a sum over all elements in +a vector of 64-bit floats so there should be no need to allocate memory (at least not on the heap which is what `@time` reports). Unexpected memory allocation is almost always a sign of some problem with your code, usually a -problem with type-stability. Consequently, in addition to the allocation itself, it's very likely +problem with type-stability or creating many small temporary arrays. +Consequently, in addition to the allocation itself, it's very likely that the code generated for your function is far from optimal. Take such indications seriously and follow the advice below. -For more serious benchmarking, consider the [BenchmarkTools.jl](https://github.com/JuliaCI/BenchmarkTools.jl) -package which evaluates the function multiple times in order to reduce noise. - -As a teaser, an improved version of this function allocates no memory +If we instead pass `x` as an argument to the function it no longer allocates memory (the allocation reported below is due to running the `@time` macro in global scope) -and has an order of magnitude faster execution after the first call: +and is significantly faster after the first call: -```julia-repl -julia> @time f_improved(1) - 0.007008 seconds (1.32 k allocations: 63.640 KiB) -0.5 +```jldoctest sumarg; setup = :(using Random; srand(1234)), filter = r"[0-9\.]+ seconds \(.*?\)" +julia> x = rand(1000); -julia> @time f_improved(10^6) - 0.002997 seconds (6 allocations: 192 bytes) -2.5000025e11 +julia> function sum_arg(x) + s = 0.0 + for i in x + s += i + end + return s + end; + +julia> @time sum_arg(x) + 0.007701 seconds (821 allocations: 43.059 KiB) +496.84883432553846 + +julia> @time sum_arg(x) + 0.000006 seconds (5 allocations: 176 bytes) +496.84883432553846 ``` -Below you'll learn how to spot the problem with `f` and how to fix it. +The 5 allocations seen are from running the `@time` macro itself in global scope. If we instead run +the timing in a function, we can see that indeed no allocations are performed: + +```jldoctest sumarg; filter = r"[0-9\.]+ seconds" +julia> time_sum(x) = @time sum_arg(x); + +julia> time_sum(x) + 0.000001 seconds +496.84883432553846 +``` In some situations, your function may need to allocate memory as part of its operation, and this can complicate the simple picture above. In such cases, consider using one of the [tools](@ref tools) below to diagnose problems, or write a version of your function that separates allocation from its algorithmic aspects (see [Pre-allocating outputs](@ref)). +!!! note + For more serious benchmarking, consider the [BenchmarkTools.jl](https://github.com/JuliaCI/BenchmarkTools.jl) + package which among other things evaluates the function multiple times in order to reduce noise. + ## [Tools](@id tools) Julia and its package ecosystem includes tools that may help you diagnose problems and improve the performance of your code: * [Profiling](@ref) allows you to measure the performance of your running code and identify lines - that serve as bottlenecks. For complex projects, the [ProfileView](https://github.com/timholy/ProfileView.jl) + that serve as bottlenecks. For complex projects, the [ProfileView](https://github.com/timholy/ProfileView.jl) package can help you visualize your profiling results. + * The [Traceur](https://github.com/MikeInnes/Traceur.jl) package can help you find common performance problems in your code. * Unexpectedly-large memory allocations--as reported by [`@time`](@ref), [`@allocated`](@ref), or the profiler (through calls to the garbage-collection routines)--hint that there might be issues - with your code. If you don't see another reason for the allocations, suspect a type problem. + with your code. If you don't see another reason for the allocations, suspect a type problem. You can also start Julia with the `--track-allocation=user` option and examine the resulting - `*.mem` files to see information about where those allocations occur. See [Memory allocation analysis](@ref). + `*.mem` files to see information about where those allocations occur. See [Memory allocation analysis](@ref). * `@code_warntype` generates a representation of your code that can be helpful in finding expressions that result in type uncertainty. See [`@code_warntype`](@ref) below. - * The [Lint](https://github.com/tonyhffong/Lint.jl) - package can also warn you of certain types of programming errors. ## Avoid containers with abstract type parameters @@ -129,23 +158,36 @@ abstract types where possible. Consider the following: -```julia -a = Real[] # typeof(a) = Array{Real,1} -if (f = rand()) < .8 - push!(a, f) -end +```jldoctest +julia> a = Real[] +0-element Array{Real,1} + +julia> push!(a, 1); push!(a, 2.0); push!(a, π) +3-element Array{Real,1}: + 1 + 2.0 + π = 3.1415926535897... ``` Because `a` is a an array of abstract type [`Real`](@ref), it must be able to hold any -`Real` value. Since `Real` objects can be of arbitrary size and structure, `a` must be -represented as an array of pointers to individually allocated `Real` objects. Because `f` -will always be a [`Float64`](@ref), we should instead, use: +`Real` value. Since `Real` objects can be of arbitrary size and structure, `a` must be +represented as an array of pointers to individually allocated `Real` objects. However, if we instead +only allow numbers of the same type, e.g. [`Float64`](@ref), to be stored in `a` these can be stored more +efficiently: -```julia -a = Float64[] # typeof(a) = Array{Float64,1} +```jldoctest +julia> a = Float64[] +0-element Array{Float64,1} + +julia> push!(a, 1); push!(a, 2.0); push!(a, π) +3-element Array{Float64,1}: + 1.0 + 2.0 + 3.141592653589793 ``` -which will create a contiguous block of 64-bit floating-point values that can be manipulated efficiently. +Assigning numbers into `a` will now convert them to `Float64` and `a` will be stored as +a contiguous block of 64-bit floating-point values that can be manipulated efficiently. See also the discussion under [Parametric Types](@ref). @@ -168,7 +210,7 @@ julia> struct MyAmbiguousType This allows `a` to be of any type. This can often be useful, but it does have a downside: for objects of type `MyAmbiguousType`, the compiler will not be able to generate high-performance -code. The reason is that the compiler uses the types of objects, not their values, to determine +code. The reason is that the compiler uses the types of objects, not their values, to determine how to build code. Unfortunately, very little can be inferred about an object of type `MyAmbiguousType`: ```jldoctest myambig @@ -185,7 +227,7 @@ julia> typeof(c) MyAmbiguousType ``` -`b` and `c` have the same type, yet their underlying representation of data in memory is very +The values of `b` and `c` have the same type, yet their underlying representation of data in memory is very different. Even if you stored just numeric values in field `a`, the fact that the memory representation of a [`UInt8`](@ref) differs from a [`Float64`](@ref) also means that the CPU needs to handle them using two different kinds of instructions. Since the required information is not available @@ -208,7 +250,7 @@ julia> mutable struct MyStillAmbiguousType end ``` -because the first version specifies the type of `a` from the type of the wrapper object. For +because the first version specifies the type of `a` from the type of the wrapper object. For example: ```jldoctest myambig2 @@ -226,7 +268,7 @@ MyStillAmbiguousType ``` The type of field `a` can be readily determined from the type of `m`, but not from the type of -`t`. Indeed, in `t` it's possible to change the type of field `a`: +`t`. Indeed, in `t` it's possible to change the type of the field `a`: ```jldoctest myambig2 julia> typeof(t.a) @@ -249,11 +291,11 @@ julia> typeof(m.a) Float64 ``` -The fact that the type of `m.a` is known from `m`'s type--coupled with the fact that its type -cannot change mid-function--allows the compiler to generate highly-optimized code for objects +The fact that the type of `m.a` is known from `m`'s type—coupled with the fact that its type +cannot change mid-function—allows the compiler to generate highly-optimized code for objects like `m` but not for objects like `t`. -Of course, all of this is true only if we construct `m` with a concrete type. We can break this +Of course, all of this is true only if we construct `m` with a concrete type. We can break this by explicitly constructing it with an abstract type: ```jldoctest myambig2 @@ -281,9 +323,8 @@ func(m::MyType) = m.a+1 using ```julia -code_llvm(func,Tuple{MyType{Float64}}) -code_llvm(func,Tuple{MyType{AbstractFloat}}) -code_llvm(func,Tuple{MyType}) +code_llvm(func, Tuple{MyType{Float64}}) +code_llvm(func, Tuple{MyType{AbstractFloat}}) ``` For reasons of length the results are not shown here, but you may wish to try this yourself. Because @@ -295,11 +336,11 @@ to resolve the type at run-time. This results in shorter and faster code. The same best practices also work for container types: ```jldoctest containers -julia> mutable struct MySimpleContainer{A<:AbstractVector} +julia> struct MySimpleContainer{A<:AbstractVector} a::A end -julia> mutable struct MyAmbiguousContainer{T} +julia> struct MyAmbiguousContainer{T} a::AbstractVector{T} end ``` @@ -332,10 +373,10 @@ For `MySimpleContainer`, the object is fully-specified by its type and parameter can generate optimized functions. In most instances, this will probably suffice. While the compiler can now do its job perfectly well, there are cases where *you* might wish that -your code could do different things depending on the *element type* of `a`. Usually the best +your code could do different things depending on the *element type* of `a`. Usually the best way to achieve this is to wrap your specific operation (here, `foo`) in a separate function: -```julia jldoctest containers +```jldoctest containers julia> function sumfoo(c::MySimpleContainer) s = 0 for x in c.a @@ -355,109 +396,37 @@ foo (generic function with 2 methods) This keeps things simple, while allowing the compiler to generate optimized code in all cases. However, there are cases where you may need to declare different versions of the outer function -for different element types of `a`. You could do it like this: +for different element types or types of the `AbstractVector` of the field `a` in `MySimpleContainer`. +You could do it like this: -``` -function myfun(c::MySimpleContainer{Vector{T}}) where T<:AbstractFloat - ... -end -function myfun(c::MySimpleContainer{Vector{T}}) where T<:Integer - ... -end -``` - -This works fine for `Vector{T}`, but we'd also have to write explicit versions for `UnitRange{T}` -or other abstract types. To prevent such tedium, you can use two parameters in the declaration -of `MyContainer`: - -```jldoctest containers2 -julia> mutable struct MyContainer{T, A<:AbstractVector} - a::A - end - -julia> MyContainer(v::AbstractVector) = MyContainer{eltype(v), typeof(v)}(v) -MyContainer - -julia> b = MyContainer(1:5); - -julia> typeof(b) -MyContainer{Int64,UnitRange{Int64}} -``` - -Note the somewhat surprising fact that `T` doesn't appear in the declaration of field `a`, a point -that we'll return to in a moment. With this approach, one can write functions such as: - -```jldoctest containers2 -julia> function myfunc(c::MyContainer{<:Integer, <:AbstractArray}) +```jldoctest containers +julia> function myfunc(c::MySimpleContainer{<:AbstractArray{<:Integer}}) return c.a[1]+1 end myfunc (generic function with 1 method) -julia> function myfunc(c::MyContainer{<:AbstractFloat}) +julia> function myfunc(c::MySimpleContainer{<:AbstractArray{<:AbstractFloat}}) return c.a[1]+2 end myfunc (generic function with 2 methods) -julia> function myfunc(c::MyContainer{T,Vector{T}}) where T<:Integer +julia> function myfunc(c::MySimpleContainer{Vector{T}}) where T <: Integer return c.a[1]+3 end myfunc (generic function with 3 methods) ``` -!!! note - Because we can only define `MyContainer` for - `A<:AbstractArray`, and any unspecified parameters are arbitrary, - the first function above could have been written more succinctly as - `function myfunc(c::MyContainer{<:Integer})` - - -```jldoctest containers2 -julia> myfunc(MyContainer(1:3)) +```jldoctest containers +julia> myfunc(MySimpleContainer(1:3)) 2 -julia> myfunc(MyContainer(1.0:3)) +julia> myfunc(MySimpleContainer(1.0:3)) 3.0 -julia> myfunc(MyContainer([1:3;])) +julia> myfunc(MySimpleContainer([1:3;])) 4 ``` -As you can see, with this approach it's possible to specialize on both the element type `T` and -the array type `A`. - -However, there's one remaining hole: we haven't enforced that `A` has element type `T`, so it's -perfectly possible to construct an object like this: - -```jldoctest containers2 -julia> b = MyContainer{Int64, UnitRange{Float64}}(UnitRange(1.3, 5.0)); - -julia> typeof(b) -MyContainer{Int64,UnitRange{Float64}} -``` - -To prevent this, we can add an inner constructor: - -```jldoctest containers3 -julia> mutable struct MyBetterContainer{T<:Real, A<:AbstractVector} - a::A - MyBetterContainer{T,A}(v::AbstractVector{T}) where {T,A} = new(v) - end - -julia> MyBetterContainer(v::AbstractVector) = MyBetterContainer{eltype(v),typeof(v)}(v) -MyBetterContainer - -julia> b = MyBetterContainer(UnitRange(1.3, 5.0)); - -julia> typeof(b) -MyBetterContainer{Float64,UnitRange{Float64}} - -julia> b = MyBetterContainer{Int64, UnitRange{Float64}}(UnitRange(1.3, 5.0)); -ERROR: MethodError: Cannot `convert` an object of type UnitRange{Float64} to an object of type MyBetterContainer{Int64,UnitRange{Float64}} -[...] -``` - -The inner constructor requires that the element type of `A` be `T`. - ### Annotate values taken from untyped locations It is often convenient to work with data structures that may contain values of any type (arrays @@ -477,7 +446,7 @@ an annotation like this has the added benefit that it will raise a run-time erro value is not of the expected type, potentially catching certain bugs earlier. In the case that the type of `a[1]` is not known precisely, `x` can be declared via -`x = convert(Int32,a[1])::Int32`. The use of the [`convert`](@ref) function allows `a[1]` +`x = convert(Int32, a[1])::Int32`. The use of the [`convert`](@ref) function allows `a[1]` to be any object convertible to an `Int32` (such as `UInt8`), thus increasing the genericity of the code by loosening the type requirement. Notice that `convert` itself needs a type annotation in this context in order to achieve type stability. This is because the compiler @@ -540,13 +509,15 @@ code, or even inline it. Here is an example of a "compound function" that should really be written as multiple definitions: ```julia -function norm(A) +using LinearAlgebra + +function mynorm(A) if isa(A, Vector) return sqrt(real(dot(A,A))) elseif isa(A, Matrix) return maximum(svdvals(A)) else - error("norm: invalid argument") + error("mynorm: invalid argument") end end ``` @@ -554,10 +525,13 @@ end This can be written more concisely and efficiently as: ```julia -norm(x::Vector) = sqrt(real(dot(x,x))) +norm(x::Vector) = sqrt(real(dot(x, x))) norm(A::Matrix) = maximum(svdvals(A)) ``` +It should however be noted that the compiler is quite efficient at optimizing away the dead branches in code +written as the `mynorm` example. + ## Write "type-stable" functions When possible, it helps to ensure that a function always returns a value of the same type. Consider @@ -576,7 +550,7 @@ easily be fixed as follows: pos(x) = x < 0 ? zero(x) : x ``` -There is also a [`one`](@ref) function, and a more general [`oftype(x, y)`](@ref) function, which +There is also a [`oneunit`](@ref) function, and a more general [`oftype(x, y)`](@ref) function, which returns `y` converted to the type of `x`. ## Avoid changing the type of a variable @@ -587,7 +561,7 @@ An analogous "type-stability" problem exists for variables used repeatedly withi function foo() x = 1 for i = 1:10 - x = x/bar() + x /= rand() end return x end @@ -599,8 +573,8 @@ optimize the body of the loop. There are several possible fixes: * Initialize `x` with `x = 1.0` * Declare the type of `x`: `x::Float64 = 1` - * Use an explicit conversion: `x = oneunit(T)` - * Initialize with the first loop iteration, to `x = 1/bar()`, then loop `for i = 2:10` + * Use an explicit conversion: `x = oneunit(Float64)` + * Initialize with the first loop iteration, to `x = 1 / rand()`, then loop `for i = 2:10` ## [Separate kernel functions (aka, function barriers)](@id kernal-functions) @@ -609,22 +583,14 @@ to perform a core computation. Where possible, it is a good idea to put these co in separate functions. For example, the following contrived function returns an array of a randomly-chosen type: -```@meta -DocTestSetup = quote - import Random - Random.srand(1234) -end -``` - -```jldoctest +```jldoctest; setup = :(using Random; srand(1234)) julia> function strange_twos(n) a = Vector{rand(Bool) ? Int64 : Float64}(undef, n) for i = 1:n a[i] = 2 end return a - end -strange_twos (generic function with 1 method) + end; julia> strange_twos(3) 3-element Array{Float64,1}: @@ -635,20 +601,18 @@ julia> strange_twos(3) This should be written as: -```jldoctest +```jldoctest; setup = :(using Random; srand(1234)) julia> function fill_twos!(a) for i = eachindex(a) a[i] = 2 end - end -fill_twos! (generic function with 1 method) + end; julia> function strange_twos(n) a = Vector{rand(Bool) ? Int64 : Float64}(undef, n) fill_twos!(a) return a - end -strange_twos (generic function with 1 method) + end; julia> strange_twos(3) 3-element Array{Float64,1}: @@ -664,9 +628,9 @@ of `fill_twos!` for different types of `a`. The second form is also often better style and can lead to more code reuse. -This pattern is used in several places in Julia Base. For example, see `hvcat_fill` -in [`abstractarray.jl`](https://github.com/JuliaLang/julia/blob/master/base/abstractarray.jl), or -the [`fill!`](@ref) function, which we could have used instead of writing our own `fill_twos!`. +This pattern is used in several places in Julia Base. For example, see `vcat` and `hcat` +in [`abstractarray.jl`](https://github.com/JuliaLang/julia/blob/40fe264f4ffaa29b749bcf42239a89abdcbba846/base/abstractarray.jl#L1205-L1206), +or the [`fill!`](@ref) function, which we could have used instead of writing our own `fill_twos!`. Functions like `strange_twos` occur when dealing with data of uncertain type, for example data loaded from an input file that might contain either integers, floats, strings, or something else. @@ -712,7 +676,7 @@ function has to be conservative, checking the type on each access of `A`; such c slow. Now, one very good way to solve such problems is by using the [function-barrier technique](@ref kernal-functions). -However, in some cases you might want to eliminate the type-instability altogether. In such cases, +However, in some cases you might want to eliminate the type-instability altogether. In such cases, one approach is to pass the dimensionality as a parameter, for example through `Val{T}()` (see ["Value types"](@ref)): @@ -743,8 +707,8 @@ end ``` Here, you've created the same problem all over again: the compiler can't guess what `n` is, -so it doesn't know the *type* of `Val(n)`. Attempting to use `Val`, but doing so incorrectly, can -easily make performance *worse* in many situations. (Only in situations where you're effectively +so it doesn't know the *type* of `Val(n)`. Attempting to use `Val`, but doing so incorrectly, can +easily make performance *worse* in many situations. (Only in situations where you're effectively combining `Val` with the function-barrier trick, to make the kernel function more efficient, should code like the above be used.) @@ -757,7 +721,7 @@ function filter3(A::AbstractArray{T,N}) where {T,N} end ``` -In this example, `N` is passed as a parameter, so its "value" is known to the compiler. Essentially, +In this example, `N` is passed as a parameter, so its "value" is known to the compiler. Essentially, `Val(T)` works only when `T` is either hard-coded/literal (`Val(3)`) or already specified in the type-domain. @@ -768,7 +732,7 @@ and try to use it for everything. For example, you might imagine using it to sto e.g. ``` -struct Car{Make,Model} +struct Car{Make, Model} year::Int ...more fields... end @@ -776,10 +740,11 @@ end and then dispatch on objects like `Car{:Honda,:Accord}(year, args...)`. -This might be worthwhile when the following are true: +This might be worthwhile when either of the following are true: * You require CPU-intensive processing on each `Car`, and it becomes vastly more efficient if you - know the `Make` and `Model` at compile time. + know the `Make` and `Model` at compile time and the total number of different `Make` or `Model` + that will be used is not too large. * You have homogenous lists of the same type of `Car` to process, so that you can store them all in an `Array{Car{:Honda,:Accord},N}`. @@ -789,7 +754,7 @@ type), so Julia can "look up" the correct method calls when the function is bein the need to check at run-time) and thereby emit efficient code for processing the whole list. When these do not hold, then it's likely that you'll get no benefit; worse, the resulting "combinatorial -explosion of types" will be counterproductive. If `items[i+1]` has a different type than `item[i]`, +explosion of types" will be counterproductive. If `items[i+1]` has a different type than `item[i]`, Julia has to look up the type at run-time, search for the appropriate method in method tables, decide (via type intersection) which one matches, determine whether it has been JIT-compiled yet (and do so if not), and then make the call. In essence, you're asking the full type- system and @@ -803,8 +768,8 @@ Perhaps even worse than the run-time impact is the compile-time impact: Julia wi functions for each different `Car{Make, Model}`; if you have hundreds or thousands of such types, then every function that accepts such an object as a parameter (from a custom `get_year` function you might write yourself, to the generic `push!` function in Julia Base) will have hundreds -or thousands of variants compiled for it. Each of these increases the size of the cache of compiled -code, the length of internal lists of methods, etc. Excess enthusiasm for values-as-parameters +or thousands of variants compiled for it. Each of these increases the size of the cache of compiled +code, the length of internal lists of methods, etc. Excess enthusiasm for values-as-parameters can easily waste enormous resources. ## Access arrays in memory order, along columns @@ -847,7 +812,7 @@ function copy_cols(x::Vector{T}) where T for i = inds out[:, i] = x end - out + return out end function copy_rows(x::Vector{T}) where T @@ -856,7 +821,7 @@ function copy_rows(x::Vector{T}) where T for i = inds out[i, :] = x end - out + return out end function copy_col_row(x::Vector{T}) where T @@ -865,7 +830,7 @@ function copy_col_row(x::Vector{T}) where T for col = inds, row = inds out[row, col] = x[row] end - out + return out end function copy_row_col(x::Vector{T}) where T @@ -874,7 +839,7 @@ function copy_row_col(x::Vector{T}) where T for row = inds, col = inds out[row, col] = x[col] end - out + return out end ``` @@ -900,50 +865,50 @@ first element to appear in a slice expression should be coupled with the inner-m ## Pre-allocating outputs If your function returns an `Array` or some other complex type, it may have to allocate memory. - Unfortunately, oftentimes allocation and its converse, garbage collection, are substantial bottlenecks. +Unfortunately, oftentimes allocation and its converse, garbage collection, are substantial bottlenecks. Sometimes you can circumvent the need to allocate memory on each function call by preallocating -the output. As a trivial example, compare - -```julia -function xinc(x) - return [x, x+1, x+2] -end - -function loopinc() - y = 0 - for i = 1:10^7 - ret = xinc(i) - y += ret[2] - end - y -end +the output. As a trivial example, compare + +```jldoctest prealloc +julia> function xinc(x) + return [x, x+1, x+2] + end; + +julia> function loopinc() + y = 0 + for i = 1:10^7 + ret = xinc(i) + y += ret[2] + end + return y + end; ``` with -```julia -function xinc!(ret::AbstractVector{T}, x::T) where T - ret[1] = x - ret[2] = x+1 - ret[3] = x+2 - nothing -end - -function loopinc_prealloc() - ret = Vector{Int}(undef, 3) - y = 0 - for i = 1:10^7 - xinc!(ret, i) - y += ret[2] - end - y -end +```jldoctest prealloc +julia> function xinc!(ret::AbstractVector{T}, x::T) where T + ret[1] = x + ret[2] = x+1 + ret[3] = x+2 + nothing + end; + +julia> function loopinc_prealloc() + ret = Vector{Int}(undef, 3) + y = 0 + for i = 1:10^7 + xinc!(ret, i) + y += ret[2] + end + return y + end; ``` Timing results: -```julia-repl +```jldoctest prealloc; filter = r"[0-9\.]+ seconds \(.*?\)" julia> @time loopinc() 0.529894 seconds (40.00 M allocations: 1.490 GiB, 12.14% gc time) 50000015000000 @@ -954,7 +919,7 @@ julia> @time loopinc_prealloc() ``` Preallocation has other advantages, for example by allowing the caller to control the "output" -type from an algorithm. In the example above, we could have passed a `SubArray` rather than an +type from an algorithm. In the example above, we could have passed a `SubArray` rather than an [`Array`](@ref), had we so desired. Taken to its extreme, pre-allocation can make your code uglier, so performance measurements and @@ -978,30 +943,30 @@ to instead use `vector .+ vector` and `vector .* scalar` because the resulting loops can be fused with surrounding computations. For example, consider the two functions: -```julia -f(x) = 3x.^2 + 4x + 7x.^3 +```jldoctest dotfuse +julia> f(x) = 3x.^2 + 4x + 7x.^3; -fdot(x) = @. 3x^2 + 4x + 7x^3 # equivalent to 3 .* x.^2 .+ 4 .* x .+ 7 .* x.^3 +julia> fdot(x) = @. 3x^2 + 4x + 7x^3 # equivalent to 3 .* x.^2 .+ 4 .* x .+ 7 .* x.^3; ``` -Both `f` and `fdot` compute the same thing. However, `fdot` +Both `f` and `fdot` compute the same thing. However, `fdot` (defined with the help of the [`@.`](@ref @__dot__) macro) is significantly faster when applied to an array: -```julia-repl +```jldoctest dotfuse; filter = r"[0-9\.]+ seconds \(.*?\)" julia> x = rand(10^6); julia> @time f(x); - 0.010986 seconds (18 allocations: 53.406 MiB, 11.45% gc time) + 0.019049 seconds (16 allocations: 45.777 MiB, 18.59% gc time) julia> @time fdot(x); - 0.003470 seconds (6 allocations: 7.630 MiB) + 0.002790 seconds (6 allocations: 7.630 MiB) julia> @time f.(x); - 0.003297 seconds (30 allocations: 7.631 MiB) + 0.002626 seconds (8 allocations: 7.630 MiB) ``` -That is, `fdot(x)` is three times faster and allocates 1/7 the +That is, `fdot(x)` is ten times faster and allocates 1/6 the memory of `f(x)`, because each `*` and `+` operation in `f(x)` allocates a new temporary array and executes in a separate loop. (Of course, if you just do `f.(x)` then it is as fast as `fdot(x)` in this @@ -1023,16 +988,16 @@ substantial. An alternative is to create a "view" of the array, which is an array object (a `SubArray`) that actually references the data -of the original array in-place, without making a copy. (If you +of the original array in-place, without making a copy. (If you write to a view, it modifies the original array's data as well.) This can be done for individual slices by calling [`view`](@ref), or more simply for a whole expression or block of code by putting -[`@views`](@ref) in front of that expression. For example: +[`@views`](@ref) in front of that expression. For example: -```julia-repl -julia> fcopy(x) = sum(x[2:end-1]) +```jldoctest; filter = r"[0-9\.]+ seconds \(.*?\)" +julia> fcopy(x) = sum(x[2:end-1]); -julia> @views fview(x) = sum(x[2:end-1]) +julia> @views fview(x) = sum(x[2:end-1]); julia> x = rand(10^6); @@ -1056,9 +1021,11 @@ can drastically slow down computations on arrays because of non-sequential memor Copying irregularly-accessed data into a contiguous array before operating on it can result in a large speedup, such as in the example below. Here, a matrix and a vector are being accessed at 800,000 of their randomly-shuffled indices before being multiplied. Copying the views into -plain arrays speeds the multiplication by more than a factor of 2 even with the cost of the copying operation. +plain arrays speeds up the multiplication even with the cost of the copying operation. ```julia-repl +julia> using Random + julia> x = randn(1_000_000); julia> inds = shuffle(1:1_000_000)[1:800000]; @@ -1070,17 +1037,18 @@ julia> xtmp = zeros(800_000); julia> Atmp = zeros(50, 800_000); julia> @time sum(view(A, :, inds) * view(x, inds)) - 0.640320 seconds (41 allocations: 1.391 KiB) -7253.242699002263 + 0.412156 seconds (14 allocations: 960 bytes) +-4256.759568345458 julia> @time begin copyto!(xtmp, view(x, inds)) copyto!(Atmp, view(A, :, inds)) sum(Atmp * xtmp) end - 0.261294 seconds (41 allocations: 1.391 KiB) -7253.242699002323 + 0.285923 seconds (14 allocations: 960 bytes) +-4256.759568345134 ``` + Provided there is enough memory for the copies, the cost of copying the view to an array is far outweighed by the speed boost from doing the matrix multiplication on a contiguous array. @@ -1118,7 +1086,9 @@ println(file, f(a), f(b)) When executing a remote function in parallel: ```julia -responses = Vector{Any}(nworkers()) +using Distributed + +responses = Vector{Any}(undef, nworkers()) @sync begin for (idx, pid) in enumerate(workers()) @async responses[idx] = remotecall_fetch(pid, foo, args...) @@ -1129,7 +1099,9 @@ end is faster than: ```julia -refs = Vector{Any}(nworkers()) +using Distributed + +refs = Vector{Any}(undef, nworkers()) for (idx, pid) in enumerate(workers()) refs[idx] = @spawnat pid foo(args...) end @@ -1173,44 +1145,46 @@ The common idiom of using 1:n to index into an AbstractArray is not safe if the and may cause a segmentation fault if bounds checking is turned off. Use `LinearIndices(x)` or `eachindex(x)` instead (see also [offset-arrays](https://docs.julialang.org/en/latest/devdocs/offset-arrays)). -Note: While `@simd` needs to be placed directly in front of a loop, both `@inbounds` and `@fastmath` -can be applied to several statements at once, e.g. using `begin` ... `end`, or even to a whole -function. +!!!note + While `@simd` needs to be placed directly in front of a loop, both `@inbounds` and `@fastmath` + can be applied to several statements at once, e.g. using `begin` ... `end`, or even to a whole + function. -Here is an example with both `@inbounds` and `@simd` markup: +Here is an example with both `@inbounds` and `@simd` markup (we here use `@noinline` to prevent +the optimizer from trying to be too clever and defeat our benchmark): ```julia -function inner(x, y) +@noinline function inner(x, y) s = zero(eltype(x)) for i=eachindex(x) @inbounds s += x[i]*y[i] end - s + return s end -function innersimd(x, y) +@noinline function innersimd(x, y) s = zero(eltype(x)) - @simd for i=eachindex(x) - @inbounds s += x[i]*y[i] + @simd for i = eachindex(x) + @inbounds s += x[i] * y[i] end - s + return s end function timeit(n, reps) - x = rand(Float32,n) - y = rand(Float32,n) + x = rand(Float32, n) + y = rand(Float32, n) s = zero(Float64) time = @elapsed for j in 1:reps - s+=inner(x,y) + s += inner(x, y) end - println("GFlop/sec = ",2.0*n*reps/time*1E-9) + println("GFlop/sec = ", 2n*reps / time*1E-9) time = @elapsed for j in 1:reps - s+=innersimd(x,y) + s += innersimd(x, y) end - println("GFlop/sec (SIMD) = ",2.0*n*reps/time*1E-9) + println("GFlop/sec (SIMD) = ", 2n*reps / time*1E-9) end -timeit(1000,1000) +timeit(1000, 1000) ``` On a computer with a 2.4GHz Intel Core i5 processor, this produces: @@ -1270,7 +1244,7 @@ function deriv!(u::Vector, du) @fastmath @inbounds du[n] = (u[n] - u[n-1]) / dx end -function norm(u::Vector) +function mynorm(u::Vector) n = length(u) T = eltype(u) s = zero(T) @@ -1287,11 +1261,11 @@ function main() du = similar(u) deriv!(u, du) - nu = norm(du) + nu = mynorm(du) @time for i in 1:10^6 deriv!(u, du) - nu = norm(du) + nu = mynorm(du) end println(nu) @@ -1304,10 +1278,12 @@ On a computer with a 2.7 GHz Intel Core i7 processor, this produces: ``` $ julia wave.jl; -elapsed time: 1.207814709 seconds (0 bytes allocated) + 1.207814709 seconds +4.443986180758249 $ julia --math-mode=ieee wave.jl; -elapsed time: 4.487083643 seconds (0 bytes allocated) + 4.487083643 seconds +4.443986180758249 ``` Here, the option `--math-mode=ieee` disables the `@fastmath` macro, so that we can compare results. @@ -1329,6 +1305,20 @@ is much faster to evaluate. Of course, both the actual optimization that is appl as well as the resulting speedup depend very much on the hardware. You can examine the change in generated code by using Julia's [`code_native`](@ref) function. +Note that `@fastmath` also assumes that `NaN`s will not occur during the computation, which can lead to surprising behavior: + +```julia-repl +julia> f(x) = isnan(x); + +julia> f(NaN) +true + +julia> f_fast(x) = @fastmath isnan(x); + +julia> f_fast(NaN) +false +``` + ## Treat Subnormal Numbers as Zeros Subnormal numbers, formerly called [denormal numbers](https://en.wikipedia.org/wiki/Denormal_number), @@ -1366,6 +1356,19 @@ for trial=1:6 end ``` +This gives an output similar to + +``` + 0.002202 seconds (1 allocation: 4.063 KiB) + 0.001502 seconds (1 allocation: 4.063 KiB) + 0.002139 seconds (1 allocation: 4.063 KiB) + 0.001454 seconds (1 allocation: 4.063 KiB) + 0.002115 seconds (1 allocation: 4.063 KiB) + 0.001455 seconds (1 allocation: 4.063 KiB) +``` + +Note how each even iteration is significantly faster. + This example generates many subnormal numbers because the values in `a` become an exponentially decreasing curve, which slowly flattens out over time. @@ -1394,91 +1397,61 @@ a = rand(Float32,1000) * 1.f-9 The macro [`@code_warntype`](@ref) (or its function variant [`code_warntype`](@ref)) can sometimes be helpful in diagnosing type-related problems. Here's an example: -```julia -pos(x) = x < 0 ? 0 : x +```julia-repl +julia> @noinline pos(x) = x < 0 ? 0 : x; -function f(x) - y = pos(x) - sin(y*x+1) -end +julia> function f(x) + y = pos(x) + sin(y*x + 1) + end; julia> @code_warntype f(3.2) -Variables: - #self#::#f - x::Float64 - y::UNION{FLOAT64,INT64} - fy::Float64 - #temp#@_5::UNION{FLOAT64,INT64} - #temp#@_6::Core.MethodInstance - #temp#@_7::Float64 - -Body: - begin - $(Expr(:inbounds, false)) - # meta: location REPL[1] pos 1 - # meta: location float.jl < 487 - fy::Float64 = (Core.typeassert)((Base.sitofp)(Float64,0)::Float64,Float64)::Float64 - # meta: pop location - unless (Base.or_int)((Base.lt_float)(x::Float64,fy::Float64)::Bool,(Base.and_int)((Base.and_int)((Base.eq_float)(x::Float64,fy::Float64)::Bool,(Base.lt_float)(fy::Float64,9.223372036854776e18)::Bool)::Bool,(Base.slt_int)((Base.fptosi)(Int64,fy::Float64)::Int64,0)::Bool)::Bool)::Bool goto 9 - #temp#@_5::UNION{FLOAT64,INT64} = 0 - goto 11 - 9: - #temp#@_5::UNION{FLOAT64,INT64} = x::Float64 - 11: - # meta: pop location - $(Expr(:inbounds, :pop)) - y::UNION{FLOAT64,INT64} = #temp#@_5::UNION{FLOAT64,INT64} # line 3: - unless (y::UNION{FLOAT64,INT64} isa Int64)::ANY goto 19 - #temp#@_6::Core.MethodInstance = MethodInstance for *(::Int64, ::Float64) - goto 28 - 19: - unless (y::UNION{FLOAT64,INT64} isa Float64)::ANY goto 23 - #temp#@_6::Core.MethodInstance = MethodInstance for *(::Float64, ::Float64) - goto 28 - 23: - goto 25 - 25: - #temp#@_7::Float64 = (y::UNION{FLOAT64,INT64} * x::Float64)::Float64 - goto 30 - 28: - #temp#@_7::Float64 = $(Expr(:invoke, :(#temp#@_6), :(Main.*), :(y), :(x))) - 30: - return $(Expr(:invoke, MethodInstance for sin(::Float64), :(Main.sin), :((Base.add_float)(#temp#@_7,(Base.sitofp)(Float64,1)::Float64)::Float64))) - end::Float64 +Body::Float64 +2 1 ─ %1 = invoke Main.pos(%%x::Float64)::UNION{FLOAT64, INT64} +3 │ %2 = isa(%1, Float64)::Bool + └── goto 3 if not %2 + 2 ─ %4 = π (%1, Float64) + │ %5 = Base.mul_float(%4, %%x)::Float64 + └── goto 6 + 3 ─ %7 = isa(%1, Int64)::Bool + └── goto 5 if not %7 + 4 ─ %9 = π (%1, Int64) + │ %10 = Base.sitofp(Float64, %9)::Float64 + │ %11 = Base.mul_float(%10, %%x)::Float64 + └── goto 6 + 5 ─ Base.error("fatal error in type inference (type bound)") + └── unreachable + 6 ┄ %15 = φ (2 => %5, 4 => %11)::Float64 + │ %16 = Base.add_float(%15, 1.0)::Float64 + │ %17 = invoke Main.sin(%16::Float64)::Float64 + └── return %17 ``` Interpreting the output of [`@code_warntype`](@ref), like that of its cousins [`@code_lowered`](@ref), [`@code_typed`](@ref), [`@code_llvm`](@ref), and [`@code_native`](@ref), takes a little practice. -Your code is being presented in form that has been partially digested on its way to generating -compiled machine code. Most of the expressions are annotated by a type, indicated by the `::T` +Your code is being presented in form that has been heavily digested on its way to generating +compiled machine code. Most of the expressions are annotated by a type, indicated by the `::T` (where `T` might be [`Float64`](@ref), for example). The most important characteristic of [`@code_warntype`](@ref) is that non-concrete types are displayed in red; in the above example, such output is shown in -all-caps. - -The top part of the output summarizes the type information for the different variables internal -to the function. You can see that `y`, one of the variables you created, is a `Union{Int64,Float64}`, -due to the type-instability of `pos`. There is another variable, `_var4`, which you can see also -has the same type. - -The next lines represent the body of `f`. The lines starting with a number followed by a colon -(`1:`, `2:`) are labels, and represent targets for jumps (via `goto`) in your code. Looking at -the body, you can see that `pos` has been *inlined* into `f`--everything before `2:` comes from -code defined in `pos`. - -Starting at `2:`, the variable `y` is defined, and again annotated as a `Union` type. Next, we -see that the compiler created the temporary variable `_var1` to hold the result of `y*x`. Because -a [`Float64`](@ref) times *either* an [`Int64`](@ref) or `Float64` yields a `Float64`, -all type-instability ends here. The net result is that `f(x::Float64)` will not be type-unstable +uppercase. + +At the top, the inferred return type of the function is shown as `Body::Float64`. +The next lines represent the body of `f` in Julia's SSA IR form. +The numbered boxes are labels and represent targets for jumps (via `goto`) in your code. +Looking at the body, you can see that the first thing that happens is that `pos` is called and the +return value has been inferred as the `Union` type `UNION{FLOAT64, INT64}` shown in uppercase since +it is a non-concrete type. This means that we cannot know the exact return type of `pos` based on the +input types. However, the result of `y*x`is a `Float64` no matter if `y` is a `Float64` or `Int64` +The net result is that `f(x::Float64)` will not be type-unstable in its output, even if some of the intermediate computations are type-unstable. How you use this information is up to you. Obviously, it would be far and away best to fix `pos` to be type-stable: if you did so, all of the variables in `f` would be concrete, and its performance -would be optimal. However, there are circumstances where this kind of *ephemeral* type instability +would be optimal. However, there are circumstances where this kind of *ephemeral* type instability might not matter too much: for example, if `pos` is never used in isolation, the fact that `f`'s output is type-stable (for [`Float64`](@ref) inputs) will shield later code from the propagating -effects of type instability. This is particularly relevant in cases where fixing the type instability -is difficult or impossible: for example, currently it's not possible to infer the return type -of an anonymous function. In such cases, the tips above (e.g., adding type annotations and/or +effects of type instability. This is particularly relevant in cases where fixing the type instability +is difficult or impossible. In such cases, the tips above (e.g., adding type annotations and/or breaking up functions) are your best tools to contain the "damage" from type instability. Also, note that even Julia Base has functions that are type unstable. For example, the function [`findfirst`](@ref) returns the index into an array where a key is found, @@ -1488,21 +1461,20 @@ are color highlighted in yellow, instead of red. The following examples may help you interpret expressions marked as containing non-leaf types: - * Function body ending in `end::Union{T1,T2})` - + * Function body starting with `Body::UNION{T1,T2})` * Interpretation: function with unstable return type * Suggestion: make the return value type-stable, even if you have to annotate it - * `f(x::T)::Union{T1,T2}` - * Interpretation: call to a type-unstable function + * `invoke Main.g(%%x::Int64)::UNION{FLOAT64, INT64}` + * Interpretation: call to a type-unstable function `g`. * Suggestion: fix the function, or if necessary annotate the return value - * `(top(arrayref))(A::Array{Any,1},1)::Any` + * `invoke Base.getindex(%%x::Array{Any,1}, 1::Int64)::ANY` * Interpretation: accessing elements of poorly-typed arrays * Suggestion: use arrays with better-defined types, or if necessary annotate the type of individual element accesses - * `(top(getfield))(A::ArrayContainer{Float64},:data)::Array{Float64,N}` + * `Base.getfield(%%x, :(:data))::ARRAY{FLOAT64,N} WHERE N` * Interpretation: getting a field that is of non-leaf type. In this case, `ArrayContainer` had a field `data::Array{T}`. But `Array` needs the dimension `N`, too, to be a concrete type. * Suggestion: use concrete types like `Array{T,3}` or `Array{T,N}`, where `N` is now a parameter diff --git a/src/NEWS.md b/src/NEWS.md index 1d4714e..cb475a2 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -202,6 +202,10 @@ Language changes * `…` (`\dots`) and `⁝` (`\tricolon`) are now parsed as binary operators ([#26262](https://github.com/JuliaLang/julia/issues/26262)). + * Assignment syntax (`a=b`) inside square bracket expressions (e.g. `A[...]`, `[x, y]`) + is deprecated. It will likely be reclaimed in a later version for passing keyword + arguments. Note this does not affect updating operators like `+=` ([#25631](https://github.com/JuliaLang/julia/issues/25631)). + Breaking changes ---------------- @@ -1236,8 +1240,12 @@ Deprecated or removed * `signif` has been deprecated in favor of the `sigdigits` keyword argument to `round`. + * `Base.IntSet` has been deprecated in favor of `Base.BitSet` ([#24282](https://github.com/JuliaLang/julia/issues/24282)). + * `setrounding` has been deprecated for `Float32` and `Float64`, as the behaviour was too unreliable ([#26935](https://github.com/JuliaLang/julia/issues/26935)). + * `atan2` is now a 2-argument method of `atan` ([#27248](https://github.com/JuliaLang/julia/issues/27248)). + Command-line option changes --------------------------- diff --git a/src/base/math.md b/src/base/math.md index bc13127..1359b11 100644 --- a/src/base/math.md +++ b/src/base/math.md @@ -72,7 +72,6 @@ Base.tanh(::Number) Base.asin(::Number) Base.acos(::Number) Base.atan(::Number) -Base.Math.atan2 Base.Math.asind Base.Math.acosd Base.Math.atand diff --git a/src/devdocs/ast.md b/src/devdocs/ast.md index e019d7a..8837b92 100644 --- a/src/devdocs/ast.md +++ b/src/devdocs/ast.md @@ -19,6 +19,8 @@ The following data types exist in lowered form: Has a node type indicated by the `head` field, and an `args` field which is a `Vector{Any}` of subexpressions. + While almost every part of a surface AST is represented by an `Expr`, the IR uses only a + limited number of `Expr`s, mostly for calls, conditional branches (`gotoifnot`), and returns. * `Slot` @@ -31,19 +33,12 @@ The following data types exist in lowered form: * `CodeInfo` - Wraps the IR of a method. - - * `LineNumberNode` - - Contains a number and a file name, specifying the line number the next statement came from. - - * `LabelNode` - - Branch target, a consecutively-numbered integer starting at 0. + Wraps the IR of a method. Its `code` field is an array of expressions to execute. * `GotoNode` - Unconditional branch. + Unconditional branch. The argument is the branch target, represented as an index in + the code array to jump to. * `QuoteNode` @@ -57,12 +52,13 @@ The following data types exist in lowered form: * `SSAValue` - Refers to a consecutively-numbered (starting at 0) static single assignment (SSA) variable inserted - by the compiler. + Refers to a consecutively-numbered (starting at 1) static single assignment (SSA) variable inserted + by the compiler. The number (`id`) of an `SSAValue` is the code array index of the expression whose + value it represents. * `NewvarNode` - Marks a point where a variable is created. This has the effect of resetting a variable to undefined. + Marks a point where a variable (slot) is created. This has the effect of resetting a variable to undefined. ### Expr types @@ -84,11 +80,11 @@ These symbols appear in the `head` field of `Expr`s in lowered form. * `gotoifnot` - Conditional branch. If `args[1]` is false, goes to label identified in `args[2]`. + Conditional branch. If `args[1]` is false, goes to the index identified in `args[2]`. * `=` - Assignment. + Assignment. In the IR, the first argument is always a Slot or a GlobalRef. * `method` @@ -181,16 +177,6 @@ These symbols appear in the `head` field of `Expr`s in lowered form. * `:inline` and `:noinline`: Inlining hints. - * `:push_loc`: enters a sequence of statements from a specified source location. - - * `args[2]` specifies a filename, as a symbol. - * `args[3]` optionally specifies the name of an (inlined) function that originally contained the - code. - - * `:pop_loc`: returns to the source location before the matching `:push_loc`. - - * `args[2]::Int` (optional) specifies the number of `push_loc` to pop - ### Method @@ -312,6 +298,15 @@ A temporary container for holding lowered source code. If an `Int`, it gives the number of compiler-inserted temporary locations in the function. If an array, specifies a type for each location. + * `linetable` + + An array of source location objects + + * `codelocs` + + An array of integer indices into the `linetable`, giving the location associated + with each statement. + Boolean properties: * `inferred` diff --git a/src/devdocs/reflection.md b/src/devdocs/reflection.md index f8af9b6..b4abeb4 100644 --- a/src/devdocs/reflection.md +++ b/src/devdocs/reflection.md @@ -90,23 +90,17 @@ The functions `Base.Meta.show_sexpr` and [`dump`](@ref) are used to display S-ex and depth-nested detail views for any expression. Finally, the [`Meta.lower`](@ref) function gives the `lowered` form of any expression and is of -particular interest for understanding both macros and top-level statements such as function declarations -and variable assignments: +particular interest for understanding how language constructs map to primitive operations such +as assignments, branches, and calls: ```jldoctest -julia> Meta.lower(@__MODULE__, :(f() = 1) ) -:($(Expr(:thunk, CodeInfo(:(begin - $(Expr(:method, :f)) - Core.SSAValue(0) = (Core.Typeof)(f) - Core.SSAValue(1) = (Core.svec)(Core.SSAValue(0)) - Core.SSAValue(2) = (Core.svec)() - Core.SSAValue(3) = (Core.svec)(Core.SSAValue(1), Core.SSAValue(2)) - $(Expr(:method, :f, Core.SSAValue(3), CodeInfo(:(begin - #= none:1 =# - return 1 - end)))) - return f - end))))) +julia> Meta.lower(@__MODULE__, :([1+2, sin(0.5)]) ) +:($(Expr(:thunk, CodeInfo( + 1 ─ %1 = :+(1, 2)::Any + │ %2 = :sin(0.5)::Any + │ %3 = Base.vect(%1, %2)::Any + └── return %3 +)))) ``` ## Intermediate and compiled representations diff --git a/src/manual/arrays.md b/src/manual/arrays.md index 2ff682a..8acb2a0 100644 --- a/src/manual/arrays.md +++ b/src/manual/arrays.md @@ -21,11 +21,11 @@ sharing](https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing) while this prevents accidental modification by callees of a value in the caller, it makes avoiding unwanted copying of arrays difficult. By convention, a function name ending with a `!` indicates that it will mutate or destroy the -value of one or more of its arguments. Callees must make explicit copies to -ensure that they don't modify inputs that they don't intend to change. Many non- -mutating functions are implemented by calling a function of the same name with -an added `!` at the end on an explicit copy of the input, and returning that -copy. +value of one or more of its arguments (see, for example, [`sort`](@ref) and [`sort!`](@ref). +Callees must make explicit copies to ensure that they don't modify inputs that +they don't intend to change. Many non- mutating functions are implemented by +calling a function of the same name with an added `!` at the end on an explicit +copy of the input, and returning that copy. ## [배열](@id Arrays) @@ -73,6 +73,25 @@ copy. `[A, B, C, ...]` 문법은 주어진 인수들의 일차원 배열(벡터)을 생성한다. 만약 모든 인수가 공통의 [확장 타입(promotion type)](@ref conversion-and-promotion)을 가진다면, 이들은 [`convert`](@ref)를 통해 공통의 확장 타입으로 변환된다. +To see the various ways we can pass dimensions to these constructors, consider the following examples: +```jldoctest +julia> zeros(Int8, 2, 2) +2×2 Array{Int8,2}: + 0 0 + 0 0 + +julia> zeros(Int8, (2, 2)) +2×2 Array{Int8,2}: + 0 0 + 0 0 + +julia> zeros((2, 2)) +2×2 Array{Float64,2}: + 0.0 0.0 + 0.0 0.0 +``` +Here, `(2, 2)` is a [`Tuple`](@ref). + ### 병합(Concatenation) 배열은 다음의 함수를 사용하여 생성하고 병합할 수 있다. @@ -83,7 +102,18 @@ copy. | [`vcat(A...)`](@ref) | `cat(A...; dims=1)`의 줄임 | | [`hcat(A...)`](@ref) | `cat(A...; dims=2)`의 줄임 | -스칼라 값이 인수로 전달되면 원소 갯수가 하나인 배열로 취급한다. +스칼라 값이 인수로 전달되면 원소 갯수가 하나인 배열로 취급한다. 예를 들어, +```jldoctest +julia> vcat([1, 2], 3) +3-element Array{Int64,1}: + 1 + 2 + 3 + +julia> hcat([1 2], 3) +1×3 Array{Int64,2}: + 1 2 3 +``` 병합 함수는 자주 사용되므로 다음의 특별한 문법을 가진다: @@ -94,6 +124,24 @@ copy. | `[A B; C D; ...]` | [`hvcat`](@ref) | [`hvcat`](@ref) 은 1차원 (세미콜론으로 구분) 과 2차원(스페이스로 구분) 모두 병합한다. +Consider these examples of this syntax: +```jldoctest +julia> [[1; 2]; [3, 4]] +4-element Array{Int64,1}: + 1 + 2 + 3 + 4 + +julia> [[1 2] [3 4]] +1×4 Array{Int64,2}: + 1 2 3 4 + +julia> [[1 2]; [3 4]] +2×2 Array{Int64,2}: + 1 2 + 3 4 +``` ### 타입이 있는 배열의 초기화 @@ -393,7 +441,51 @@ julia> x * `CartesianIndex{N}`의 배열 (자세한 내용은 아래를 참조). 3. 스칼라 인덱스의 배열을 나타내는 객체이면서 [`to_indices`](@ref)를 통해 스칼라 인덱스의 배열로 변환될 수 있는 것. 기본으로 다음을 포함한다: * [`Colon()`](@ref) (`:`). 차원 혹은 배열의 모든 원소를 선택한다. - * 부울 배열. `true` 인덱스에 있는 원소를 선택한다. + * 부울 배열. `true` 인덱스에 있는 원소를 선택한다 (자세한 내용은 아래를 참조) + +Some examples: +```jldoctest +julia> A = reshape(collect(1:2:18), (3, 3)) +3×3 Array{Int64,2}: + 1 7 13 + 3 9 15 + 5 11 17 + +julia> A[4] +7 + +julia> A[[2, 5, 8]] +3-element Array{Int64,1}: + 3 + 9 + 15 + +julia> A[[1 4; 3 8]] +2×2 Array{Int64,2}: + 1 7 + 5 15 + +julia> A[[]] +0-element Array{Int64,1} + +julia> A[1:2:5] +3-element Array{Int64,1}: + 1 + 5 + 9 + +julia> A[2, :] +3-element Array{Int64,1}: + 3 + 9 + 15 + +julia> A[:, 3] +3-element Array{Int64,1}: + 13 + 15 + 17 +``` #### 직교 인덱스(Cartesian indices) diff --git a/src/manual/mathematical-operations.md b/src/manual/mathematical-operations.md index 1e8ccca..aae4ce1 100644 --- a/src/manual/mathematical-operations.md +++ b/src/manual/mathematical-operations.md @@ -528,12 +528,11 @@ sin cos tan cot sec csc sinh cosh tanh coth sech csch asin acos atan acot asec acsc asinh acosh atanh acoth asech acsch -sinc cosc atan2 +sinc cosc ``` -These are all single-argument functions, with the exception of [atan2](https://en.wikipedia.org/wiki/Atan2), -which gives the angle in [radians](https://en.wikipedia.org/wiki/Radian) between the *x*-axis -and the point specified by its arguments, interpreted as *x* and *y* coordinates. +These are all single-argument functions, with [`atan`](@ref) also accepting two arguments +corresponding to a traditional [`atan2`](https://en.wikipedia.org/wiki/Atan2) function. Additionally, [`sinpi(x)`](@ref) and [`cospi(x)`](@ref) are provided for more accurate computations of [`sin(pi*x)`](@ref) and [`cos(pi*x)`](@ref) respectively. diff --git a/src/manual/performance-tips.md b/src/manual/performance-tips.md index 1ecac2d..a0c2d0b 100644 --- a/src/manual/performance-tips.md +++ b/src/manual/performance-tips.md @@ -21,16 +21,23 @@ const DEFAULT_VAL = 0 Uses of non-constant globals can be optimized by annotating their types at the point of use: ```julia -global x -y = f(x::Int + 1) +global x = rand(1000) + +function loop_over_global() + s = 0.0 + for i in x::Vector{Float64} + s += i + end + return s +end ``` -Writing functions is better style. It leads to more reusable code and clarifies what steps are -being done, and what their inputs and outputs are. +Passing arguments to functions is better style. It leads to more reusable code and clarifies what the inputs and outputs are. !!! note All code in the REPL is evaluated in global scope, so a variable defined and assigned - at toplevel will be a **global** variable. + at toplevel will be a **global** variable. Variables defined in at top level scope inside + modules are also global. In the following REPL session: @@ -48,79 +55,101 @@ so all the performance issues discussed previously apply. ## Measure performance with [`@time`](@ref) and pay attention to memory allocation -A useful tool for measuring performance is the [`@time`](@ref) macro. The following example -illustrates good working style: +A useful tool for measuring performance is the [`@time`](@ref) macro. We here repeat the example +with the global variable above, but this time with the type annotation removed: -```julia-repl -julia> function f(n) - s = 0 - for i = 1:n - s += i/2 +```jldoctest; setup = :(using Random; srand(1234)), filter = r"[0-9\.]+ seconds \(.*?\)" +julia> x = rand(1000); + +julia> function sum_global() + s = 0.0 + for i in x + s += i end - s - end -f (generic function with 1 method) + return s + end; -julia> @time f(1) - 0.012686 seconds (2.09 k allocations: 103.421 KiB) -0.5 +julia> @time sum_global() + 0.017705 seconds (15.28 k allocations: 694.484 KiB) +496.84883432553846 -julia> @time f(10^6) - 0.021061 seconds (3.00 M allocations: 45.777 MiB, 11.69% gc time) -2.5000025e11 +julia> @time sum_global() + 0.000140 seconds (3.49 k allocations: 70.313 KiB) +496.84883432553846 ``` -On the first call (`@time f(1)`), `f` gets compiled. (If you've not yet used [`@time`](@ref) +On the first call (`@time sum_global()`) the function gets compiled. (If you've not yet used [`@time`](@ref) in this session, it will also compile functions needed for timing.) You should not take the results of this run seriously. For the second run, note that in addition to reporting the time, it also -indicated that a large amount of memory was allocated. +indicated that a significant amount of memory was allocated. We are here just computing a sum over all elements in +a vector of 64-bit floats so there should be no need to allocate memory (at least not on the heap which is what `@time` reports). Unexpected memory allocation is almost always a sign of some problem with your code, usually a -problem with type-stability. Consequently, in addition to the allocation itself, it's very likely +problem with type-stability or creating many small temporary arrays. +Consequently, in addition to the allocation itself, it's very likely that the code generated for your function is far from optimal. Take such indications seriously and follow the advice below. -For more serious benchmarking, consider the [BenchmarkTools.jl](https://github.com/JuliaCI/BenchmarkTools.jl) -package which evaluates the function multiple times in order to reduce noise. - -As a teaser, an improved version of this function allocates no memory +If we instead pass `x` as an argument to the function it no longer allocates memory (the allocation reported below is due to running the `@time` macro in global scope) -and has an order of magnitude faster execution after the first call: +and is significantly faster after the first call: -```julia-repl -julia> @time f_improved(1) - 0.007008 seconds (1.32 k allocations: 63.640 KiB) -0.5 +```jldoctest sumarg; setup = :(using Random; srand(1234)), filter = r"[0-9\.]+ seconds \(.*?\)" +julia> x = rand(1000); -julia> @time f_improved(10^6) - 0.002997 seconds (6 allocations: 192 bytes) -2.5000025e11 +julia> function sum_arg(x) + s = 0.0 + for i in x + s += i + end + return s + end; + +julia> @time sum_arg(x) + 0.007701 seconds (821 allocations: 43.059 KiB) +496.84883432553846 + +julia> @time sum_arg(x) + 0.000006 seconds (5 allocations: 176 bytes) +496.84883432553846 ``` -Below you'll learn how to spot the problem with `f` and how to fix it. +The 5 allocations seen are from running the `@time` macro itself in global scope. If we instead run +the timing in a function, we can see that indeed no allocations are performed: + +```jldoctest sumarg; filter = r"[0-9\.]+ seconds" +julia> time_sum(x) = @time sum_arg(x); + +julia> time_sum(x) + 0.000001 seconds +496.84883432553846 +``` In some situations, your function may need to allocate memory as part of its operation, and this can complicate the simple picture above. In such cases, consider using one of the [tools](@ref tools) below to diagnose problems, or write a version of your function that separates allocation from its algorithmic aspects (see [Pre-allocating outputs](@ref)). +!!! note + For more serious benchmarking, consider the [BenchmarkTools.jl](https://github.com/JuliaCI/BenchmarkTools.jl) + package which among other things evaluates the function multiple times in order to reduce noise. + ## [Tools](@id tools) Julia and its package ecosystem includes tools that may help you diagnose problems and improve the performance of your code: * [Profiling](@ref) allows you to measure the performance of your running code and identify lines - that serve as bottlenecks. For complex projects, the [ProfileView](https://github.com/timholy/ProfileView.jl) + that serve as bottlenecks. For complex projects, the [ProfileView](https://github.com/timholy/ProfileView.jl) package can help you visualize your profiling results. + * The [Traceur](https://github.com/MikeInnes/Traceur.jl) package can help you find common performance problems in your code. * Unexpectedly-large memory allocations--as reported by [`@time`](@ref), [`@allocated`](@ref), or the profiler (through calls to the garbage-collection routines)--hint that there might be issues - with your code. If you don't see another reason for the allocations, suspect a type problem. + with your code. If you don't see another reason for the allocations, suspect a type problem. You can also start Julia with the `--track-allocation=user` option and examine the resulting - `*.mem` files to see information about where those allocations occur. See [Memory allocation analysis](@ref). + `*.mem` files to see information about where those allocations occur. See [Memory allocation analysis](@ref). * `@code_warntype` generates a representation of your code that can be helpful in finding expressions that result in type uncertainty. See [`@code_warntype`](@ref) below. - * The [Lint](https://github.com/tonyhffong/Lint.jl) - package can also warn you of certain types of programming errors. ## Avoid containers with abstract type parameters @@ -129,23 +158,36 @@ abstract types where possible. Consider the following: -```julia -a = Real[] # typeof(a) = Array{Real,1} -if (f = rand()) < .8 - push!(a, f) -end +```jldoctest +julia> a = Real[] +0-element Array{Real,1} + +julia> push!(a, 1); push!(a, 2.0); push!(a, π) +3-element Array{Real,1}: + 1 + 2.0 + π = 3.1415926535897... ``` Because `a` is a an array of abstract type [`Real`](@ref), it must be able to hold any -`Real` value. Since `Real` objects can be of arbitrary size and structure, `a` must be -represented as an array of pointers to individually allocated `Real` objects. Because `f` -will always be a [`Float64`](@ref), we should instead, use: +`Real` value. Since `Real` objects can be of arbitrary size and structure, `a` must be +represented as an array of pointers to individually allocated `Real` objects. However, if we instead +only allow numbers of the same type, e.g. [`Float64`](@ref), to be stored in `a` these can be stored more +efficiently: -```julia -a = Float64[] # typeof(a) = Array{Float64,1} +```jldoctest +julia> a = Float64[] +0-element Array{Float64,1} + +julia> push!(a, 1); push!(a, 2.0); push!(a, π) +3-element Array{Float64,1}: + 1.0 + 2.0 + 3.141592653589793 ``` -which will create a contiguous block of 64-bit floating-point values that can be manipulated efficiently. +Assigning numbers into `a` will now convert them to `Float64` and `a` will be stored as +a contiguous block of 64-bit floating-point values that can be manipulated efficiently. See also the discussion under [Parametric Types](@ref). @@ -168,7 +210,7 @@ julia> struct MyAmbiguousType This allows `a` to be of any type. This can often be useful, but it does have a downside: for objects of type `MyAmbiguousType`, the compiler will not be able to generate high-performance -code. The reason is that the compiler uses the types of objects, not their values, to determine +code. The reason is that the compiler uses the types of objects, not their values, to determine how to build code. Unfortunately, very little can be inferred about an object of type `MyAmbiguousType`: ```jldoctest myambig @@ -185,7 +227,7 @@ julia> typeof(c) MyAmbiguousType ``` -`b` and `c` have the same type, yet their underlying representation of data in memory is very +The values of `b` and `c` have the same type, yet their underlying representation of data in memory is very different. Even if you stored just numeric values in field `a`, the fact that the memory representation of a [`UInt8`](@ref) differs from a [`Float64`](@ref) also means that the CPU needs to handle them using two different kinds of instructions. Since the required information is not available @@ -208,7 +250,7 @@ julia> mutable struct MyStillAmbiguousType end ``` -because the first version specifies the type of `a` from the type of the wrapper object. For +because the first version specifies the type of `a` from the type of the wrapper object. For example: ```jldoctest myambig2 @@ -226,7 +268,7 @@ MyStillAmbiguousType ``` The type of field `a` can be readily determined from the type of `m`, but not from the type of -`t`. Indeed, in `t` it's possible to change the type of field `a`: +`t`. Indeed, in `t` it's possible to change the type of the field `a`: ```jldoctest myambig2 julia> typeof(t.a) @@ -249,11 +291,11 @@ julia> typeof(m.a) Float64 ``` -The fact that the type of `m.a` is known from `m`'s type--coupled with the fact that its type -cannot change mid-function--allows the compiler to generate highly-optimized code for objects +The fact that the type of `m.a` is known from `m`'s type—coupled with the fact that its type +cannot change mid-function—allows the compiler to generate highly-optimized code for objects like `m` but not for objects like `t`. -Of course, all of this is true only if we construct `m` with a concrete type. We can break this +Of course, all of this is true only if we construct `m` with a concrete type. We can break this by explicitly constructing it with an abstract type: ```jldoctest myambig2 @@ -281,9 +323,8 @@ func(m::MyType) = m.a+1 using ```julia -code_llvm(func,Tuple{MyType{Float64}}) -code_llvm(func,Tuple{MyType{AbstractFloat}}) -code_llvm(func,Tuple{MyType}) +code_llvm(func, Tuple{MyType{Float64}}) +code_llvm(func, Tuple{MyType{AbstractFloat}}) ``` For reasons of length the results are not shown here, but you may wish to try this yourself. Because @@ -295,11 +336,11 @@ to resolve the type at run-time. This results in shorter and faster code. The same best practices also work for container types: ```jldoctest containers -julia> mutable struct MySimpleContainer{A<:AbstractVector} +julia> struct MySimpleContainer{A<:AbstractVector} a::A end -julia> mutable struct MyAmbiguousContainer{T} +julia> struct MyAmbiguousContainer{T} a::AbstractVector{T} end ``` @@ -332,10 +373,10 @@ For `MySimpleContainer`, the object is fully-specified by its type and parameter can generate optimized functions. In most instances, this will probably suffice. While the compiler can now do its job perfectly well, there are cases where *you* might wish that -your code could do different things depending on the *element type* of `a`. Usually the best +your code could do different things depending on the *element type* of `a`. Usually the best way to achieve this is to wrap your specific operation (here, `foo`) in a separate function: -```julia jldoctest containers +```jldoctest containers julia> function sumfoo(c::MySimpleContainer) s = 0 for x in c.a @@ -355,109 +396,37 @@ foo (generic function with 2 methods) This keeps things simple, while allowing the compiler to generate optimized code in all cases. However, there are cases where you may need to declare different versions of the outer function -for different element types of `a`. You could do it like this: +for different element types or types of the `AbstractVector` of the field `a` in `MySimpleContainer`. +You could do it like this: -``` -function myfun(c::MySimpleContainer{Vector{T}}) where T<:AbstractFloat - ... -end -function myfun(c::MySimpleContainer{Vector{T}}) where T<:Integer - ... -end -``` - -This works fine for `Vector{T}`, but we'd also have to write explicit versions for `UnitRange{T}` -or other abstract types. To prevent such tedium, you can use two parameters in the declaration -of `MyContainer`: - -```jldoctest containers2 -julia> mutable struct MyContainer{T, A<:AbstractVector} - a::A - end - -julia> MyContainer(v::AbstractVector) = MyContainer{eltype(v), typeof(v)}(v) -MyContainer - -julia> b = MyContainer(1:5); - -julia> typeof(b) -MyContainer{Int64,UnitRange{Int64}} -``` - -Note the somewhat surprising fact that `T` doesn't appear in the declaration of field `a`, a point -that we'll return to in a moment. With this approach, one can write functions such as: - -```jldoctest containers2 -julia> function myfunc(c::MyContainer{<:Integer, <:AbstractArray}) +```jldoctest containers +julia> function myfunc(c::MySimpleContainer{<:AbstractArray{<:Integer}}) return c.a[1]+1 end myfunc (generic function with 1 method) -julia> function myfunc(c::MyContainer{<:AbstractFloat}) +julia> function myfunc(c::MySimpleContainer{<:AbstractArray{<:AbstractFloat}}) return c.a[1]+2 end myfunc (generic function with 2 methods) -julia> function myfunc(c::MyContainer{T,Vector{T}}) where T<:Integer +julia> function myfunc(c::MySimpleContainer{Vector{T}}) where T <: Integer return c.a[1]+3 end myfunc (generic function with 3 methods) ``` -!!! note - Because we can only define `MyContainer` for - `A<:AbstractArray`, and any unspecified parameters are arbitrary, - the first function above could have been written more succinctly as - `function myfunc(c::MyContainer{<:Integer})` - - -```jldoctest containers2 -julia> myfunc(MyContainer(1:3)) +```jldoctest containers +julia> myfunc(MySimpleContainer(1:3)) 2 -julia> myfunc(MyContainer(1.0:3)) +julia> myfunc(MySimpleContainer(1.0:3)) 3.0 -julia> myfunc(MyContainer([1:3;])) +julia> myfunc(MySimpleContainer([1:3;])) 4 ``` -As you can see, with this approach it's possible to specialize on both the element type `T` and -the array type `A`. - -However, there's one remaining hole: we haven't enforced that `A` has element type `T`, so it's -perfectly possible to construct an object like this: - -```jldoctest containers2 -julia> b = MyContainer{Int64, UnitRange{Float64}}(UnitRange(1.3, 5.0)); - -julia> typeof(b) -MyContainer{Int64,UnitRange{Float64}} -``` - -To prevent this, we can add an inner constructor: - -```jldoctest containers3 -julia> mutable struct MyBetterContainer{T<:Real, A<:AbstractVector} - a::A - MyBetterContainer{T,A}(v::AbstractVector{T}) where {T,A} = new(v) - end - -julia> MyBetterContainer(v::AbstractVector) = MyBetterContainer{eltype(v),typeof(v)}(v) -MyBetterContainer - -julia> b = MyBetterContainer(UnitRange(1.3, 5.0)); - -julia> typeof(b) -MyBetterContainer{Float64,UnitRange{Float64}} - -julia> b = MyBetterContainer{Int64, UnitRange{Float64}}(UnitRange(1.3, 5.0)); -ERROR: MethodError: Cannot `convert` an object of type UnitRange{Float64} to an object of type MyBetterContainer{Int64,UnitRange{Float64}} -[...] -``` - -The inner constructor requires that the element type of `A` be `T`. - ### Annotate values taken from untyped locations It is often convenient to work with data structures that may contain values of any type (arrays @@ -477,7 +446,7 @@ an annotation like this has the added benefit that it will raise a run-time erro value is not of the expected type, potentially catching certain bugs earlier. In the case that the type of `a[1]` is not known precisely, `x` can be declared via -`x = convert(Int32,a[1])::Int32`. The use of the [`convert`](@ref) function allows `a[1]` +`x = convert(Int32, a[1])::Int32`. The use of the [`convert`](@ref) function allows `a[1]` to be any object convertible to an `Int32` (such as `UInt8`), thus increasing the genericity of the code by loosening the type requirement. Notice that `convert` itself needs a type annotation in this context in order to achieve type stability. This is because the compiler @@ -540,13 +509,15 @@ code, or even inline it. Here is an example of a "compound function" that should really be written as multiple definitions: ```julia -function norm(A) +using LinearAlgebra + +function mynorm(A) if isa(A, Vector) return sqrt(real(dot(A,A))) elseif isa(A, Matrix) return maximum(svdvals(A)) else - error("norm: invalid argument") + error("mynorm: invalid argument") end end ``` @@ -554,10 +525,13 @@ end This can be written more concisely and efficiently as: ```julia -norm(x::Vector) = sqrt(real(dot(x,x))) +norm(x::Vector) = sqrt(real(dot(x, x))) norm(A::Matrix) = maximum(svdvals(A)) ``` +It should however be noted that the compiler is quite efficient at optimizing away the dead branches in code +written as the `mynorm` example. + ## Write "type-stable" functions When possible, it helps to ensure that a function always returns a value of the same type. Consider @@ -576,7 +550,7 @@ easily be fixed as follows: pos(x) = x < 0 ? zero(x) : x ``` -There is also a [`one`](@ref) function, and a more general [`oftype(x, y)`](@ref) function, which +There is also a [`oneunit`](@ref) function, and a more general [`oftype(x, y)`](@ref) function, which returns `y` converted to the type of `x`. ## Avoid changing the type of a variable @@ -587,7 +561,7 @@ An analogous "type-stability" problem exists for variables used repeatedly withi function foo() x = 1 for i = 1:10 - x = x/bar() + x /= rand() end return x end @@ -599,8 +573,8 @@ optimize the body of the loop. There are several possible fixes: * Initialize `x` with `x = 1.0` * Declare the type of `x`: `x::Float64 = 1` - * Use an explicit conversion: `x = oneunit(T)` - * Initialize with the first loop iteration, to `x = 1/bar()`, then loop `for i = 2:10` + * Use an explicit conversion: `x = oneunit(Float64)` + * Initialize with the first loop iteration, to `x = 1 / rand()`, then loop `for i = 2:10` ## [Separate kernel functions (aka, function barriers)](@id kernal-functions) @@ -609,22 +583,14 @@ to perform a core computation. Where possible, it is a good idea to put these co in separate functions. For example, the following contrived function returns an array of a randomly-chosen type: -```@meta -DocTestSetup = quote - import Random - Random.srand(1234) -end -``` - -```jldoctest +```jldoctest; setup = :(using Random; srand(1234)) julia> function strange_twos(n) a = Vector{rand(Bool) ? Int64 : Float64}(undef, n) for i = 1:n a[i] = 2 end return a - end -strange_twos (generic function with 1 method) + end; julia> strange_twos(3) 3-element Array{Float64,1}: @@ -635,20 +601,18 @@ julia> strange_twos(3) This should be written as: -```jldoctest +```jldoctest; setup = :(using Random; srand(1234)) julia> function fill_twos!(a) for i = eachindex(a) a[i] = 2 end - end -fill_twos! (generic function with 1 method) + end; julia> function strange_twos(n) a = Vector{rand(Bool) ? Int64 : Float64}(undef, n) fill_twos!(a) return a - end -strange_twos (generic function with 1 method) + end; julia> strange_twos(3) 3-element Array{Float64,1}: @@ -664,9 +628,9 @@ of `fill_twos!` for different types of `a`. The second form is also often better style and can lead to more code reuse. -This pattern is used in several places in Julia Base. For example, see `hvcat_fill` -in [`abstractarray.jl`](https://github.com/JuliaLang/julia/blob/master/base/abstractarray.jl), or -the [`fill!`](@ref) function, which we could have used instead of writing our own `fill_twos!`. +This pattern is used in several places in Julia Base. For example, see `vcat` and `hcat` +in [`abstractarray.jl`](https://github.com/JuliaLang/julia/blob/40fe264f4ffaa29b749bcf42239a89abdcbba846/base/abstractarray.jl#L1205-L1206), +or the [`fill!`](@ref) function, which we could have used instead of writing our own `fill_twos!`. Functions like `strange_twos` occur when dealing with data of uncertain type, for example data loaded from an input file that might contain either integers, floats, strings, or something else. @@ -712,7 +676,7 @@ function has to be conservative, checking the type on each access of `A`; such c slow. Now, one very good way to solve such problems is by using the [function-barrier technique](@ref kernal-functions). -However, in some cases you might want to eliminate the type-instability altogether. In such cases, +However, in some cases you might want to eliminate the type-instability altogether. In such cases, one approach is to pass the dimensionality as a parameter, for example through `Val{T}()` (see ["Value types"](@ref)): @@ -743,8 +707,8 @@ end ``` Here, you've created the same problem all over again: the compiler can't guess what `n` is, -so it doesn't know the *type* of `Val(n)`. Attempting to use `Val`, but doing so incorrectly, can -easily make performance *worse* in many situations. (Only in situations where you're effectively +so it doesn't know the *type* of `Val(n)`. Attempting to use `Val`, but doing so incorrectly, can +easily make performance *worse* in many situations. (Only in situations where you're effectively combining `Val` with the function-barrier trick, to make the kernel function more efficient, should code like the above be used.) @@ -757,7 +721,7 @@ function filter3(A::AbstractArray{T,N}) where {T,N} end ``` -In this example, `N` is passed as a parameter, so its "value" is known to the compiler. Essentially, +In this example, `N` is passed as a parameter, so its "value" is known to the compiler. Essentially, `Val(T)` works only when `T` is either hard-coded/literal (`Val(3)`) or already specified in the type-domain. @@ -768,7 +732,7 @@ and try to use it for everything. For example, you might imagine using it to sto e.g. ``` -struct Car{Make,Model} +struct Car{Make, Model} year::Int ...more fields... end @@ -776,10 +740,11 @@ end and then dispatch on objects like `Car{:Honda,:Accord}(year, args...)`. -This might be worthwhile when the following are true: +This might be worthwhile when either of the following are true: * You require CPU-intensive processing on each `Car`, and it becomes vastly more efficient if you - know the `Make` and `Model` at compile time. + know the `Make` and `Model` at compile time and the total number of different `Make` or `Model` + that will be used is not too large. * You have homogenous lists of the same type of `Car` to process, so that you can store them all in an `Array{Car{:Honda,:Accord},N}`. @@ -789,7 +754,7 @@ type), so Julia can "look up" the correct method calls when the function is bein the need to check at run-time) and thereby emit efficient code for processing the whole list. When these do not hold, then it's likely that you'll get no benefit; worse, the resulting "combinatorial -explosion of types" will be counterproductive. If `items[i+1]` has a different type than `item[i]`, +explosion of types" will be counterproductive. If `items[i+1]` has a different type than `item[i]`, Julia has to look up the type at run-time, search for the appropriate method in method tables, decide (via type intersection) which one matches, determine whether it has been JIT-compiled yet (and do so if not), and then make the call. In essence, you're asking the full type- system and @@ -803,8 +768,8 @@ Perhaps even worse than the run-time impact is the compile-time impact: Julia wi functions for each different `Car{Make, Model}`; if you have hundreds or thousands of such types, then every function that accepts such an object as a parameter (from a custom `get_year` function you might write yourself, to the generic `push!` function in Julia Base) will have hundreds -or thousands of variants compiled for it. Each of these increases the size of the cache of compiled -code, the length of internal lists of methods, etc. Excess enthusiasm for values-as-parameters +or thousands of variants compiled for it. Each of these increases the size of the cache of compiled +code, the length of internal lists of methods, etc. Excess enthusiasm for values-as-parameters can easily waste enormous resources. ## Access arrays in memory order, along columns @@ -847,7 +812,7 @@ function copy_cols(x::Vector{T}) where T for i = inds out[:, i] = x end - out + return out end function copy_rows(x::Vector{T}) where T @@ -856,7 +821,7 @@ function copy_rows(x::Vector{T}) where T for i = inds out[i, :] = x end - out + return out end function copy_col_row(x::Vector{T}) where T @@ -865,7 +830,7 @@ function copy_col_row(x::Vector{T}) where T for col = inds, row = inds out[row, col] = x[row] end - out + return out end function copy_row_col(x::Vector{T}) where T @@ -874,7 +839,7 @@ function copy_row_col(x::Vector{T}) where T for row = inds, col = inds out[row, col] = x[col] end - out + return out end ``` @@ -900,50 +865,50 @@ first element to appear in a slice expression should be coupled with the inner-m ## Pre-allocating outputs If your function returns an `Array` or some other complex type, it may have to allocate memory. - Unfortunately, oftentimes allocation and its converse, garbage collection, are substantial bottlenecks. +Unfortunately, oftentimes allocation and its converse, garbage collection, are substantial bottlenecks. Sometimes you can circumvent the need to allocate memory on each function call by preallocating -the output. As a trivial example, compare - -```julia -function xinc(x) - return [x, x+1, x+2] -end - -function loopinc() - y = 0 - for i = 1:10^7 - ret = xinc(i) - y += ret[2] - end - y -end +the output. As a trivial example, compare + +```jldoctest prealloc +julia> function xinc(x) + return [x, x+1, x+2] + end; + +julia> function loopinc() + y = 0 + for i = 1:10^7 + ret = xinc(i) + y += ret[2] + end + return y + end; ``` with -```julia -function xinc!(ret::AbstractVector{T}, x::T) where T - ret[1] = x - ret[2] = x+1 - ret[3] = x+2 - nothing -end - -function loopinc_prealloc() - ret = Vector{Int}(undef, 3) - y = 0 - for i = 1:10^7 - xinc!(ret, i) - y += ret[2] - end - y -end +```jldoctest prealloc +julia> function xinc!(ret::AbstractVector{T}, x::T) where T + ret[1] = x + ret[2] = x+1 + ret[3] = x+2 + nothing + end; + +julia> function loopinc_prealloc() + ret = Vector{Int}(undef, 3) + y = 0 + for i = 1:10^7 + xinc!(ret, i) + y += ret[2] + end + return y + end; ``` Timing results: -```julia-repl +```jldoctest prealloc; filter = r"[0-9\.]+ seconds \(.*?\)" julia> @time loopinc() 0.529894 seconds (40.00 M allocations: 1.490 GiB, 12.14% gc time) 50000015000000 @@ -954,7 +919,7 @@ julia> @time loopinc_prealloc() ``` Preallocation has other advantages, for example by allowing the caller to control the "output" -type from an algorithm. In the example above, we could have passed a `SubArray` rather than an +type from an algorithm. In the example above, we could have passed a `SubArray` rather than an [`Array`](@ref), had we so desired. Taken to its extreme, pre-allocation can make your code uglier, so performance measurements and @@ -978,30 +943,30 @@ to instead use `vector .+ vector` and `vector .* scalar` because the resulting loops can be fused with surrounding computations. For example, consider the two functions: -```julia -f(x) = 3x.^2 + 4x + 7x.^3 +```jldoctest dotfuse +julia> f(x) = 3x.^2 + 4x + 7x.^3; -fdot(x) = @. 3x^2 + 4x + 7x^3 # equivalent to 3 .* x.^2 .+ 4 .* x .+ 7 .* x.^3 +julia> fdot(x) = @. 3x^2 + 4x + 7x^3 # equivalent to 3 .* x.^2 .+ 4 .* x .+ 7 .* x.^3; ``` -Both `f` and `fdot` compute the same thing. However, `fdot` +Both `f` and `fdot` compute the same thing. However, `fdot` (defined with the help of the [`@.`](@ref @__dot__) macro) is significantly faster when applied to an array: -```julia-repl +```jldoctest dotfuse; filter = r"[0-9\.]+ seconds \(.*?\)" julia> x = rand(10^6); julia> @time f(x); - 0.010986 seconds (18 allocations: 53.406 MiB, 11.45% gc time) + 0.019049 seconds (16 allocations: 45.777 MiB, 18.59% gc time) julia> @time fdot(x); - 0.003470 seconds (6 allocations: 7.630 MiB) + 0.002790 seconds (6 allocations: 7.630 MiB) julia> @time f.(x); - 0.003297 seconds (30 allocations: 7.631 MiB) + 0.002626 seconds (8 allocations: 7.630 MiB) ``` -That is, `fdot(x)` is three times faster and allocates 1/7 the +That is, `fdot(x)` is ten times faster and allocates 1/6 the memory of `f(x)`, because each `*` and `+` operation in `f(x)` allocates a new temporary array and executes in a separate loop. (Of course, if you just do `f.(x)` then it is as fast as `fdot(x)` in this @@ -1023,16 +988,16 @@ substantial. An alternative is to create a "view" of the array, which is an array object (a `SubArray`) that actually references the data -of the original array in-place, without making a copy. (If you +of the original array in-place, without making a copy. (If you write to a view, it modifies the original array's data as well.) This can be done for individual slices by calling [`view`](@ref), or more simply for a whole expression or block of code by putting -[`@views`](@ref) in front of that expression. For example: +[`@views`](@ref) in front of that expression. For example: -```julia-repl -julia> fcopy(x) = sum(x[2:end-1]) +```jldoctest; filter = r"[0-9\.]+ seconds \(.*?\)" +julia> fcopy(x) = sum(x[2:end-1]); -julia> @views fview(x) = sum(x[2:end-1]) +julia> @views fview(x) = sum(x[2:end-1]); julia> x = rand(10^6); @@ -1056,9 +1021,11 @@ can drastically slow down computations on arrays because of non-sequential memor Copying irregularly-accessed data into a contiguous array before operating on it can result in a large speedup, such as in the example below. Here, a matrix and a vector are being accessed at 800,000 of their randomly-shuffled indices before being multiplied. Copying the views into -plain arrays speeds the multiplication by more than a factor of 2 even with the cost of the copying operation. +plain arrays speeds up the multiplication even with the cost of the copying operation. ```julia-repl +julia> using Random + julia> x = randn(1_000_000); julia> inds = shuffle(1:1_000_000)[1:800000]; @@ -1070,17 +1037,18 @@ julia> xtmp = zeros(800_000); julia> Atmp = zeros(50, 800_000); julia> @time sum(view(A, :, inds) * view(x, inds)) - 0.640320 seconds (41 allocations: 1.391 KiB) -7253.242699002263 + 0.412156 seconds (14 allocations: 960 bytes) +-4256.759568345458 julia> @time begin copyto!(xtmp, view(x, inds)) copyto!(Atmp, view(A, :, inds)) sum(Atmp * xtmp) end - 0.261294 seconds (41 allocations: 1.391 KiB) -7253.242699002323 + 0.285923 seconds (14 allocations: 960 bytes) +-4256.759568345134 ``` + Provided there is enough memory for the copies, the cost of copying the view to an array is far outweighed by the speed boost from doing the matrix multiplication on a contiguous array. @@ -1118,7 +1086,9 @@ println(file, f(a), f(b)) When executing a remote function in parallel: ```julia -responses = Vector{Any}(nworkers()) +using Distributed + +responses = Vector{Any}(undef, nworkers()) @sync begin for (idx, pid) in enumerate(workers()) @async responses[idx] = remotecall_fetch(pid, foo, args...) @@ -1129,7 +1099,9 @@ end is faster than: ```julia -refs = Vector{Any}(nworkers()) +using Distributed + +refs = Vector{Any}(undef, nworkers()) for (idx, pid) in enumerate(workers()) refs[idx] = @spawnat pid foo(args...) end @@ -1173,44 +1145,46 @@ The common idiom of using 1:n to index into an AbstractArray is not safe if the and may cause a segmentation fault if bounds checking is turned off. Use `LinearIndices(x)` or `eachindex(x)` instead (see also [offset-arrays](https://docs.julialang.org/en/latest/devdocs/offset-arrays)). -Note: While `@simd` needs to be placed directly in front of a loop, both `@inbounds` and `@fastmath` -can be applied to several statements at once, e.g. using `begin` ... `end`, or even to a whole -function. +!!!note + While `@simd` needs to be placed directly in front of a loop, both `@inbounds` and `@fastmath` + can be applied to several statements at once, e.g. using `begin` ... `end`, or even to a whole + function. -Here is an example with both `@inbounds` and `@simd` markup: +Here is an example with both `@inbounds` and `@simd` markup (we here use `@noinline` to prevent +the optimizer from trying to be too clever and defeat our benchmark): ```julia -function inner(x, y) +@noinline function inner(x, y) s = zero(eltype(x)) for i=eachindex(x) @inbounds s += x[i]*y[i] end - s + return s end -function innersimd(x, y) +@noinline function innersimd(x, y) s = zero(eltype(x)) - @simd for i=eachindex(x) - @inbounds s += x[i]*y[i] + @simd for i = eachindex(x) + @inbounds s += x[i] * y[i] end - s + return s end function timeit(n, reps) - x = rand(Float32,n) - y = rand(Float32,n) + x = rand(Float32, n) + y = rand(Float32, n) s = zero(Float64) time = @elapsed for j in 1:reps - s+=inner(x,y) + s += inner(x, y) end - println("GFlop/sec = ",2.0*n*reps/time*1E-9) + println("GFlop/sec = ", 2n*reps / time*1E-9) time = @elapsed for j in 1:reps - s+=innersimd(x,y) + s += innersimd(x, y) end - println("GFlop/sec (SIMD) = ",2.0*n*reps/time*1E-9) + println("GFlop/sec (SIMD) = ", 2n*reps / time*1E-9) end -timeit(1000,1000) +timeit(1000, 1000) ``` On a computer with a 2.4GHz Intel Core i5 processor, this produces: @@ -1270,7 +1244,7 @@ function deriv!(u::Vector, du) @fastmath @inbounds du[n] = (u[n] - u[n-1]) / dx end -function norm(u::Vector) +function mynorm(u::Vector) n = length(u) T = eltype(u) s = zero(T) @@ -1287,11 +1261,11 @@ function main() du = similar(u) deriv!(u, du) - nu = norm(du) + nu = mynorm(du) @time for i in 1:10^6 deriv!(u, du) - nu = norm(du) + nu = mynorm(du) end println(nu) @@ -1304,10 +1278,12 @@ On a computer with a 2.7 GHz Intel Core i7 processor, this produces: ``` $ julia wave.jl; -elapsed time: 1.207814709 seconds (0 bytes allocated) + 1.207814709 seconds +4.443986180758249 $ julia --math-mode=ieee wave.jl; -elapsed time: 4.487083643 seconds (0 bytes allocated) + 4.487083643 seconds +4.443986180758249 ``` Here, the option `--math-mode=ieee` disables the `@fastmath` macro, so that we can compare results. @@ -1329,6 +1305,20 @@ is much faster to evaluate. Of course, both the actual optimization that is appl as well as the resulting speedup depend very much on the hardware. You can examine the change in generated code by using Julia's [`code_native`](@ref) function. +Note that `@fastmath` also assumes that `NaN`s will not occur during the computation, which can lead to surprising behavior: + +```julia-repl +julia> f(x) = isnan(x); + +julia> f(NaN) +true + +julia> f_fast(x) = @fastmath isnan(x); + +julia> f_fast(NaN) +false +``` + ## Treat Subnormal Numbers as Zeros Subnormal numbers, formerly called [denormal numbers](https://en.wikipedia.org/wiki/Denormal_number), @@ -1366,6 +1356,19 @@ for trial=1:6 end ``` +This gives an output similar to + +``` + 0.002202 seconds (1 allocation: 4.063 KiB) + 0.001502 seconds (1 allocation: 4.063 KiB) + 0.002139 seconds (1 allocation: 4.063 KiB) + 0.001454 seconds (1 allocation: 4.063 KiB) + 0.002115 seconds (1 allocation: 4.063 KiB) + 0.001455 seconds (1 allocation: 4.063 KiB) +``` + +Note how each even iteration is significantly faster. + This example generates many subnormal numbers because the values in `a` become an exponentially decreasing curve, which slowly flattens out over time. @@ -1394,91 +1397,61 @@ a = rand(Float32,1000) * 1.f-9 The macro [`@code_warntype`](@ref) (or its function variant [`code_warntype`](@ref)) can sometimes be helpful in diagnosing type-related problems. Here's an example: -```julia -pos(x) = x < 0 ? 0 : x +```julia-repl +julia> @noinline pos(x) = x < 0 ? 0 : x; -function f(x) - y = pos(x) - sin(y*x+1) -end +julia> function f(x) + y = pos(x) + sin(y*x + 1) + end; julia> @code_warntype f(3.2) -Variables: - #self#::#f - x::Float64 - y::UNION{FLOAT64,INT64} - fy::Float64 - #temp#@_5::UNION{FLOAT64,INT64} - #temp#@_6::Core.MethodInstance - #temp#@_7::Float64 - -Body: - begin - $(Expr(:inbounds, false)) - # meta: location REPL[1] pos 1 - # meta: location float.jl < 487 - fy::Float64 = (Core.typeassert)((Base.sitofp)(Float64,0)::Float64,Float64)::Float64 - # meta: pop location - unless (Base.or_int)((Base.lt_float)(x::Float64,fy::Float64)::Bool,(Base.and_int)((Base.and_int)((Base.eq_float)(x::Float64,fy::Float64)::Bool,(Base.lt_float)(fy::Float64,9.223372036854776e18)::Bool)::Bool,(Base.slt_int)((Base.fptosi)(Int64,fy::Float64)::Int64,0)::Bool)::Bool)::Bool goto 9 - #temp#@_5::UNION{FLOAT64,INT64} = 0 - goto 11 - 9: - #temp#@_5::UNION{FLOAT64,INT64} = x::Float64 - 11: - # meta: pop location - $(Expr(:inbounds, :pop)) - y::UNION{FLOAT64,INT64} = #temp#@_5::UNION{FLOAT64,INT64} # line 3: - unless (y::UNION{FLOAT64,INT64} isa Int64)::ANY goto 19 - #temp#@_6::Core.MethodInstance = MethodInstance for *(::Int64, ::Float64) - goto 28 - 19: - unless (y::UNION{FLOAT64,INT64} isa Float64)::ANY goto 23 - #temp#@_6::Core.MethodInstance = MethodInstance for *(::Float64, ::Float64) - goto 28 - 23: - goto 25 - 25: - #temp#@_7::Float64 = (y::UNION{FLOAT64,INT64} * x::Float64)::Float64 - goto 30 - 28: - #temp#@_7::Float64 = $(Expr(:invoke, :(#temp#@_6), :(Main.*), :(y), :(x))) - 30: - return $(Expr(:invoke, MethodInstance for sin(::Float64), :(Main.sin), :((Base.add_float)(#temp#@_7,(Base.sitofp)(Float64,1)::Float64)::Float64))) - end::Float64 +Body::Float64 +2 1 ─ %1 = invoke Main.pos(%%x::Float64)::UNION{FLOAT64, INT64} +3 │ %2 = isa(%1, Float64)::Bool + └── goto 3 if not %2 + 2 ─ %4 = π (%1, Float64) + │ %5 = Base.mul_float(%4, %%x)::Float64 + └── goto 6 + 3 ─ %7 = isa(%1, Int64)::Bool + └── goto 5 if not %7 + 4 ─ %9 = π (%1, Int64) + │ %10 = Base.sitofp(Float64, %9)::Float64 + │ %11 = Base.mul_float(%10, %%x)::Float64 + └── goto 6 + 5 ─ Base.error("fatal error in type inference (type bound)") + └── unreachable + 6 ┄ %15 = φ (2 => %5, 4 => %11)::Float64 + │ %16 = Base.add_float(%15, 1.0)::Float64 + │ %17 = invoke Main.sin(%16::Float64)::Float64 + └── return %17 ``` Interpreting the output of [`@code_warntype`](@ref), like that of its cousins [`@code_lowered`](@ref), [`@code_typed`](@ref), [`@code_llvm`](@ref), and [`@code_native`](@ref), takes a little practice. -Your code is being presented in form that has been partially digested on its way to generating -compiled machine code. Most of the expressions are annotated by a type, indicated by the `::T` +Your code is being presented in form that has been heavily digested on its way to generating +compiled machine code. Most of the expressions are annotated by a type, indicated by the `::T` (where `T` might be [`Float64`](@ref), for example). The most important characteristic of [`@code_warntype`](@ref) is that non-concrete types are displayed in red; in the above example, such output is shown in -all-caps. - -The top part of the output summarizes the type information for the different variables internal -to the function. You can see that `y`, one of the variables you created, is a `Union{Int64,Float64}`, -due to the type-instability of `pos`. There is another variable, `_var4`, which you can see also -has the same type. - -The next lines represent the body of `f`. The lines starting with a number followed by a colon -(`1:`, `2:`) are labels, and represent targets for jumps (via `goto`) in your code. Looking at -the body, you can see that `pos` has been *inlined* into `f`--everything before `2:` comes from -code defined in `pos`. - -Starting at `2:`, the variable `y` is defined, and again annotated as a `Union` type. Next, we -see that the compiler created the temporary variable `_var1` to hold the result of `y*x`. Because -a [`Float64`](@ref) times *either* an [`Int64`](@ref) or `Float64` yields a `Float64`, -all type-instability ends here. The net result is that `f(x::Float64)` will not be type-unstable +uppercase. + +At the top, the inferred return type of the function is shown as `Body::Float64`. +The next lines represent the body of `f` in Julia's SSA IR form. +The numbered boxes are labels and represent targets for jumps (via `goto`) in your code. +Looking at the body, you can see that the first thing that happens is that `pos` is called and the +return value has been inferred as the `Union` type `UNION{FLOAT64, INT64}` shown in uppercase since +it is a non-concrete type. This means that we cannot know the exact return type of `pos` based on the +input types. However, the result of `y*x`is a `Float64` no matter if `y` is a `Float64` or `Int64` +The net result is that `f(x::Float64)` will not be type-unstable in its output, even if some of the intermediate computations are type-unstable. How you use this information is up to you. Obviously, it would be far and away best to fix `pos` to be type-stable: if you did so, all of the variables in `f` would be concrete, and its performance -would be optimal. However, there are circumstances where this kind of *ephemeral* type instability +would be optimal. However, there are circumstances where this kind of *ephemeral* type instability might not matter too much: for example, if `pos` is never used in isolation, the fact that `f`'s output is type-stable (for [`Float64`](@ref) inputs) will shield later code from the propagating -effects of type instability. This is particularly relevant in cases where fixing the type instability -is difficult or impossible: for example, currently it's not possible to infer the return type -of an anonymous function. In such cases, the tips above (e.g., adding type annotations and/or +effects of type instability. This is particularly relevant in cases where fixing the type instability +is difficult or impossible. In such cases, the tips above (e.g., adding type annotations and/or breaking up functions) are your best tools to contain the "damage" from type instability. Also, note that even Julia Base has functions that are type unstable. For example, the function [`findfirst`](@ref) returns the index into an array where a key is found, @@ -1488,21 +1461,20 @@ are color highlighted in yellow, instead of red. The following examples may help you interpret expressions marked as containing non-leaf types: - * Function body ending in `end::Union{T1,T2})` - + * Function body starting with `Body::UNION{T1,T2})` * Interpretation: function with unstable return type * Suggestion: make the return value type-stable, even if you have to annotate it - * `f(x::T)::Union{T1,T2}` - * Interpretation: call to a type-unstable function + * `invoke Main.g(%%x::Int64)::UNION{FLOAT64, INT64}` + * Interpretation: call to a type-unstable function `g`. * Suggestion: fix the function, or if necessary annotate the return value - * `(top(arrayref))(A::Array{Any,1},1)::Any` + * `invoke Base.getindex(%%x::Array{Any,1}, 1::Int64)::ANY` * Interpretation: accessing elements of poorly-typed arrays * Suggestion: use arrays with better-defined types, or if necessary annotate the type of individual element accesses - * `(top(getfield))(A::ArrayContainer{Float64},:data)::Array{Float64,N}` + * `Base.getfield(%%x, :(:data))::ARRAY{FLOAT64,N} WHERE N` * Interpretation: getting a field that is of non-leaf type. In this case, `ArrayContainer` had a field `data::Array{T}`. But `Array` needs the dimension `N`, too, to be a concrete type. * Suggestion: use concrete types like `Array{T,3}` or `Array{T,N}`, where `N` is now a parameter From cde3a61e85e00c15ade8fefae896df72c8b2af0e Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Fri, 8 Jun 2018 13:02:53 +0900 Subject: [PATCH 033/153] custom font --- src/assets/custom.css | 4 ++-- src/assets/font-iropke-batang.css | 13 +++++++++++++ src/assets/fonts/IropkeBatangM.eot | Bin 0 -> 857430 bytes src/assets/fonts/IropkeBatangM.ttf | Bin 0 -> 3202516 bytes src/assets/fonts/IropkeBatangM.woff | Bin 0 -> 984484 bytes 5 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 src/assets/font-iropke-batang.css create mode 100644 src/assets/fonts/IropkeBatangM.eot create mode 100644 src/assets/fonts/IropkeBatangM.ttf create mode 100644 src/assets/fonts/IropkeBatangM.woff diff --git a/src/assets/custom.css b/src/assets/custom.css index 92bfef0..d7a8d7d 100644 --- a/src/assets/custom.css +++ b/src/assets/custom.css @@ -2,10 +2,10 @@ 이롭게 바탕체 https://www.iropke.com/archive/iropke-batang-css.html */ -@import url('//cdn.jsdelivr.net/font-iropke-batang/1.2/font-iropke-batang.css'); +@import url('font-iropke-batang.css'); body { - font-family: 'Iropke Batang', serif; + font-family: 'Lato', 'Iropke Batang'; } p { line-height: 1.8em; diff --git a/src/assets/font-iropke-batang.css b/src/assets/font-iropke-batang.css new file mode 100644 index 0000000..4df3e05 --- /dev/null +++ b/src/assets/font-iropke-batang.css @@ -0,0 +1,13 @@ +/* + * Iropke Batang (Korean) + * http://font.iropke.com/batang/ + */ +@font-face { + font-family: 'Iropke Batang'; + font-style: normal; + font-weight: 400; + src: url(fonts/IropkeBatangM.eot); + src: url(fonts/IropkeBatangM.eot?#iefix) format('embedded-opentype'), + url(fonts/IropkeBatangM.woff) format('woff'), + url(fonts/IropkeBatangM.ttf) format('truetype'); +} diff --git a/src/assets/fonts/IropkeBatangM.eot b/src/assets/fonts/IropkeBatangM.eot new file mode 100644 index 0000000000000000000000000000000000000000..68a5913b34804d797fbc477c08c676f13fb90b74 GIT binary patch literal 857430 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�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

@xcHGT;`F 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

WJw%k3AqP~FN#MIk903yn5TbTk8T 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 literal 0 HcmV?d00001 diff --git a/src/assets/fonts/IropkeBatangM.ttf b/src/assets/fonts/IropkeBatangM.ttf new file mode 100644 index 0000000000000000000000000000000000000000..efa41dcdd503ed38f208e47a09a0a1295ff5210d GIT binary patch literal 3202516 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

^3pQCIRNr>7bS%3)U$+V)by6_$g6 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%0DmH`0@%6_xH=pb)kPpT1IaDmtmabs0 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࡝OnNtWEdc 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�Df; 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%0DubVk8a7AbXq-6d$5Igu- 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

~L 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 literal 0 HcmV?d00001 diff --git a/src/assets/fonts/IropkeBatangM.woff b/src/assets/fonts/IropkeBatangM.woff new file mode 100644 index 0000000000000000000000000000000000000000..b7f793a3ee020299d73e12ee76605e5da5a47c57 GIT binary patch literal 984484 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 Q*4=Hy_8AoJZ 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

((kCgv3I4VWfS2*|)EcEyqs9<; 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%0Aq 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

SBlL3d8G|$2!}8xJAEu8L{-})4Rht_GR`g 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Í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

UL5o3Y}I%D9Mcr?_bVy>zP=1!(+;dOQ4 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 z%0A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 z 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 wbF3oh~_cnNK57VZ+`$+{hQDj-7q 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

#{ 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 z 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 z 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'YyZGBa0sUV9*CHdVQR9!P$! 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 literal 0 HcmV?d00001 From 50f1afbad29827bbe2be552b0e64d1f2dab3defc Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Fri, 8 Jun 2018 20:23:00 +0900 Subject: [PATCH 034/153] add fonts, iropke-batang to ignore_assets --- tools/check_codex.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/check_codex.jl b/tools/check_codex.jl index 402a3e1..d815fb2 100644 --- a/tools/check_codex.jl +++ b/tools/check_codex.jl @@ -19,7 +19,7 @@ const julia_doc_src_path = abspath(JULIA_PATH, "doc", "src") translated_files = [] function check_src_and_codex(path1, path2) - ignore_assets = ["custom.css"] + ignore_assets = ["custom.css", "font-iropke-batang.css", "fonts"] src_codex_diff = `diff -qr $path1 $path2` lines = readlines(ignorestatus(src_codex_diff)) for line in lines From 590346bffe06306e24ea1be42977c4c6de944d13 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Tue, 12 Jun 2018 12:14:48 +0900 Subject: [PATCH 035/153] update Julia Commit 83a0dd79cd --- codex/NEWS.md | 12 ++++++++++-- codex/base/c.md | 1 + codex/base/math.md | 5 ----- codex/manual/mathematical-operations.md | 9 ++------- src/NEWS.md | 12 ++++++++++-- src/base/c.md | 1 + src/base/math.md | 5 ----- src/manual/mathematical-operations.md | 9 ++------- 8 files changed, 26 insertions(+), 28 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index 3a38ea3..314e6cf 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -47,6 +47,8 @@ New language features * Keyword arguments can be required: if a default value is omitted, then an exception is thrown if the caller does not assign the keyword a value ([#25830](https://github.com/JuliaLang/julia/issues/25830)). + * The pair operator `=>` is now broadcastable as `.=>` which was previously a parsing error ([#27447](https://github.com/JuliaLang/julia/issues/27447)) + Language changes ---------------- @@ -994,8 +996,11 @@ Deprecated or removed * `Base.SparseArrays.SpDiagIterator` has been removed ([#23261](https://github.com/JuliaLang/julia/issues/23261)). - * The tuple-of-types form of `cfunction`, `cfunction(f, returntype, (types...))`, has been deprecated - in favor of the tuple-type form `cfunction(f, returntype, Tuple{types...})` ([#23066](https://github.com/JuliaLang/julia/issues/23066)). + * The function `cfunction`, has been deprecated in favor of a macro form `@cfunction`. + Most existing uses can be upgraded simply by adding a `@`. + The new syntax now additionally supports allocating closures at runtime, + for dealing with C APIs that don't provide a separate `void* env`-type callback + argument. ([#26486](https://github.com/JuliaLang/julia/issues/26486)) * `diagm(v::AbstractVector, k::Integer=0)` has been deprecated in favor of `diagm(k => v)` ([#24047](https://github.com/JuliaLang/julia/issues/24047)). @@ -1256,6 +1261,9 @@ Deprecated or removed * `setrounding` has been deprecated for `Float32` and `Float64`, as the behaviour was too unreliable ([#26935](https://github.com/JuliaLang/julia/issues/26935)). + * `gamma`, `lgamma`, `beta`, `lbeta` and `lfact` have been moved to + [SpecialFunctions.jl](https://github.com/JuliaMath/SpecialFunctions.jl) ([#27459](https://github.com/JuliaLang/julia/issues/27459), [#27473](https://github.com/JuliaLang/julia/issues/27473)). + * `atan2` is now a 2-argument method of `atan` ([#27248](https://github.com/JuliaLang/julia/issues/27248)). Command-line option changes diff --git a/codex/base/c.md b/codex/base/c.md index a09b916..7977dd2 100644 --- a/codex/base/c.md +++ b/codex/base/c.md @@ -4,6 +4,7 @@ ccall Core.Intrinsics.cglobal Base.@cfunction +Base.CFunction Base.unsafe_convert Base.cconvert Base.unsafe_load diff --git a/codex/base/math.md b/codex/base/math.md index 1359b11..91e8d07 100644 --- a/codex/base/math.md +++ b/codex/base/math.md @@ -172,11 +172,6 @@ Base.prevpow Base.nextprod Base.invmod Base.powermod -Base.Math.gamma -Base.Math.lgamma -Base.Math.lfact -Base.Math.beta -Base.Math.lbeta Base.ndigits Base.widemul Base.Math.@evalpoly diff --git a/codex/manual/mathematical-operations.md b/codex/manual/mathematical-operations.md index aae4ce1..35417b6 100644 --- a/codex/manual/mathematical-operations.md +++ b/codex/manual/mathematical-operations.md @@ -548,10 +548,5 @@ asind acosd atand acotd asecd acscd ### Special functions -| Function | Description | -|:------------------------------------------------------------- |:--------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [`gamma(x)`](@ref) | [gamma function](https://en.wikipedia.org/wiki/Gamma_function) at `x` | -| [`lgamma(x)`](@ref) | accurate `log(gamma(x))` for large `x` | -| [`lfact(x)`](@ref) | accurate `log(factorial(x))` for large `x`; same as `lgamma(x+1)` for `x > 1`, zero otherwise | -| [`beta(x,y)`](@ref) | [beta function](https://en.wikipedia.org/wiki/Beta_function) at `x,y` | -| [`lbeta(x,y)`](@ref) | accurate `log(beta(x,y))` for large `x` or `y` | +Many other special mathematical functions are provided by the package +[SpecialFunctions.jl](https://github.com/JuliaMath/SpecialFunctions.jl). diff --git a/src/NEWS.md b/src/NEWS.md index cb475a2..c26309f 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -35,6 +35,8 @@ * 키워드 인자를 요구할 수 있습니다: 기본값을 생략한 경우, 호출하는 쪽에서 키워드 값을 지정하지 않으면 예외를 던집니다 ([#25830](https://github.com/JuliaLang/julia/issues/25830)). + * pair 연산자 `=>` 또한 `.=>`로 브로드캐스팅 할 수 있습니다. 파싱 에러(parsing error) 였던 것을 고쳤습니다. ([#27447](https://github.com/JuliaLang/julia/issues/27447)) + Language changes ---------------- @@ -982,8 +984,11 @@ Deprecated or removed * `Base.SparseArrays.SpDiagIterator` has been removed ([#23261](https://github.com/JuliaLang/julia/issues/23261)). - * The tuple-of-types form of `cfunction`, `cfunction(f, returntype, (types...))`, has been deprecated - in favor of the tuple-type form `cfunction(f, returntype, Tuple{types...})` ([#23066](https://github.com/JuliaLang/julia/issues/23066)). + * The function `cfunction`, has been deprecated in favor of a macro form `@cfunction`. + Most existing uses can be upgraded simply by adding a `@`. + The new syntax now additionally supports allocating closures at runtime, + for dealing with C APIs that don't provide a separate `void* env`-type callback + argument. ([#26486](https://github.com/JuliaLang/julia/issues/26486)) * `diagm(v::AbstractVector, k::Integer=0)` has been deprecated in favor of `diagm(k => v)` ([#24047](https://github.com/JuliaLang/julia/issues/24047)). @@ -1244,6 +1249,9 @@ Deprecated or removed * `setrounding` has been deprecated for `Float32` and `Float64`, as the behaviour was too unreliable ([#26935](https://github.com/JuliaLang/julia/issues/26935)). + * `gamma`, `lgamma`, `beta`, `lbeta` and `lfact` have been moved to + [SpecialFunctions.jl](https://github.com/JuliaMath/SpecialFunctions.jl) ([#27459](https://github.com/JuliaLang/julia/issues/27459), [#27473](https://github.com/JuliaLang/julia/issues/27473)). + * `atan2` is now a 2-argument method of `atan` ([#27248](https://github.com/JuliaLang/julia/issues/27248)). Command-line option changes diff --git a/src/base/c.md b/src/base/c.md index a09b916..7977dd2 100644 --- a/src/base/c.md +++ b/src/base/c.md @@ -4,6 +4,7 @@ ccall Core.Intrinsics.cglobal Base.@cfunction +Base.CFunction Base.unsafe_convert Base.cconvert Base.unsafe_load diff --git a/src/base/math.md b/src/base/math.md index 1359b11..91e8d07 100644 --- a/src/base/math.md +++ b/src/base/math.md @@ -172,11 +172,6 @@ Base.prevpow Base.nextprod Base.invmod Base.powermod -Base.Math.gamma -Base.Math.lgamma -Base.Math.lfact -Base.Math.beta -Base.Math.lbeta Base.ndigits Base.widemul Base.Math.@evalpoly diff --git a/src/manual/mathematical-operations.md b/src/manual/mathematical-operations.md index aae4ce1..35417b6 100644 --- a/src/manual/mathematical-operations.md +++ b/src/manual/mathematical-operations.md @@ -548,10 +548,5 @@ asind acosd atand acotd asecd acscd ### Special functions -| Function | Description | -|:------------------------------------------------------------- |:--------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [`gamma(x)`](@ref) | [gamma function](https://en.wikipedia.org/wiki/Gamma_function) at `x` | -| [`lgamma(x)`](@ref) | accurate `log(gamma(x))` for large `x` | -| [`lfact(x)`](@ref) | accurate `log(factorial(x))` for large `x`; same as `lgamma(x+1)` for `x > 1`, zero otherwise | -| [`beta(x,y)`](@ref) | [beta function](https://en.wikipedia.org/wiki/Beta_function) at `x,y` | -| [`lbeta(x,y)`](@ref) | accurate `log(beta(x,y))` for large `x` or `y` | +Many other special mathematical functions are provided by the package +[SpecialFunctions.jl](https://github.com/JuliaMath/SpecialFunctions.jl). From 18675f552a0ea9f588744198f4bb3849afa3c808 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Sun, 17 Jun 2018 11:36:42 +0900 Subject: [PATCH 036/153] update Julia Commit 5e3259e98e --- codex/NEWS.md | 10 ++++- codex/manual/code-loading.md | 12 +++--- codex/manual/control-flow.md | 6 --- codex/manual/metaprogramming.md | 4 -- codex/stdlib/Pkg.md | 73 +++++++++++++++++++++++++++++---- src/NEWS.md | 10 ++++- src/manual/code-loading.md | 12 +++--- src/manual/control-flow.md | 6 --- src/manual/metaprogramming.md | 4 -- src/stdlib/Pkg.md | 73 +++++++++++++++++++++++++++++---- 10 files changed, 156 insertions(+), 54 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index 314e6cf..e63cc6b 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -220,6 +220,9 @@ Language changes is deprecated. It will likely be reclaimed in a later version for passing keyword arguments. Note this does not affect updating operators like `+=` ([#25631](https://github.com/JuliaLang/julia/issues/25631)). + * `try` blocks without `catch` or `finally` are no longer allowed. An explicit empty + `catch` block should be written instead ([#27554](https://github.com/JuliaLang/julia/issues/27554)). + Breaking changes ---------------- @@ -694,6 +697,9 @@ Library improvements * `Sys.which()` provides a cross-platform method to find executable files, similar to the Unix `which` command. ([#26559](https://github.com/JuliaLang/julia/issues/26559)) + * Added an optimized method of `vecdot` for taking the Frobenius inner product + of sparse matrices. ([#27470](https://github.com/JuliaLang/julia/issues/27470)) + Compiler/Runtime improvements ----------------------------- @@ -1023,8 +1029,8 @@ Deprecated or removed * `eu` (previously an alias for `ℯ`) has been deprecated in favor of `ℯ` (or `MathConstants.e`) ([#23427](https://github.com/JuliaLang/julia/issues/23427)). - * `GMP.gmp_version()`, `GMP.GMP_VERSION`, `GMP.gmp_bits_per_limb()`, and `GMP.GMP_BITS_PER_LIBM` - have been renamed to `GMP.version()`, `GMP.VERSION`, `GMP.bits_per_libm()`, and `GMP.BITS_PER_LIBM`, + * `GMP.gmp_version()`, `GMP.GMP_VERSION`, `GMP.gmp_bits_per_limb()`, and `GMP.GMP_BITS_PER_LIMB` + have been renamed to `GMP.version()`, `GMP.VERSION`, `GMP.bits_per_limb()`, and `GMP.BITS_PER_LIMB`, respectively. Similarly, `MPFR.get_version()`, has been renamed to `MPFR.version()` ([#23323](https://github.com/JuliaLang/julia/issues/23323)). Also, `LinAlg.LAPACK.laver()` has been renamed to `LinAlg.LAPACK.version()` and now returns a `VersionNumber`. diff --git a/codex/manual/code-loading.md b/codex/manual/code-loading.md index 2140306..c990de6 100644 --- a/codex/manual/code-loading.md +++ b/codex/manual/code-loading.md @@ -99,7 +99,7 @@ git-tree-sha1 = "1bf63d3be994fe83456a03b874b409cfd59a6373" version = "0.1.5" [[Pub]] -uuid = "ba13f791-ae1d-465a-978b-69c3ad90f72b" +uuid = "c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1" git-tree-sha1 = "9ebd50e2b0dd1e110e842df3b433cb5869b0dd38" version = "2.1.4" @@ -126,13 +126,13 @@ A materialized representation of this dependency `graph` looks like this: graph = Dict{UUID,Dict{Symbol,UUID}}( # Priv – the private one: UUID("ba13f791-ae1d-465a-978b-69c3ad90f72b") => Dict{Symbol,UUID}( - :Pub => UUID("ba13f791-ae1d-465a-978b-69c3ad90f72b"), + :Pub => UUID("c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1"), :Zebra => UUID("f7a24cb4-21fc-4002-ac70-f0e3a0dd3f62"), ), # Priv – the public one: UUID("2d15fe94-a1f7-436c-a4d8-07a9a496e01c") => Dict{Symbol,UUID}(), # Pub: - UUID("ba13f791-ae1d-465a-978b-69c3ad90f72b") => Dict{Symbol,UUID}( + UUID("c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1") => Dict{Symbol,UUID}( :Priv => UUID("2d15fe94-a1f7-436c-a4d8-07a9a496e01c"), :Zebra => UUID("f7a24cb4-21fc-4002-ac70-f0e3a0dd3f62"), ), @@ -141,10 +141,10 @@ graph = Dict{UUID,Dict{Symbol,UUID}}( ) ``` -Given this dependency `graph`, when Julia sees `import Priv` in the `Pub` package—which has UUID `ba13f791-ae1d-465a-978b-69c3ad90f72b`—it looks up: +Given this dependency `graph`, when Julia sees `import Priv` in the `Pub` package—which has UUID `c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1`—it looks up: ```julia -graph[UUID("ba13f791-ae1d-465a-978b-69c3ad90f72b")][:Priv] +graph[UUID("c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1")][:Priv] ``` and gets `2d15fe94-a1f7-436c-a4d8-07a9a496e01c` , which indicates that in the context of the `Pub` package, `import Priv` refers to the public `Priv` package, rather than the private one which the app depends on directly. This is how the name `Priv` can refer to different packages in the main project than it does in one of the packages dependencies, which allows for name collisions in the package ecosystem. @@ -180,7 +180,7 @@ paths = Dict{Tuple{UUID,Symbol},String}( # package installed in the system depot: "/usr/local/julia/packages/Priv/HDkr/src/Priv.jl", # Pub: - (UUID("ba13f791-ae1d-465a-978b-69c3ad90f72b"), :Pub) => + (UUID("c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1"), :Pub) => # package installed in the user depot: "/home/me/.julia/packages/Pub/oKpw/src/Pub.jl", # Zebra: diff --git a/codex/manual/control-flow.md b/codex/manual/control-flow.md index 47cb4a9..44e034e 100644 --- a/codex/manual/control-flow.md +++ b/codex/manual/control-flow.md @@ -790,12 +790,6 @@ catch end ``` -The `catch` clause is not strictly necessary; when omitted, the default return value is `nothing`. - -```jldoctest -julia> try error() end # Returns nothing -``` - The power of the `try/catch` construct lies in the ability to unwind a deeply nested computation immediately to a much higher level in the stack of calling functions. There are situations where no error has occurred, but the ability to unwind the stack and pass a value to a higher level diff --git a/codex/manual/metaprogramming.md b/codex/manual/metaprogramming.md index 14fa9c5..6cc4e01 100644 --- a/codex/manual/metaprogramming.md +++ b/codex/manual/metaprogramming.md @@ -80,7 +80,6 @@ Expr 1: Symbol + 2: Int64 1 3: Int64 1 - typ: Any ``` `Expr` objects may also be nested: @@ -324,8 +323,6 @@ Expr 1: Symbol + 2: Int64 1 3: Int64 2 - typ: Any - typ: Any ``` As we have seen, such expressions support interpolation with `$`. @@ -734,7 +731,6 @@ Expr 3: String ") should equal b (" 4: Symbol b 5: String ")!" - typ: Any ``` So now instead of getting a plain string in `msg_body`, the macro is receiving a full expression diff --git a/codex/stdlib/Pkg.md b/codex/stdlib/Pkg.md index 9d8651a..a6bb9ba 100644 --- a/codex/stdlib/Pkg.md +++ b/codex/stdlib/Pkg.md @@ -329,9 +329,9 @@ Let’s say we found a bug in one of our dependencies, e.g. `JSON` that we want ... ``` -By default, the package get cloned to the `~/.julia/dev` folder but can also be set by the `JULIA_PKG_DEVDIR` environment variable. +By default, the package gets cloned to the `~/.julia/dev` folder but can also be set by the `JULIA_PKG_DEVDIR` environment variable. When we have fixed the bug and checked that `JSON` now works correctly with our project, we can make a PR to the `JSON` repository. -When the PR has been merged we can go over to track the master branch and finally, when a new release of `JSON` is made, we can go back to using the versioned `JSON` using the command `free` and `update` (see next section): +When the PR has been merged we can go over to track the master branch and finally when a new release of `JSON` is made, we can go back to using the versioned `JSON` using the command `free` and `update` (see next section): ``` (HelloWorld) pkg> free JSON @@ -344,11 +344,11 @@ When the PR has been merged we can go over to track the master branch and finall It is also possible to give a local path as the argument to `develop` which will not clone anything but simply use that directory for the package. -Overriding the dependency path for a non registered package is done by giving the git-repo url as an argument to `develop`. +Overriding the dependency path for a non-registered package is done by giving the git-repo url as an argument to `develop`. ## Updating dependencies -When new versions of packages the project is using are released, it is a good idea to update. Simply calling `up` will try to update *all* the dependencies of the project. Sometimes this is not what you want. You can specify a subset of the dependencies to upgrade by giving them as arguments to `up`, e.g: +When new versions of packages the project is using are released, it is a good idea to update. Simply calling `up` will try to update *all* the dependencies of the project. Sometimes this is not what you want. You can specify a subset of the dependencies to upgrade by giving them as arguments to `up`, e.g: ``` (HelloWorld) pkg> up JSON @@ -363,7 +363,7 @@ The version of all other direct dependencies will stay the same. If you only wan Packages that track a branch are not updated when a minor upgrade is done. Developed packages are never touched by the package manager. -If you just want install the packages that are given by the current `Manifest.toml` use +If you just want to install the packages that are given by the current `Manifest.toml` use ``` (HelloWorld) pkg> instantiate @@ -394,10 +394,10 @@ or (HelloWorld) pkg> preview up ``` -will show you the effects adding `Plots`, or doing a full upgrade, respectively, would have on your project. +will show you the effects of adding `Plots`, or doing a full upgrade, respectively, would have on your project. However, nothing would be installed and your `Project.toml` and `Manfiest.toml` are untouched. -## Using someone elses project +## Using someone else's project Simple clone their project using e.g. `git clone`, `cd` to the project directory and call @@ -405,7 +405,62 @@ Simple clone their project using e.g. `git clone`, `cd` to the project directory (SomeProject) pkg> instantiate ``` -If the project contains a manifest, this will install the packages at the same state that is given by that manifest. -Otherwise it will resolve the latest versions of the dependencies compatible with the project. +If the project contains a manifest, this will install the packages in the same state that is given by that manifest. +Otherwise, it will resolve the latest versions of the dependencies compatible with the project. +## Compatibility +Compatibility refers to the ability to restrict what version of the dependencies that your project is compatible with. +If the compatibility for a dependency is not given, the project is assumed to be compatible with all versions of that dependency. + +Compatibility for a dependency is entered in the `Project.toml` file as for example: + +```toml +[compat] +Example = "0.4.3" +``` + +After a compatibility entry is put into the project file, `up` can be used to apply it. + +The format of the version specifier is described in detail below. + +!!! info + There is currently no way to give compatibility from the Pkg REPL mode so for now, one has to manually edit the project file. + +### Version specifier format + +Similar to other package managers, the Julia package manager respects [semantic versioning](https://semver.org/) (semver). +As an example, a version specifier is given as e.g. `1.2.3` is therefore assumed to be compatible with the versions `[1.2.3 - 2.0.0)` where `)` is a non-inclusive upper bound. +More specifically, a version specifier is either given as a **caret specifier**, e.g. `^1.2.3` or a **tilde specifier** `~1.2.3`. +Caret specifiers are the default and hence `1.2.3 == ^1.2.3`. The difference between a caret and tilde is described in the next section. + +#### Caret specifiers + +A caret specifier allows upgrade that would be compatible according to semver. +An updated dependency is considered compatible if the new version does not modify the left-most non zero digit in the version specifier. + +Some examples are shown below. + +``` +^1.2.3 = [1.2.3, 2.0.0) +^1.2 = [1.2.0, 2.0.0) +^1 = [1.0.0, 2.0.0) +^0.2.3 = [0.2.3, 0.3.0) +^0.0.3 = [0.0.3, 0.0.4) +^0.0 = [0.0.0, 0.1.0) +^0 = [0.0.0, 1.0.0) +``` + +While the semver specification says that all versions with a major version of 0 are incompatible with each other, we have made that choice that +a version given as `0.a.b` is considered compatible with `0.a.c` if `a != 0` and `c >= b`. + +#### Tilde specifiers + +A tilde specifier provides more limited upgrade possibilities. With a tilde, only the last specified digit is allowed to increment by one. +This gives the following example. + +``` +~1.2.3 = [1.2.3, 1.2.4) +~1.2 = [1.2.0, 1.3.0) +~1 = [1.0.0, 2.0.0) +``` diff --git a/src/NEWS.md b/src/NEWS.md index c26309f..1c98766 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -208,6 +208,9 @@ Language changes is deprecated. It will likely be reclaimed in a later version for passing keyword arguments. Note this does not affect updating operators like `+=` ([#25631](https://github.com/JuliaLang/julia/issues/25631)). + * `try` blocks without `catch` or `finally` are no longer allowed. An explicit empty + `catch` block should be written instead ([#27554](https://github.com/JuliaLang/julia/issues/27554)). + Breaking changes ---------------- @@ -682,6 +685,9 @@ Library improvements * `Sys.which()` provides a cross-platform method to find executable files, similar to the Unix `which` command. ([#26559](https://github.com/JuliaLang/julia/issues/26559)) + * Added an optimized method of `vecdot` for taking the Frobenius inner product + of sparse matrices. ([#27470](https://github.com/JuliaLang/julia/issues/27470)) + Compiler/Runtime improvements ----------------------------- @@ -1011,8 +1017,8 @@ Deprecated or removed * `eu` (previously an alias for `ℯ`) has been deprecated in favor of `ℯ` (or `MathConstants.e`) ([#23427](https://github.com/JuliaLang/julia/issues/23427)). - * `GMP.gmp_version()`, `GMP.GMP_VERSION`, `GMP.gmp_bits_per_limb()`, and `GMP.GMP_BITS_PER_LIBM` - have been renamed to `GMP.version()`, `GMP.VERSION`, `GMP.bits_per_libm()`, and `GMP.BITS_PER_LIBM`, + * `GMP.gmp_version()`, `GMP.GMP_VERSION`, `GMP.gmp_bits_per_limb()`, and `GMP.GMP_BITS_PER_LIMB` + have been renamed to `GMP.version()`, `GMP.VERSION`, `GMP.bits_per_limb()`, and `GMP.BITS_PER_LIMB`, respectively. Similarly, `MPFR.get_version()`, has been renamed to `MPFR.version()` ([#23323](https://github.com/JuliaLang/julia/issues/23323)). Also, `LinAlg.LAPACK.laver()` has been renamed to `LinAlg.LAPACK.version()` and now returns a `VersionNumber`. diff --git a/src/manual/code-loading.md b/src/manual/code-loading.md index 2140306..c990de6 100644 --- a/src/manual/code-loading.md +++ b/src/manual/code-loading.md @@ -99,7 +99,7 @@ git-tree-sha1 = "1bf63d3be994fe83456a03b874b409cfd59a6373" version = "0.1.5" [[Pub]] -uuid = "ba13f791-ae1d-465a-978b-69c3ad90f72b" +uuid = "c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1" git-tree-sha1 = "9ebd50e2b0dd1e110e842df3b433cb5869b0dd38" version = "2.1.4" @@ -126,13 +126,13 @@ A materialized representation of this dependency `graph` looks like this: graph = Dict{UUID,Dict{Symbol,UUID}}( # Priv – the private one: UUID("ba13f791-ae1d-465a-978b-69c3ad90f72b") => Dict{Symbol,UUID}( - :Pub => UUID("ba13f791-ae1d-465a-978b-69c3ad90f72b"), + :Pub => UUID("c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1"), :Zebra => UUID("f7a24cb4-21fc-4002-ac70-f0e3a0dd3f62"), ), # Priv – the public one: UUID("2d15fe94-a1f7-436c-a4d8-07a9a496e01c") => Dict{Symbol,UUID}(), # Pub: - UUID("ba13f791-ae1d-465a-978b-69c3ad90f72b") => Dict{Symbol,UUID}( + UUID("c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1") => Dict{Symbol,UUID}( :Priv => UUID("2d15fe94-a1f7-436c-a4d8-07a9a496e01c"), :Zebra => UUID("f7a24cb4-21fc-4002-ac70-f0e3a0dd3f62"), ), @@ -141,10 +141,10 @@ graph = Dict{UUID,Dict{Symbol,UUID}}( ) ``` -Given this dependency `graph`, when Julia sees `import Priv` in the `Pub` package—which has UUID `ba13f791-ae1d-465a-978b-69c3ad90f72b`—it looks up: +Given this dependency `graph`, when Julia sees `import Priv` in the `Pub` package—which has UUID `c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1`—it looks up: ```julia -graph[UUID("ba13f791-ae1d-465a-978b-69c3ad90f72b")][:Priv] +graph[UUID("c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1")][:Priv] ``` and gets `2d15fe94-a1f7-436c-a4d8-07a9a496e01c` , which indicates that in the context of the `Pub` package, `import Priv` refers to the public `Priv` package, rather than the private one which the app depends on directly. This is how the name `Priv` can refer to different packages in the main project than it does in one of the packages dependencies, which allows for name collisions in the package ecosystem. @@ -180,7 +180,7 @@ paths = Dict{Tuple{UUID,Symbol},String}( # package installed in the system depot: "/usr/local/julia/packages/Priv/HDkr/src/Priv.jl", # Pub: - (UUID("ba13f791-ae1d-465a-978b-69c3ad90f72b"), :Pub) => + (UUID("c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1"), :Pub) => # package installed in the user depot: "/home/me/.julia/packages/Pub/oKpw/src/Pub.jl", # Zebra: diff --git a/src/manual/control-flow.md b/src/manual/control-flow.md index 4851a99..57afc3d 100644 --- a/src/manual/control-flow.md +++ b/src/manual/control-flow.md @@ -692,12 +692,6 @@ catch end ``` -`catch`절은 꼭 필요한 것은 아닙니다. 생략한다면 기본 반환값은 `nothing`입니다. - -```jldoctest -julia> try error() end # Returns nothing -``` - `try/catch`문의 장점은 호출 함수의 스택에서 훨씬 더 높은 레벨로 깊게 중첩된 계산을 즉시 풀 수 있는 능력에 있습니다. 오류가 발생하지 않은 상황이 있지만 스택을 풀어 더 높은 레벨로 값을 전달하는 것이 바람직합니다. Julia는 고급 오류 처리를 위해 `rethrow`, `backtrace`, `catch_backtrace`와 같은 함수들을 제공합니다. ### `finally`문 diff --git a/src/manual/metaprogramming.md b/src/manual/metaprogramming.md index 14fa9c5..6cc4e01 100644 --- a/src/manual/metaprogramming.md +++ b/src/manual/metaprogramming.md @@ -80,7 +80,6 @@ Expr 1: Symbol + 2: Int64 1 3: Int64 1 - typ: Any ``` `Expr` objects may also be nested: @@ -324,8 +323,6 @@ Expr 1: Symbol + 2: Int64 1 3: Int64 2 - typ: Any - typ: Any ``` As we have seen, such expressions support interpolation with `$`. @@ -734,7 +731,6 @@ Expr 3: String ") should equal b (" 4: Symbol b 5: String ")!" - typ: Any ``` So now instead of getting a plain string in `msg_body`, the macro is receiving a full expression diff --git a/src/stdlib/Pkg.md b/src/stdlib/Pkg.md index 9d8651a..a6bb9ba 100644 --- a/src/stdlib/Pkg.md +++ b/src/stdlib/Pkg.md @@ -329,9 +329,9 @@ Let’s say we found a bug in one of our dependencies, e.g. `JSON` that we want ... ``` -By default, the package get cloned to the `~/.julia/dev` folder but can also be set by the `JULIA_PKG_DEVDIR` environment variable. +By default, the package gets cloned to the `~/.julia/dev` folder but can also be set by the `JULIA_PKG_DEVDIR` environment variable. When we have fixed the bug and checked that `JSON` now works correctly with our project, we can make a PR to the `JSON` repository. -When the PR has been merged we can go over to track the master branch and finally, when a new release of `JSON` is made, we can go back to using the versioned `JSON` using the command `free` and `update` (see next section): +When the PR has been merged we can go over to track the master branch and finally when a new release of `JSON` is made, we can go back to using the versioned `JSON` using the command `free` and `update` (see next section): ``` (HelloWorld) pkg> free JSON @@ -344,11 +344,11 @@ When the PR has been merged we can go over to track the master branch and finall It is also possible to give a local path as the argument to `develop` which will not clone anything but simply use that directory for the package. -Overriding the dependency path for a non registered package is done by giving the git-repo url as an argument to `develop`. +Overriding the dependency path for a non-registered package is done by giving the git-repo url as an argument to `develop`. ## Updating dependencies -When new versions of packages the project is using are released, it is a good idea to update. Simply calling `up` will try to update *all* the dependencies of the project. Sometimes this is not what you want. You can specify a subset of the dependencies to upgrade by giving them as arguments to `up`, e.g: +When new versions of packages the project is using are released, it is a good idea to update. Simply calling `up` will try to update *all* the dependencies of the project. Sometimes this is not what you want. You can specify a subset of the dependencies to upgrade by giving them as arguments to `up`, e.g: ``` (HelloWorld) pkg> up JSON @@ -363,7 +363,7 @@ The version of all other direct dependencies will stay the same. If you only wan Packages that track a branch are not updated when a minor upgrade is done. Developed packages are never touched by the package manager. -If you just want install the packages that are given by the current `Manifest.toml` use +If you just want to install the packages that are given by the current `Manifest.toml` use ``` (HelloWorld) pkg> instantiate @@ -394,10 +394,10 @@ or (HelloWorld) pkg> preview up ``` -will show you the effects adding `Plots`, or doing a full upgrade, respectively, would have on your project. +will show you the effects of adding `Plots`, or doing a full upgrade, respectively, would have on your project. However, nothing would be installed and your `Project.toml` and `Manfiest.toml` are untouched. -## Using someone elses project +## Using someone else's project Simple clone their project using e.g. `git clone`, `cd` to the project directory and call @@ -405,7 +405,62 @@ Simple clone their project using e.g. `git clone`, `cd` to the project directory (SomeProject) pkg> instantiate ``` -If the project contains a manifest, this will install the packages at the same state that is given by that manifest. -Otherwise it will resolve the latest versions of the dependencies compatible with the project. +If the project contains a manifest, this will install the packages in the same state that is given by that manifest. +Otherwise, it will resolve the latest versions of the dependencies compatible with the project. +## Compatibility +Compatibility refers to the ability to restrict what version of the dependencies that your project is compatible with. +If the compatibility for a dependency is not given, the project is assumed to be compatible with all versions of that dependency. + +Compatibility for a dependency is entered in the `Project.toml` file as for example: + +```toml +[compat] +Example = "0.4.3" +``` + +After a compatibility entry is put into the project file, `up` can be used to apply it. + +The format of the version specifier is described in detail below. + +!!! info + There is currently no way to give compatibility from the Pkg REPL mode so for now, one has to manually edit the project file. + +### Version specifier format + +Similar to other package managers, the Julia package manager respects [semantic versioning](https://semver.org/) (semver). +As an example, a version specifier is given as e.g. `1.2.3` is therefore assumed to be compatible with the versions `[1.2.3 - 2.0.0)` where `)` is a non-inclusive upper bound. +More specifically, a version specifier is either given as a **caret specifier**, e.g. `^1.2.3` or a **tilde specifier** `~1.2.3`. +Caret specifiers are the default and hence `1.2.3 == ^1.2.3`. The difference between a caret and tilde is described in the next section. + +#### Caret specifiers + +A caret specifier allows upgrade that would be compatible according to semver. +An updated dependency is considered compatible if the new version does not modify the left-most non zero digit in the version specifier. + +Some examples are shown below. + +``` +^1.2.3 = [1.2.3, 2.0.0) +^1.2 = [1.2.0, 2.0.0) +^1 = [1.0.0, 2.0.0) +^0.2.3 = [0.2.3, 0.3.0) +^0.0.3 = [0.0.3, 0.0.4) +^0.0 = [0.0.0, 0.1.0) +^0 = [0.0.0, 1.0.0) +``` + +While the semver specification says that all versions with a major version of 0 are incompatible with each other, we have made that choice that +a version given as `0.a.b` is considered compatible with `0.a.c` if `a != 0` and `c >= b`. + +#### Tilde specifiers + +A tilde specifier provides more limited upgrade possibilities. With a tilde, only the last specified digit is allowed to increment by one. +This gives the following example. + +``` +~1.2.3 = [1.2.3, 1.2.4) +~1.2 = [1.2.0, 1.3.0) +~1 = [1.0.0, 2.0.0) +``` From 1774ee642a94be29b68f6851d5c09cbcceb62e8c Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Tue, 19 Jun 2018 19:58:26 +0900 Subject: [PATCH 037/153] update Julia Commit d128b9c847 --- codex/NEWS.md | 17 +- codex/base/strings.md | 2 + codex/manual/documentation.md | 4 +- codex/manual/noteworthy-differences.md | 3 - codex/stdlib/IterativeEigensolvers.md | 208 ---------- codex/stdlib/LibGit2.md | 1 + codex/stdlib/LinearAlgebra.md | 3 +- codex/stdlib/Pkg.md | 516 ++++++++++++++++++++----- codex/stdlib/iterativeeigensolvers.md | 208 ---------- codex/stdlib/linearalgebra.md | 3 +- contrib/build_sysimg.jl | 1 + src/.NEWS.md.swp | Bin 0 -> 110592 bytes src/NEWS.md | 17 +- src/base/strings.md | 2 + src/manual/documentation.md | 4 +- src/manual/noteworthy-differences.md | 3 - src/stdlib/IterativeEigensolvers.md | 208 ---------- src/stdlib/LibGit2.md | 1 + src/stdlib/LinearAlgebra.md | 3 +- src/stdlib/Pkg.md | 516 ++++++++++++++++++++----- src/stdlib/iterativeeigensolvers.md | 208 ---------- src/stdlib/linearalgebra.md | 3 +- 22 files changed, 869 insertions(+), 1062 deletions(-) delete mode 100644 codex/stdlib/IterativeEigensolvers.md delete mode 100644 codex/stdlib/iterativeeigensolvers.md create mode 100644 src/.NEWS.md.swp delete mode 100644 src/stdlib/IterativeEigensolvers.md delete mode 100644 src/stdlib/iterativeeigensolvers.md diff --git a/codex/NEWS.md b/codex/NEWS.md index e63cc6b..16d93d3 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -511,6 +511,13 @@ This section lists changes that do not have deprecation warnings. This change makes `@schedule` redundant with `@async`, so `@schedule` has been deprecated ([#27164](https://github.com/JuliaLang/julia/issues/27164)). + * `norm(A::AbstractMatrix, p=2)` computes no longer the operator/matrix norm but the `norm` of `A` + as for other iterables, i.e. as if it were a vector. Especially, `norm(A::AbstractMatrix)` is the + Frobenius norm. To compute the operator/matrix norm, use the new function `opnorm` ([#27401](https://github.com/JuliaLang/julia/issues/27401)). + + * `dot(u, v)` now acts recursively. Instead of `sum(u[i]' * v[i] for i in ...)`, it computes + `sum(dot(u[i], v[i]) for i in ...)`, similarly to `vecdot` before ([#27401](https://github.com/JuliaLang/julia/issues/27401)). + Library improvements -------------------- @@ -691,6 +698,9 @@ Library improvements * `IOBuffer` can take the `sizehint` keyword argument to suggest a capacity of the buffer ([#25944](https://github.com/JuliaLang/julia/issues/25944)). + * `lstrip` and `rstrip` now accept a predicate function that defaults to `isspace` + ([#27309](https://github.com/JuliaLang/julia/issues/27309)). + * `trunc`, `floor`, `ceil`, and `round` specify `digits`, `sigdigits` and `base` using keyword arguments. ([#26156](https://github.com/JuliaLang/julia/issues/26156), [#26670](https://github.com/JuliaLang/julia/issues/26670)) @@ -1130,9 +1140,6 @@ Deprecated or removed `normalize`, and moved to the new `Unicode` standard library module. `graphemes` has also been moved to that module ([#25021](https://github.com/JuliaLang/julia/issues/25021)). - * The functions `eigs` and `svds` have been moved to the `IterativeEigensolvers` standard - library module ([#24714](https://github.com/JuliaLang/julia/issues/24714)). - * Sparse array functionality has moved to the `SparseArrays` standard library module ([#25249](https://github.com/JuliaLang/julia/issues/25249)). * Linear algebra functionality, and specifically the `LinAlg` module has moved to the @@ -1272,6 +1279,10 @@ Deprecated or removed * `atan2` is now a 2-argument method of `atan` ([#27248](https://github.com/JuliaLang/julia/issues/27248)). + * The functions `eigs` and `svds` have been moved to the `Arpack.jl` package ([#27616](https://github.com/JuliaLang/julia/issues/27616)). + + * `vecdot` and `vecnorm` are deprecated in favor of `dot` and `norm`, respectively ([#27401](https://github.com/JuliaLang/julia/issues/27401)). + Command-line option changes --------------------------- diff --git a/codex/base/strings.md b/codex/base/strings.md index d178271..95e07e3 100644 --- a/codex/base/strings.md +++ b/codex/base/strings.md @@ -21,6 +21,8 @@ Base.codeunit Base.codeunits Base.ascii Base.@r_str +Base.SubstitutionString +Base.@s_str Base.@raw_str Base.Docs.@html_str Base.Docs.@text_str diff --git a/codex/manual/documentation.md b/codex/manual/documentation.md index bfb24a4..20983fd 100644 --- a/codex/manual/documentation.md +++ b/codex/manual/documentation.md @@ -126,8 +126,8 @@ As in the example above, we recommend following some simple conventions when wri Note that whitespace in your doctest is significant! The doctest will fail if you misalign the output of pretty-printing an array, for example. - You can then run `make -C doc doctest` to run all the doctests in the Julia Manual, which will - ensure that your example works. + You can then run `make -C doc doctest=true` to run all the doctests in the Julia Manual and API + documentation, which will ensure that your example works. To indicate that the output result is truncated, you may write `[...]` at the line where checking should stop. This is useful to diff --git a/codex/manual/noteworthy-differences.md b/codex/manual/noteworthy-differences.md index 20ba324..da423bc 100644 --- a/codex/manual/noteworthy-differences.md +++ b/codex/manual/noteworthy-differences.md @@ -49,9 +49,6 @@ may trip up Julia users accustomed to MATLAB: * In Julia, reductions such as [`sum`](@ref), [`prod`](@ref), and [`max`](@ref) are performed over every element of an array when called with a single argument, as in `sum(A)`, even if `A` has more than one dimension. - * In Julia, functions such as [`sort`](@ref) that operate column-wise by default (`sort(A)` is - equivalent to `sort(A,1)`) do not have special behavior for `1xN` arrays; the argument is returned - unmodified since it still performs `sort(A,1)`. To sort a `1xN` matrix like a vector, use `sort(A,2)`. * In Julia, parentheses must be used to call a function with zero arguments, like in [`rand()`](@ref). * Julia discourages the used of semicolons to end statements. The results of statements are not automatically printed (except at the interactive prompt), and lines of code do not need to end diff --git a/codex/stdlib/IterativeEigensolvers.md b/codex/stdlib/IterativeEigensolvers.md deleted file mode 100644 index 185d2dc..0000000 --- a/codex/stdlib/IterativeEigensolvers.md +++ /dev/null @@ -1,208 +0,0 @@ -# [Iterative Eigensolvers](@id lib-itereigen) - -```@meta -DocTestSetup = :(using IterativeEigensolvers, LinearAlgebra, SparseArrays) -``` - -Julia provides bindings to [ARPACK](http://www.caam.rice.edu/software/ARPACK/), which -can be used to perform iterative solutions for eigensystems (using [`eigs`](@ref)) -or singular value decompositions (using [`svds`](@ref)). - -`eigs` calculates the eigenvalues and, optionally, eigenvectors of its input(s) -using implicitly restarted Lanczos or Arnoldi iterations for real symmetric or -general nonsymmetric matrices respectively. - -For the single matrix version, - -`eigs(A; nev=6, ncv=max(20,2*nev+1), which=:LM, tol=0.0, maxiter=300, sigma=nothing, ritzvec=true, v0=zeros((0,))) -> (d,[v,],nconv,niter,nmult,resid)` - -the following keyword arguments are supported: - -* `nev`: Number of eigenvalues -* `ncv`: Number of Krylov vectors used in the computation; should satisfy `nev+1 <= ncv <= n` - for real symmetric problems and `nev+2 <= ncv <= n` for other problems, where `n` is the - size of the input matrix `A`. The default is `ncv = max(20,2*nev+1)`. Note that these - restrictions limit the input matrix `A` to be of dimension at least 2. -* `which`: type of eigenvalues to compute. See the note below. - -| `which` | type of eigenvalues | -|:--------|:--------------------------------------------------------------------------------------------------------------------------| -| `:LM` | eigenvalues of largest magnitude (default) | -| `:SM` | eigenvalues of smallest magnitude | -| `:LR` | eigenvalues of largest real part | -| `:SR` | eigenvalues of smallest real part | -| `:LI` | eigenvalues of largest imaginary part (nonsymmetric or complex `A` only) | -| `:SI` | eigenvalues of smallest imaginary part (nonsymmetric or complex `A` only) | -| `:BE` | compute half of the eigenvalues from each end of the spectrum, biased in favor of the high end. (real symmetric `A` only) | - -* `tol`: parameter defining the relative tolerance for convergence of Ritz values (eigenvalue estimates). - A Ritz value ``θ`` is considered converged when its associated residual - is less than or equal to the product of `tol` and ``max(ɛ^{2/3}, |θ|)``, - where `ɛ = eps(real(eltype(A)))/2` is LAPACK's machine epsilon. - The residual associated with ``θ`` and its corresponding Ritz vector ``v`` - is defined as the norm ``||Av - vθ||``. - The specified value of `tol` should be positive; otherwise, it is ignored - and ``ɛ`` is used instead. - Default: ``ɛ``. - -* `maxiter`: Maximum number of iterations (default = 300) -* `sigma`: Specifies the level shift used in inverse iteration. If `nothing` (default), - defaults to ordinary (forward) iterations. Otherwise, find eigenvalues close to `sigma` - using shift and invert iterations. -* `ritzvec`: Returns the Ritz vectors `v` (eigenvectors) if `true` -* `v0`: starting vector from which to start the iterations - -We can see the various keywords in action in the following examples: -```jldoctest; filter = r"(1|2)-element Array{(Float64|Complex{Float64}),1}:\n (.|\s)*$" -julia> A = Diagonal(1:4); - -julia> λ, ϕ = eigs(A, nev = 2, which=:SM); - -julia> λ -2-element Array{Float64,1}: - 1.0000000000000002 - 2.0 - -julia> B = Diagonal([1., 2., -3im, 4im]); - -julia> λ, ϕ = eigs(B, nev=1, which=:LI); - -julia> λ -1-element Array{Complex{Float64},1}: - 1.3322676295501878e-15 + 4.0im - -julia> λ, ϕ = eigs(B, nev=1, which=:SI); - -julia> λ -1-element Array{Complex{Float64},1}: - -2.498001805406602e-16 - 3.0000000000000018im - -julia> λ, ϕ = eigs(B, nev=1, which=:LR); - -julia> λ -1-element Array{Complex{Float64},1}: - 2.0000000000000004 + 4.0615212488780827e-17im - -julia> λ, ϕ = eigs(B, nev=1, which=:SR); - -julia> λ -1-element Array{Complex{Float64},1}: - -8.881784197001252e-16 + 3.999999999999997im - -julia> λ, ϕ = eigs(B, nev=1, sigma=1.5); - -julia> λ -1-element Array{Complex{Float64},1}: - 1.0000000000000004 + 4.0417078924070745e-18im -``` - -!!! note - The `sigma` and `which` keywords interact: the description of eigenvalues - searched for by `which` do *not* necessarily refer to the eigenvalues of - `A`, but rather the linear operator constructed by the specification of the - iteration mode implied by `sigma`. - - | `sigma` | iteration mode | `which` refers to eigenvalues of | - |:----------------|:---------------------------------|:---------------------------------| - | `nothing` | ordinary (forward) | ``A`` | - | real or complex | inverse with level shift `sigma` | ``(A - \\sigma I )^{-1}`` | - -!!! note - Although `tol` has a default value, the best choice depends strongly on the - matrix `A`. We recommend that users _always_ specify a value for `tol` - which suits their specific needs. - - For details of how the errors in the computed eigenvalues are estimated, see: - - * B. N. Parlett, "The Symmetric Eigenvalue Problem", SIAM: Philadelphia, 2/e - (1998), Ch. 13.2, "Accessing Accuracy in Lanczos Problems", pp. 290-292 ff. - * R. B. Lehoucq and D. C. Sorensen, "Deflation Techniques for an Implicitly - Restarted Arnoldi Iteration", SIAM Journal on Matrix Analysis and - Applications (1996), 17(4), 789–821. doi:10.1137/S0895479895281484 - -For the two-input generalized eigensolution version, - -`eigs(A, B; nev=6, ncv=max(20,2*nev+1), which=:LM, tol=0.0, maxiter=300, sigma=nothing, ritzvec=true, v0=zeros((0,))) -> (d,[v,],nconv,niter,nmult,resid)` - -the following keyword arguments are supported: - -* `nev`: Number of eigenvalues -* `ncv`: Number of Krylov vectors used in the computation; should satisfy `nev+1 <= ncv <= n` - for real symmetric problems and `nev+2 <= ncv <= n` for other problems, where `n` is the - size of the input matrices `A` and `B`. The default is `ncv = max(20,2*nev+1)`. Note that - these restrictions limit the input matrix `A` to be of dimension at least 2. -* `which`: type of eigenvalues to compute. See the note below. - -| `which` | type of eigenvalues | -|:--------|:--------------------------------------------------------------------------------------------------------------------------| -| `:LM` | eigenvalues of largest magnitude (default) | -| `:SM` | eigenvalues of smallest magnitude | -| `:LR` | eigenvalues of largest real part | -| `:SR` | eigenvalues of smallest real part | -| `:LI` | eigenvalues of largest imaginary part (nonsymmetric or complex `A` only) | -| `:SI` | eigenvalues of smallest imaginary part (nonsymmetric or complex `A` only) | -| `:BE` | compute half of the eigenvalues from each end of the spectrum, biased in favor of the high end. (real symmetric `A` only) | - -* `tol`: relative tolerance used in the convergence criterion for eigenvalues, similar to - `tol` in the [`eigs(A)`](@ref) method for the ordinary eigenvalue - problem, but effectively for the eigenvalues of ``B^{-1} A`` instead of ``A``. - See the documentation for the ordinary eigenvalue problem in - [`eigs(A)`](@ref) and the accompanying note about `tol`. -* `maxiter`: Maximum number of iterations (default = 300) -* `sigma`: Specifies the level shift used in inverse iteration. If `nothing` (default), - defaults to ordinary (forward) iterations. Otherwise, find eigenvalues close to `sigma` - using shift and invert iterations. -* `ritzvec`: Returns the Ritz vectors `v` (eigenvectors) if `true` -* `v0`: starting vector from which to start the iterations - -`eigs` returns the `nev` requested eigenvalues in `d`, the corresponding Ritz vectors `v` -(only if `ritzvec=true`), the number of converged eigenvalues `nconv`, the number of -iterations `niter` and the number of matrix vector multiplications `nmult`, as well as the -final residual vector `resid`. - -We can see the various keywords in action in the following examples: -```jldoctest; filter = r"(1|2)-element Array{(Float64|Complex{Float64}),1}:\n (.|\s)*$" -julia> A = sparse(1.0I, 4, 4); B = Diagonal(1:4); - -julia> λ, ϕ = eigs(A, B, nev = 2); - -julia> λ -2-element Array{Float64,1}: - 1.0000000000000002 - 0.5 - -julia> A = Diagonal([1, -2im, 3, 4im]); B = sparse(1.0I, 4, 4); - -julia> λ, ϕ = eigs(A, B, nev=1, which=:SI); - -julia> λ -1-element Array{Complex{Float64},1}: - -1.5720931501039814e-16 - 1.9999999999999984im - -julia> λ, ϕ = eigs(A, B, nev=1, which=:LI); - -julia> λ -1-element Array{Complex{Float64},1}: - 0.0 + 4.000000000000002im -``` - -!!! note - The `sigma` and `which` keywords interact: the description of eigenvalues searched for by - `which` do *not* necessarily refer to the eigenvalue problem ``Av = Bv\\lambda``, but rather - the linear operator constructed by the specification of the iteration mode implied by `sigma`. - - | `sigma` | iteration mode | `which` refers to the problem | - |:----------------|:---------------------------------|:-----------------------------------| - | `nothing` | ordinary (forward) | ``Av = Bv\\lambda`` | - | real or complex | inverse with level shift `sigma` | ``(A - \\sigma B )^{-1}B = v\\nu`` | - - -```@docs -IterativeEigensolvers.eigs(::Any) -IterativeEigensolvers.eigs(::Any, ::Any) -IterativeEigensolvers.svds -``` - -```@meta -DocTestSetup = nothing -``` diff --git a/codex/stdlib/LibGit2.md b/codex/stdlib/LibGit2.md index 48af940..421540d 100644 --- a/codex/stdlib/LibGit2.md +++ b/codex/stdlib/LibGit2.md @@ -137,6 +137,7 @@ LibGit2.revcount LibGit2.set_remote_url LibGit2.shortname LibGit2.snapshot +LibGit2.split_cfg_entry LibGit2.status LibGit2.stage LibGit2.tag_create diff --git a/codex/stdlib/LinearAlgebra.md b/codex/stdlib/LinearAlgebra.md index 3b3d6c9..6e7d122 100644 --- a/codex/stdlib/LinearAlgebra.md +++ b/codex/stdlib/LinearAlgebra.md @@ -299,7 +299,6 @@ Linear algebra functions in Julia are largely implemented by calling functions f Base.:*(::AbstractMatrix, ::AbstractMatrix) Base.:\(::AbstractMatrix, ::AbstractVecOrMat) LinearAlgebra.dot -LinearAlgebra.vecdot LinearAlgebra.cross LinearAlgebra.factorize LinearAlgebra.Diagonal @@ -358,7 +357,7 @@ LinearAlgebra.diag LinearAlgebra.diagm LinearAlgebra.rank LinearAlgebra.norm -LinearAlgebra.vecnorm +LinearAlgebra.opnorm LinearAlgebra.normalize! LinearAlgebra.normalize LinearAlgebra.cond diff --git a/codex/stdlib/Pkg.md b/codex/stdlib/Pkg.md index a6bb9ba..f84fc76 100644 --- a/codex/stdlib/Pkg.md +++ b/codex/stdlib/Pkg.md @@ -58,7 +58,7 @@ official release again. **Project:** a source tree with a standard layout, including a `src` directory for the main body of Julia code, a `test` directory for testing the project, -`docs` for documentation files, and optionally a `build` directory for a build +`docs` for documentation files, and optionally a `deps` directory for a build script and its outputs. A project will typically also have a project file and may optionally have a manifest file: @@ -172,7 +172,7 @@ which is populated at startup based on the value of the `JULIA_DEPOT_PATH` environment variable. The first entry is the “user depot” and should be writable by and owned by the current user. The user depot is where: registries are cloned, new package versions are installed, named environments are created and -updated, package repos are cloned, new compiled package image files are saved, +updated, package repos are cloned, newly compiled package image files are saved, log files are written, development packages are checked out by default, and global configuration data is saved. Later entries in the depot path are treated as read-only and are appropriate for registries, packages, etc. installed and @@ -193,7 +193,317 @@ Since we haven't created our own project yet, we are in the default project, loc To return to the `julia>` prompt, either press backspace when the input line is empty or press Ctrl+C. Help is available by calling `pkg> help`. -To generate files for a new project, use `pkg> generate`. +The documentation here describes using Pkg from the REPL mode. Documentation of using +the Pkg API (by calling `Pkg.` functions) is in progress of being written. + +### Adding packages + +There are two ways of adding packages, either using the `add` command or the `dev` command. +The most frequently used one is `add` and its usage is described first. + +#### Adding registered packages + +In the Pkg REPL packages can be added with the `add` command followed by the name of the package, for example: + +``` +(v0.7) pkg> add Example + Cloning default registries into /Users/kristoffer/.julia/registries + Cloning registry Uncurated from "https://github.com/JuliaRegistries/Uncurated.git" + Updating registry at `~/.julia/registries/Uncurated` + Updating git-repo `https://github.com/JuliaRegistries/Uncurated.git` + Resolving package versions... + Updating `~/.julia/environments/v0.7/Project.toml` + [7876af07] + Example v0.5.1 + Updating `~/.julia/environments/v0.7/Manifest.toml` + [7876af07] + Example v0.5.1 + [8dfed614] + Test +``` + +Here we added the package Example to the current project. In this example, we are using a fresh Julia installation, +and this is our first time adding a package using Pkg. By default, Pkg clones Julia's Uncurated registry, +and uses this registry to look up packages requested for inclusion in the current environment. +The status update shows a short form of the package UUID to the left, then the package name, and the version. +Since standard libraries (e.g. `Test`) are shipped with Julia, they do not have a version. The project status contains the packages +you have added yourself, in this case, `Example`: + +``` +(v0.7) pkg> st + Status `Project.toml` + [7876af07] Example v0.5.1 +``` + +The manifest status, in addition, includes the dependencies of explicitly added packages. + +``` +(v0.7) pkg> st --manifest + Status `Manifest.toml` + [7876af07] Example v0.5.1 + [8dfed614] Test +``` + +It is possible to add multiple packages in one command as `pkg> add A B C`. + +After a package is added to the project, it can be loaded in Julia: + +``` +julia> using Example + +julia> Example.hello("User") +"Hello, User" +``` + +A specific version can be installed by appending a version after a `@` symbol, e.g. `@v0.4`, to the package name: + +``` +(v0.7) pkg> add Example@0.4 + Resolving package versions... + Updating `~/.julia/environments/v0.7/Project.toml` + [7876af07] + Example v0.4.1 + Updating `~/.julia/environments/v0.7/Manifest.toml` + [7876af07] + Example v0.4.1 +``` + +If the master branch (or a certain commit SHA) of `Example` has a hotfix that has not yet included in a registered version, +we can explicitly track a branch (or commit) by appending `#branch` (or `#commit`) to the package name: + +``` +(v0.7) pkg> add Example#master + Updating git-repo `https://github.com/JuliaLang/Example.jl.git` + Resolving package versions... + Updating `~/.julia/environments/v0.7/Project.toml` + [7876af07] ~ Example v0.5.1 ⇒ v0.5.1+ #master [https://github.com/JuliaLang/Example.jl.git] + Updating `~/.julia/environments/v0.7/Manifest.toml` + [7876af07] ~ Example v0.5.1 ⇒ v0.5.1+ #master [https://github.com/JuliaLang/Example.jl.git] +``` + +The status output now shows that we are tracking the `master` branch of `Example`. +When updating packages, we will pull updates from that branch. + +To go back to tracking the registry version of `Example`, the command `free` is used: + +``` +(v0.7) pkg> free Example + Resolving package versions... + Updating `~/.julia/environments/v0.7/Project.toml` + [7876af07] ~ Example v0.5.1+ #master [https://github.com/JuliaLang/Example.jl.git] ⇒ v0.5.1 + Updating `~/.julia/environments/v0.7/Manifest.toml` + [7876af07] ~ Example v0.5.1+ #master [https://github.com/JuliaLang/Example.jl.git] ⇒ v0.5.1 +``` + + +#### Adding unregistered packages + +If a package is not in a registry, it can still be added by instead of the package name giving the URL to the repository to `add`. + +``` +(v0.7) pkg> add https://github.com/fredrikekre/ImportMacros.jl + Updating git-repo `https://github.com/fredrikekre/ImportMacros.jl` + Resolving package versions... +Downloaded MacroTools ─ v0.4.1 + Updating `~/.julia/environments/v0.7/Project.toml` + [e6797606] + ImportMacros v0.0.0 # [https://github.com/fredrikekre/ImportMacros.jl] + Updating `~/.julia/environments/v0.7/Manifest.toml` + [e6797606] + ImportMacros v0.0.0 # [https://github.com/fredrikekre/ImportMacros.jl] + [1914dd2f] + MacroTools v0.4.1 +``` + +The dependencies of the unregistered package (here `MacroTools`) got installed. +For unregistered packages we could have given a branch (or commit SHA) to track using `#`, just like for registered packages. + + +#### Adding a local package + +Instead of giving a URL of a git repo to `add` we could instead have given a local path to a git repo. +This works similarly to adding a URL. The local repository will be tracked (at some branch) and updates +from that local repo are pulled when packages are updated. +Note that changes to files in the local package repository will not immediately be reflected when loading that package. +The changes would have to be committed and the packages updated in order to pull in the changes. + +#### Developing packages + +By only using `add` your Manifest will always have a "reproducible state", in other words, as long as the repositories and registries used are still accessible +it is possible to retrieve the exact state of all the dependencies in the project. This has the advantage that you can send your project (`Project.toml` +and `Manifest.toml`) to someone else and they can "instantiate" that project in the same state as you had it locally. +However, when you are developing a package, it is more convenient to load packages at their current state at some path. For this reason, the `dev` command exists. + +Let's try to `dev` a registered package: + +``` +(v0.7) pkg> dev Example + Updating git-repo `https://github.com/JuliaLang/Example.jl.git` + Resolving package versions... + Updating `~/.julia/environments/v0.7/Project.toml` + [7876af07] + Example v0.5.1+ [`~/.julia/dev/Example`] + Updating `~/.julia/environments/v0.7/Manifest.toml` + [7876af07] + Example v0.5.1+ [`~/.julia/dev/Example`] +``` + +The `dev` command fetches a full clone of the package to `~/.julia/dev/` (the path can be changed by setting the environment variable `JULIA_PKG_DEVDIR`). +When importing `Example` julia will now import it from `~/.julia/dev/Example` and whatever local changes have been made to the files in that path are consequently +reflected in the code loaded. When we used `add` we said that we tracked the package repository, we here say that we track the path itself. +Note that the package manager will never touch any of the files at a tracked path. It is therefore up to you to pull updates, change branches etc. +If we try to `dev` a package at some branch that already exists at `~/.julia/dev/` the package manager we will simply use the existing path. +For example: + +``` +(v0.7) pkg> dev Example#master + Updating git-repo `https://github.com/JuliaLang/Example.jl.git` +[ Info: Path `/Users/kristoffer/.julia/dev/Example` exists and looks like the correct package, using existing path instead of cloning +``` + +Note the info message saying that it is using the existing path. This means that you cannot use `dev` to e.g. change branches of +an already developed package. + +If `dev` is used on a local path, that path to that package is recorded and used when loading that package. + +To stop tracking a path and use the registered version again, use `free` + +``` +(v0.7) pkg> free Example + Resolving package versions... + Updating `~/.julia/environments/v0.7/Project.toml` + [7876af07] ↓ Example v0.5.1+ [`~/.julia/dev/Example`] ⇒ v0.5.1 + Updating `~/.julia/environments/v0.7/Manifest.toml` + [7876af07] ↓ Example v0.5.1+ [`~/.julia/dev/Example`] ⇒ v0.5.1 +``` + +It should be pointed out that by using `dev` your project is now inherently stateful. +Its state depends on the current content of the files at the path and the manifest cannot be "instantiated" by someone else without +knowing the exact content of all the packages that are tracking a path. + +Note that if you add a dependency to a package that tracks a local path, the Manifest (which contains the whole dependency graph) will become +out of sync with the actual dependency graph. This means that the package will not be able to load that dependency since it is not recorded +in the Manifest. To update sync the Manifest, use the REPL command `resolve`. + +### Removing packages + +Packages can be removed from the current project by using `pkg> rm Package`. +This will only remove packages that exist in the project, to remove a package that only +exists as a dependency use `pkg> rm --manifest DepPackage`. +Note that this will remove all packages that depends on `DepPackage`. + +### Updating packages + +When new versions of packages the project is using are released, it is a good idea to update. Simply calling `up` will try to update *all* the dependencies of the project +to the latest compatible version. Sometimes this is not what you want. You can specify a subset of the dependencies to upgrade by giving them as arguments to `up`, e.g: + +``` +(v0.7) pkg> up Example +``` + +The version of all other packages direct dependencies will stay the same. If you only want to update the minor version of packages, to reduce the risk that your project breaks, you can give the `--minor` flag, e.g: + +``` +(v0.7) pkg> up --minor Example +``` + +Packages that track a repository are not updated when a minor upgrade is done. +Packages that track a path are never touched by the package manager. + +### Pinning a package + +A pinned package will never be updated. A package can be pinned using `pin` as for example + +``` +(v0.7) pkg> pin Example + Resolving package versions... + Updating `~/.julia/environments/v0.7/Project.toml` + [7876af07] ~ Example v0.5.1 ⇒ v0.5.1 ⚲ + Updating `~/.julia/environments/v0.7/Manifest.toml` + [7876af07] ~ Example v0.5.1 ⇒ v0.5.1 ⚲ +``` + +Note the pin symbol `⚲` showing that the package is pinned. Removing the pin is done using `free` + +``` +(v0.7) pkg> free Example + Updating `~/.julia/environments/v0.7/Project.toml` + [7876af07] ~ Example v0.5.1 ⚲ ⇒ v0.5.1 + Updating `~/.julia/environments/v0.7/Manifest.toml` + [7876af07] ~ Example v0.5.1 ⚲ ⇒ v0.5.1 +``` + +### Testing packages + +The tests for a package can be run using `test`command: + +``` +(v0.7) pkg> test Example + Testing Example + Testing Example tests passed +``` + +### Building packages + +The build step of a package is automatically run when a package is first installed. +The output of the build process is directed to a file. +To explicitly run the build step for a package the `build` command is used: + +``` +(v0.7) pkg> build MbedTLS + Building MbedTLS → `~/.julia/packages/MbedTLS/h1Vu/deps/build.log` + +shell> cat ~/.julia/packages/MbedTLS/h1Vu/deps/build.log +┌ Warning: `wait(t::Task)` is deprecated, use `fetch(t)` instead. +│ caller = macro expansion at OutputCollector.jl:63 [inlined] +└ @ Core OutputCollector.jl:63 +... +[ Info: using prebuilt binaries +``` + +## Creating your own projects + +So far we have added packages to the default project at `~/.julia/environments/v0.7`, it is, however, easy to create other, independent, projects. +It should be pointed out if two projects uses the same package at the same version, the content of this package is not duplicated. +This is done using the `init` command. Below we make a new directory and create a new project in it: + +``` +shell> mkdir MyProject + +shell> cd MyProject +/Users/kristoffer/MyProject + +(v0.7) pkg> init +Initialized project at /Users/kristoffer/MyProject/Project.toml + +(MyProject) pkg> st + Status `Project.toml` +``` + +Note that the REPL prompt changed when the new project was initiated. Since this is a newly created project, the status command show it contains no packages. +Packages added here again in a completely separate environment from the one earlier used. + +## Garbage collecting old, unused packages + +As packages are updated and projects are deleted, installed packages that were once used will inevitably +become old and not used from any existing project. +Pkg keeps a log of all projects used so it can go through the log and see exactly which projects still exist +and what packages those projects used. The rest can be deleted. +This is done with the `gc` command: + +``` +(v0.7) pkg> gc + Active manifests at: + `/Users/kristoffer/BinaryProvider/Manifest.toml` + ... + `/Users/kristoffer/Compat.jl/Manifest.toml` + Deleted /Users/kristoffer/.julia/packages/BenchmarkTools/1cAj: 146.302 KiB + Deleted /Users/kristoffer/.julia/packages/Cassette/BXVB: 795.557 KiB + ... + Deleted /Users/kristoffer/.julia/packages/WeakRefStrings/YrK6: 27.328 KiB + Deleted 36 package installations: 113.205 MiB +``` + +Note that only packages in `~/.julia/packages` are deleted. + +## Creating your own packages + +A package is a project with a `name`, `uuid` and `version` entry in the `Project.toml` file `src/PackageName.jl` file that defines the module `PackageName`. +This file is executed when the package is loaded. + +### Generating files for a package + +To generate files for a new package, use `pkg> generate`. ``` (v0.7) pkg> generate HelloWorld @@ -242,7 +552,7 @@ julia> HelloWorld.greet() Hello World! ``` -### Adding packages to the project +### Adding dependencies to the project Let’s say we want to use the standard library package `Random` and the registered package `JSON` in our project. We simply `add` these packages (note how the prompt now shows the name of the newly generated project, @@ -285,130 +595,90 @@ julia> HelloWorld.greet_alien() Hello aT157rHV ``` -Sometimes we might want to use the very latest, unreleased version of a package, or perhaps a specific branch in the package -git repository. We can use e.g. the `master` branch of `JSON` by specifying the branch after a `#` when adding the package: +### Adding a build step to the package. -``` -(HelloWorld) pkg> add JSON#master - Cloning package from https://github.com/JuliaIO/JSON.jl.git - Resolving package versions... - Updating "~/Documents/HelloWorld/Project.toml" - [682c06a0] ~ JSON v0.17.1 ⇒ v0.17.1+ #master - Updating "~/Documents/HelloWorld/Manifest.toml" - [682c06a0] ~ JSON v0.17.1 ⇒ v0.17.1+ #master -``` - -If we want to use a package that has not been registered in a registry, we can `add` its git repository url: +The build step is executed the first time a package is installed or when explicitly invoked with `build`. +A package is built by executing the file `deps/build.jl`. ``` -(HelloWorld) pkg> add https://github.com/fredrikekre/ImportMacros.jl - Cloning package from https://github.com/fredrikekre/ImportMacros.jl - Resolving package versions... -Downloaded MacroTools ─ v0.4.0 - Updating "~/Documents/HelloWorld/Project.toml" - [5adcef86] + ImportMacros v0.1.0 #master - Updating "~/Documents/HelloWorld/Manifest.toml" - [5adcef86] + ImportMacros v0.1.0 #master - [1914dd2f] + MacroTools v0.4.0 -``` - -The dependencies of the unregistered package (here `MacroTools`) got installed. -For unregistered packages we could have given a branch (or commit SHA) to track using `#`, just like for registered packages. - - -## Developing packages +shell> cat deps/build.log +I am being built... -Let’s say we found a bug in one of our dependencies, e.g. `JSON` that we want to fix. We can get the full git-repo using the `develop` command - -``` -(HelloWorld) pkg> develop JSON - Cloning package from https://github.com/JuliaIO/JSON.jl.git - Resolving package versions... - Updating "~/Documents/HelloWorld/Project.toml" - [682c06a0] + JSON v0.17.1+ [~/.julia/dev/JSON] -... -``` - -By default, the package gets cloned to the `~/.julia/dev` folder but can also be set by the `JULIA_PKG_DEVDIR` environment variable. -When we have fixed the bug and checked that `JSON` now works correctly with our project, we can make a PR to the `JSON` repository. -When the PR has been merged we can go over to track the master branch and finally when a new release of `JSON` is made, we can go back to using the versioned `JSON` using the command `free` and `update` (see next section): - -``` -(HelloWorld) pkg> free JSON +(HelloWorld) pkg> build + Building HelloWorld → `deps/build.log` Resolving package versions... - Updating "~/Documents/HelloWorld/Project.toml" - [682c06a0] ~ JSON v0.17.1+ #master ⇒ v0.17.1 - Updating "~/Documents/HelloWorld/Manifest.toml" - [682c06a0] ~ JSON v0.17.1+ #master ⇒ v0.17.1 -``` - -It is also possible to give a local path as the argument to `develop` which will not clone anything but simply use that directory for the package. - -Overriding the dependency path for a non-registered package is done by giving the git-repo url as an argument to `develop`. - -## Updating dependencies - -When new versions of packages the project is using are released, it is a good idea to update. Simply calling `up` will try to update *all* the dependencies of the project. Sometimes this is not what you want. You can specify a subset of the dependencies to upgrade by giving them as arguments to `up`, e.g: -``` -(HelloWorld) pkg> up JSON +shell> cat deps/build.log +I am being built... ``` -The version of all other direct dependencies will stay the same. If you only want to update the minor version of packages, to reduce the risk that your project breaks, you can give the `--minor` flag, e.g: +If the build step fails, the output of the build step is printed to the console ``` -(HelloWorld) pkg> up --minor JSON -``` - -Packages that track a branch are not updated when a minor upgrade is done. -Developed packages are never touched by the package manager. - -If you just want to install the packages that are given by the current `Manifest.toml` use +shell> cat deps/build.jl +error("Ooops") -``` -(HelloWorld) pkg> instantiate +(HelloWorld) pkg> build + Building HelloWorld → `deps/build.log` + Resolving package versions... +┌ Error: Error building `HelloWorld`: +│ ERROR: LoadError: Ooops +│ Stacktrace: +│ [1] error(::String) at ./error.jl:33 +│ [2] top-level scope at none:0 +│ [3] include at ./boot.jl:317 [inlined] +│ [4] include_relative(::Module, ::String) at ./loading.jl:1071 +│ [5] include(::Module, ::String) at ./sysimg.jl:29 +│ [6] include(::String) at ./client.jl:393 +│ [7] top-level scope at none:0 +│ in expression starting at /Users/kristoffer/.julia/dev/Pkg/HelloWorld/deps/build.jl:1 +└ @ Pkg.Operations Operations.jl:938 ``` -## Precompiling the project +### Adding tests to the package -The REPL command `precompile` can be used to precompile all the dependencies in the project. You can for example do +When a package is tested the file `test/runtests.jl` is executed. ``` -(HelloWorld) pkg> update; precompile +shell> cat test/runtests.jl +println("Testing...") +(HelloWorld) pkg> test + Testing HelloWorld + Resolving package versions... +Testing... + Testing HelloWorld tests passed ``` -do update the dependencies and then precompile them. - -## Preview mode +#### Test-specific dependencies -If you just want to see the effects of running a command, but not change your state you can `preview` a command. -For example: +Sometimes one might to want to use some packages only at testing time but not enforce a dependency on them when the package is used. +This is possible by adding dependencies to a "test target" to the Project file. Here we add the `Test` standard library as a +test-only dependency by adding the following to the Project file: ``` -(HelloWorld) pkg> preview add Plots +[target.test.deps] +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" ``` -or +We can now use `Test` in the test script and we can see that it gets installed on testing: ``` -(HelloWorld) pkg> preview up -``` - -will show you the effects of adding `Plots`, or doing a full upgrade, respectively, would have on your project. -However, nothing would be installed and your `Project.toml` and `Manfiest.toml` are untouched. +shell> cat test/runtests.jl +using Test +@test 1 == 1 -## Using someone else's project - -Simple clone their project using e.g. `git clone`, `cd` to the project directory and call - -``` -(SomeProject) pkg> instantiate +(HelloWorld) pkg> test + Testing HelloWorld + Resolving package versions... + Updating `/var/folders/64/76tk_g152sg6c6t0b4nkn1vw0000gn/T/tmpPzUPPw/Project.toml` + [d8327f2a] + HelloWorld v0.1.0 [`~/.julia/dev/Pkg/HelloWorld`] + [8dfed614] + Test + Updating `/var/folders/64/76tk_g152sg6c6t0b4nkn1vw0000gn/T/tmpPzUPPw/Manifest.toml` + [d8327f2a] + HelloWorld v0.1.0 [`~/.julia/dev/Pkg/HelloWorld`] + Testing HelloWorld tests passed``` ``` -If the project contains a manifest, this will install the packages in the same state that is given by that manifest. -Otherwise, it will resolve the latest versions of the dependencies compatible with the project. - -## Compatibility +### Compatibility Compatibility refers to the ability to restrict what version of the dependencies that your project is compatible with. If the compatibility for a dependency is not given, the project is assumed to be compatible with all versions of that dependency. @@ -427,14 +697,14 @@ The format of the version specifier is described in detail below. !!! info There is currently no way to give compatibility from the Pkg REPL mode so for now, one has to manually edit the project file. -### Version specifier format +#### Version specifier format Similar to other package managers, the Julia package manager respects [semantic versioning](https://semver.org/) (semver). As an example, a version specifier is given as e.g. `1.2.3` is therefore assumed to be compatible with the versions `[1.2.3 - 2.0.0)` where `)` is a non-inclusive upper bound. More specifically, a version specifier is either given as a **caret specifier**, e.g. `^1.2.3` or a **tilde specifier** `~1.2.3`. Caret specifiers are the default and hence `1.2.3 == ^1.2.3`. The difference between a caret and tilde is described in the next section. -#### Caret specifiers +##### Caret specifiers A caret specifier allows upgrade that would be compatible according to semver. An updated dependency is considered compatible if the new version does not modify the left-most non zero digit in the version specifier. @@ -454,7 +724,7 @@ Some examples are shown below. While the semver specification says that all versions with a major version of 0 are incompatible with each other, we have made that choice that a version given as `0.a.b` is considered compatible with `0.a.c` if `a != 0` and `c >= b`. -#### Tilde specifiers +##### Tilde specifiers A tilde specifier provides more limited upgrade possibilities. With a tilde, only the last specified digit is allowed to increment by one. This gives the following example. @@ -464,3 +734,43 @@ This gives the following example. ~1.2 = [1.2.0, 1.3.0) ~1 = [1.0.0, 2.0.0) ``` + + +## Precompiling a project + +The REPL command `precompile` can be used to precompile all the dependencies in the project. You can for example do + +``` +(HelloWorld) pkg> update; precompile +``` + +do update the dependencies and then precompile them. + +## Preview mode + +If you just want to see the effects of running a command, but not change your state you can `preview` a command. +For example: + +``` +(HelloWorld) pkg> preview add Plots +``` + +or + +``` +(HelloWorld) pkg> preview up +``` + +will show you the effects of adding `Plots`, or doing a full upgrade, respectively, would have on your project. +However, nothing would be installed and your `Project.toml` and `Manifest.toml` are untouched. + +## Using someone else's project + +Simple clone their project using e.g. `git clone`, `cd` to the project directory and call + +``` +(SomeProject) pkg> instantiate +``` + +If the project contains a manifest, this will install the packages in the same state that is given by that manifest. +Otherwise, it will resolve the latest versions of the dependencies compatible with the project. diff --git a/codex/stdlib/iterativeeigensolvers.md b/codex/stdlib/iterativeeigensolvers.md deleted file mode 100644 index 185d2dc..0000000 --- a/codex/stdlib/iterativeeigensolvers.md +++ /dev/null @@ -1,208 +0,0 @@ -# [Iterative Eigensolvers](@id lib-itereigen) - -```@meta -DocTestSetup = :(using IterativeEigensolvers, LinearAlgebra, SparseArrays) -``` - -Julia provides bindings to [ARPACK](http://www.caam.rice.edu/software/ARPACK/), which -can be used to perform iterative solutions for eigensystems (using [`eigs`](@ref)) -or singular value decompositions (using [`svds`](@ref)). - -`eigs` calculates the eigenvalues and, optionally, eigenvectors of its input(s) -using implicitly restarted Lanczos or Arnoldi iterations for real symmetric or -general nonsymmetric matrices respectively. - -For the single matrix version, - -`eigs(A; nev=6, ncv=max(20,2*nev+1), which=:LM, tol=0.0, maxiter=300, sigma=nothing, ritzvec=true, v0=zeros((0,))) -> (d,[v,],nconv,niter,nmult,resid)` - -the following keyword arguments are supported: - -* `nev`: Number of eigenvalues -* `ncv`: Number of Krylov vectors used in the computation; should satisfy `nev+1 <= ncv <= n` - for real symmetric problems and `nev+2 <= ncv <= n` for other problems, where `n` is the - size of the input matrix `A`. The default is `ncv = max(20,2*nev+1)`. Note that these - restrictions limit the input matrix `A` to be of dimension at least 2. -* `which`: type of eigenvalues to compute. See the note below. - -| `which` | type of eigenvalues | -|:--------|:--------------------------------------------------------------------------------------------------------------------------| -| `:LM` | eigenvalues of largest magnitude (default) | -| `:SM` | eigenvalues of smallest magnitude | -| `:LR` | eigenvalues of largest real part | -| `:SR` | eigenvalues of smallest real part | -| `:LI` | eigenvalues of largest imaginary part (nonsymmetric or complex `A` only) | -| `:SI` | eigenvalues of smallest imaginary part (nonsymmetric or complex `A` only) | -| `:BE` | compute half of the eigenvalues from each end of the spectrum, biased in favor of the high end. (real symmetric `A` only) | - -* `tol`: parameter defining the relative tolerance for convergence of Ritz values (eigenvalue estimates). - A Ritz value ``θ`` is considered converged when its associated residual - is less than or equal to the product of `tol` and ``max(ɛ^{2/3}, |θ|)``, - where `ɛ = eps(real(eltype(A)))/2` is LAPACK's machine epsilon. - The residual associated with ``θ`` and its corresponding Ritz vector ``v`` - is defined as the norm ``||Av - vθ||``. - The specified value of `tol` should be positive; otherwise, it is ignored - and ``ɛ`` is used instead. - Default: ``ɛ``. - -* `maxiter`: Maximum number of iterations (default = 300) -* `sigma`: Specifies the level shift used in inverse iteration. If `nothing` (default), - defaults to ordinary (forward) iterations. Otherwise, find eigenvalues close to `sigma` - using shift and invert iterations. -* `ritzvec`: Returns the Ritz vectors `v` (eigenvectors) if `true` -* `v0`: starting vector from which to start the iterations - -We can see the various keywords in action in the following examples: -```jldoctest; filter = r"(1|2)-element Array{(Float64|Complex{Float64}),1}:\n (.|\s)*$" -julia> A = Diagonal(1:4); - -julia> λ, ϕ = eigs(A, nev = 2, which=:SM); - -julia> λ -2-element Array{Float64,1}: - 1.0000000000000002 - 2.0 - -julia> B = Diagonal([1., 2., -3im, 4im]); - -julia> λ, ϕ = eigs(B, nev=1, which=:LI); - -julia> λ -1-element Array{Complex{Float64},1}: - 1.3322676295501878e-15 + 4.0im - -julia> λ, ϕ = eigs(B, nev=1, which=:SI); - -julia> λ -1-element Array{Complex{Float64},1}: - -2.498001805406602e-16 - 3.0000000000000018im - -julia> λ, ϕ = eigs(B, nev=1, which=:LR); - -julia> λ -1-element Array{Complex{Float64},1}: - 2.0000000000000004 + 4.0615212488780827e-17im - -julia> λ, ϕ = eigs(B, nev=1, which=:SR); - -julia> λ -1-element Array{Complex{Float64},1}: - -8.881784197001252e-16 + 3.999999999999997im - -julia> λ, ϕ = eigs(B, nev=1, sigma=1.5); - -julia> λ -1-element Array{Complex{Float64},1}: - 1.0000000000000004 + 4.0417078924070745e-18im -``` - -!!! note - The `sigma` and `which` keywords interact: the description of eigenvalues - searched for by `which` do *not* necessarily refer to the eigenvalues of - `A`, but rather the linear operator constructed by the specification of the - iteration mode implied by `sigma`. - - | `sigma` | iteration mode | `which` refers to eigenvalues of | - |:----------------|:---------------------------------|:---------------------------------| - | `nothing` | ordinary (forward) | ``A`` | - | real or complex | inverse with level shift `sigma` | ``(A - \\sigma I )^{-1}`` | - -!!! note - Although `tol` has a default value, the best choice depends strongly on the - matrix `A`. We recommend that users _always_ specify a value for `tol` - which suits their specific needs. - - For details of how the errors in the computed eigenvalues are estimated, see: - - * B. N. Parlett, "The Symmetric Eigenvalue Problem", SIAM: Philadelphia, 2/e - (1998), Ch. 13.2, "Accessing Accuracy in Lanczos Problems", pp. 290-292 ff. - * R. B. Lehoucq and D. C. Sorensen, "Deflation Techniques for an Implicitly - Restarted Arnoldi Iteration", SIAM Journal on Matrix Analysis and - Applications (1996), 17(4), 789–821. doi:10.1137/S0895479895281484 - -For the two-input generalized eigensolution version, - -`eigs(A, B; nev=6, ncv=max(20,2*nev+1), which=:LM, tol=0.0, maxiter=300, sigma=nothing, ritzvec=true, v0=zeros((0,))) -> (d,[v,],nconv,niter,nmult,resid)` - -the following keyword arguments are supported: - -* `nev`: Number of eigenvalues -* `ncv`: Number of Krylov vectors used in the computation; should satisfy `nev+1 <= ncv <= n` - for real symmetric problems and `nev+2 <= ncv <= n` for other problems, where `n` is the - size of the input matrices `A` and `B`. The default is `ncv = max(20,2*nev+1)`. Note that - these restrictions limit the input matrix `A` to be of dimension at least 2. -* `which`: type of eigenvalues to compute. See the note below. - -| `which` | type of eigenvalues | -|:--------|:--------------------------------------------------------------------------------------------------------------------------| -| `:LM` | eigenvalues of largest magnitude (default) | -| `:SM` | eigenvalues of smallest magnitude | -| `:LR` | eigenvalues of largest real part | -| `:SR` | eigenvalues of smallest real part | -| `:LI` | eigenvalues of largest imaginary part (nonsymmetric or complex `A` only) | -| `:SI` | eigenvalues of smallest imaginary part (nonsymmetric or complex `A` only) | -| `:BE` | compute half of the eigenvalues from each end of the spectrum, biased in favor of the high end. (real symmetric `A` only) | - -* `tol`: relative tolerance used in the convergence criterion for eigenvalues, similar to - `tol` in the [`eigs(A)`](@ref) method for the ordinary eigenvalue - problem, but effectively for the eigenvalues of ``B^{-1} A`` instead of ``A``. - See the documentation for the ordinary eigenvalue problem in - [`eigs(A)`](@ref) and the accompanying note about `tol`. -* `maxiter`: Maximum number of iterations (default = 300) -* `sigma`: Specifies the level shift used in inverse iteration. If `nothing` (default), - defaults to ordinary (forward) iterations. Otherwise, find eigenvalues close to `sigma` - using shift and invert iterations. -* `ritzvec`: Returns the Ritz vectors `v` (eigenvectors) if `true` -* `v0`: starting vector from which to start the iterations - -`eigs` returns the `nev` requested eigenvalues in `d`, the corresponding Ritz vectors `v` -(only if `ritzvec=true`), the number of converged eigenvalues `nconv`, the number of -iterations `niter` and the number of matrix vector multiplications `nmult`, as well as the -final residual vector `resid`. - -We can see the various keywords in action in the following examples: -```jldoctest; filter = r"(1|2)-element Array{(Float64|Complex{Float64}),1}:\n (.|\s)*$" -julia> A = sparse(1.0I, 4, 4); B = Diagonal(1:4); - -julia> λ, ϕ = eigs(A, B, nev = 2); - -julia> λ -2-element Array{Float64,1}: - 1.0000000000000002 - 0.5 - -julia> A = Diagonal([1, -2im, 3, 4im]); B = sparse(1.0I, 4, 4); - -julia> λ, ϕ = eigs(A, B, nev=1, which=:SI); - -julia> λ -1-element Array{Complex{Float64},1}: - -1.5720931501039814e-16 - 1.9999999999999984im - -julia> λ, ϕ = eigs(A, B, nev=1, which=:LI); - -julia> λ -1-element Array{Complex{Float64},1}: - 0.0 + 4.000000000000002im -``` - -!!! note - The `sigma` and `which` keywords interact: the description of eigenvalues searched for by - `which` do *not* necessarily refer to the eigenvalue problem ``Av = Bv\\lambda``, but rather - the linear operator constructed by the specification of the iteration mode implied by `sigma`. - - | `sigma` | iteration mode | `which` refers to the problem | - |:----------------|:---------------------------------|:-----------------------------------| - | `nothing` | ordinary (forward) | ``Av = Bv\\lambda`` | - | real or complex | inverse with level shift `sigma` | ``(A - \\sigma B )^{-1}B = v\\nu`` | - - -```@docs -IterativeEigensolvers.eigs(::Any) -IterativeEigensolvers.eigs(::Any, ::Any) -IterativeEigensolvers.svds -``` - -```@meta -DocTestSetup = nothing -``` diff --git a/codex/stdlib/linearalgebra.md b/codex/stdlib/linearalgebra.md index 3b3d6c9..6e7d122 100644 --- a/codex/stdlib/linearalgebra.md +++ b/codex/stdlib/linearalgebra.md @@ -299,7 +299,6 @@ Linear algebra functions in Julia are largely implemented by calling functions f Base.:*(::AbstractMatrix, ::AbstractMatrix) Base.:\(::AbstractMatrix, ::AbstractVecOrMat) LinearAlgebra.dot -LinearAlgebra.vecdot LinearAlgebra.cross LinearAlgebra.factorize LinearAlgebra.Diagonal @@ -358,7 +357,7 @@ LinearAlgebra.diag LinearAlgebra.diagm LinearAlgebra.rank LinearAlgebra.norm -LinearAlgebra.vecnorm +LinearAlgebra.opnorm LinearAlgebra.normalize! LinearAlgebra.normalize LinearAlgebra.cond diff --git a/contrib/build_sysimg.jl b/contrib/build_sysimg.jl index 7b77af8..2d7f13d 100644 --- a/contrib/build_sysimg.jl +++ b/contrib/build_sysimg.jl @@ -139,6 +139,7 @@ function find_system_compiler() if success(`cc -v`) cc = "cc" end + catch end if cc === nothing diff --git a/src/.NEWS.md.swp b/src/.NEWS.md.swp new file mode 100644 index 0000000000000000000000000000000000000000..1ee7cb4c898c94aaecab1627b2894633c57d704b GIT binary patch literal 110592 zcmeFa3z%eAS?@g%5aB4IfVYF6JHxGd(%sYdp6O&lCX)mPCX+CiAcoMpx~saUGSyX` zs_L0(!eD@aNeF%c5(tn4)NnP(2!Rt66pvTbPd|OUpgu<=DoVOXMbGE;9MAXrzwcUm z@9LR>?C|(J;?oUprn_pdwby#rTJQaR*WAc8d#_A(43BK#=V@EEeD9xBu6@C~|9Z=b zXKdMWWTm-W)8}8~$DUhh3|(2BzqH*xI&^iXJ=|>1SDPE!y~ZBgexzQlZSQret!}g0 zs}I%M^V_?f`R)5Jf7!v|rAPC=4c%`3xru>I416sNtn?O!c6{rW@v%`m>d)SKe)9D1 zIQ+F*ZGOLrflUl-Vqg;kn;6){z$OMZF|dh&O$_`e!a#5Nd$#-#^Lc!j(?t09aU1@9 zQuzA?;or#(-+y!XdnWwb+wlF9!{0l@zdyO*`=^AzW50j7;rsux;rnNW0mgBDOZa|A z`1hq7zW>(nd7R&^8@_)+`2NE1?`JlA|HSZloX0Ad>_a6;~T#J_VE4o@b4dQ`2IV>=hNZer<~`%#P>fvd_Erj-M!&^ z%t7`O@z>k%{WHV&asD6N@cnm&?_>X8-0=N(ZTS8fVL{^fzB_y$$N$0&-+xc|ek%O? znhoE7Z}>do_rVR{hv96Acv#=?eQ3V<&n5;oF|dh&O$=;eU=stI7}&(XCI&V!u!(_h zSPWEaTee8&K3|F!N@&#Y{se{fmw;ac9su4AybJg{6y2`?CxAahss23hQs9?Rz<&{V zK5!Yz`X1nyQR<%uJQsK)it`(QrvY!nSnyWhJAr2cs~8u43kCN#fo}tz3UpAoZvei4 z9`?h)8-dTDqZ*;pW_3n0SFfcH@B}uj=hj>GGwbiShP^TC0(ndF_ z)t5WYb$5W@HPE7C33Qy1mZIe6QW<4kp!BEveRO zNy^8^>YZN7pn6BzwQkZoQe~XgW|QCA-Trpj^cVPkt~!6T*lXUhTj;hAHN(kX20?Vm zAX7b_^j4Sa-K2X&NO45W9|86CnueV&thDBPjdm+psGOLYIW&+Q2VeE%#zQArWzaJ^ zK3WbvYH*e{Twrr7S36Y@&}qy^JPZ~Gz&m{m>0ok%b(*W!TU)jaZTQ)ueX~+s1ZOsl zuI99jz8jrn{T-*)Uw3N#zB`h1*TreFcK02p@46>RhxudeNAF429=e@>*4}o{`cL1n ze%t-0Z+}B_`mXmT>$lvUtlxLb`fZ>u>rgy1QfTJr7hEHhXO` zsdqZ<&Oow$_f2bWzB_s3W3OMo_vYl0kH2^Qqh>LOhb@#8o`*voZtl#?(IMN%|-*x9BpLpPG zNSH|;dFa&I#~*s+)LS*p_1E9KcHbw2%||}=ne}&_8ca^#{m}X+?>T+f-D|hqnXG^K zGazgI=6jO-EwSYXZd!luT|Bq`ft!-`yKY;*=hJH+de9dwy`!^AR;;3De81LFoJRZJ)Bf&s;-C*TmRFsb!d?fzV|; zYW=-;RE7s^@~?Yf{aqi@YPUYTSnn-&+RL2q)pY%x z@zZYp>G`S6?C$&5K6bOFc_+Qyz5b2|lGE?JYyH0WooxZ^^zEE3HGxr{593dg({H(F z{eDm$&x8iXRzH2$JDJ7@`AtJQ{YDn`!DRitH?O_vfwepCUi%PByMFJ3h3^i&bl>{D zcPHuo!~6E7`s#IeCkOnK-8S1tPQ6p8SihOga*w`PfBkDuzuwmJkyCHi_F&5EA9$@D z7k1m-H=n-iL*b|yrqd-D04FR>ICYOabkpgZA50!Ob?^Ge9;~ES#;;Dl{-*W&-Y{U@ z-E#BVy`NdTgU#r>lc`#-+KX#%K9#KB`P#y%nV6a!FSQNSAlnA%!|!<=q%eI2%e$O% z{3AXeIdxOA_Nkj6`NSO@qf_hm+$@|i;fxm89-NpMDYb-SYLKnr+FS010)ZBe#b@qh z>uLIreEbtETR0F}khk5>;bRS7%Pw8JBcRsaK0Z3Nqtw*ZKyMdGO&bfzC5!b|y(5O3 z3=a=qnADpvEB~!k<7__gke!13G1l;7cdxx4nj%v1`bRzv8Tv|lNH@hVEB@_( zQT#y2vv)XBCPzz&C1c|>$d&~1tc4cR-~M2dUho^Qd-!#CJbcr~Q!Pz;LEnjBTipEK z^;_;?bLd<&S__R6`34d_3j^$5wXu?N)0i5>Ra-Y=B_0TAJlk7EV()n`=figtt8@zd zh}=Wc2a~l=-emu--}8>`>yW$qIL{yZp!fyD^)Amwu8e3VMmpYq^AP7US-<_wwl~C? zyOpEISrNTD&{Cs*>!&`r_M}N6E%7#TsPmpexGrW(>I?wedp~Ev_J=w6p80(-PuQ&+S;9Wt-s+;I^{S; zlC3qk_o1~n{}hz6fGVVrL6;teHIDb+oTR-Eha+#hr&8TDI+)Du z8WTG6+2n`|n1txOhu!tIQwSG{7@2Vb$4Pp^x$tsf8KXMVmx-}*al0Z}fp z-7Yd9IxeB?l1A56omxPjujxh^F1)MAi^j%wj6SL}x4hD9ZXeU*!qAxt!20WNu{HbT zoebHe03_Ah-nV7Tu5SsAlC?KHbo#c3wn+c~ zNA&YqIoQ$vqyMvquHOZ|_*C?1;1_`p0v`bO1MBGgYrxxq3xO}9_ul|41Aj?hUjkCV z`h9GQ_hze23~XXx69bzV*u=ml1~xIUiGfWFe8XWNdUV>$=4?oZhVTO|H<~ze=8x3V z%-)~iQF2`n-$eFMZD^@oTR}H8pTyYs$Yd#H%Nm$2apo}OPx6sq&Wc`#4WsC;b{k80 z9EMueUgKDuq1PC)4Dw&kNbnw2&Fra(-mucB;~wg@F(u=GNsi;U(&uy47WTJYtJ&1Y zC&nI?5*1u(W8*Y%MKdv%TK=xE6pf|jW&;ON{<2m(P3p($E$mgvfy=Mnmw^0wGPfd! zRSU07(#Dt7Y1C>wGPjD+E=jt*Y6tB-@!<}}C*(Derx1;?y3*{?_DJ8kJWLe3Q5xwBacq4k2_Kg z`VM1sL4x^uW05m%!|NWa@hkg*mO@jyyR(dAbolya$|;&ZDtDj_W~!WB zZ)}0=t1Pqwm*%1Hemx z-$UoWGwA)#=ik4;wr~$n1ybP2z`eu(+ym?f{tEy9UjlalF9BW*{1Wj1zX-H}?*hIP z_*r5CP6Dq6o&)>}u>rpfyc~Eu@HpUOPuQ}h4tzK8DdGYi0%n0H0uK-ua2IeX@DI%O z{{!9vXx{Gz-UVC&v;h5Fz~R24)1Irh8Y_6t*)RG;UUb``I;(ix@es^God=V~aD7-` z;yJ(%e_WpAYQjdt9X^~~uAS51z^>xXk1Tmz*chKlm zIo>i&gPg!JdOvc>QuU~)>Lp$Hn|N2s(W$MpYE>d8oVs69CB9)EXLlD~S9mURp)JC+ zjrtOMFqxy8#8LTXSO5zi;6TK~gCpJC<{TG(<6XU#PRm;NFf7}V0$aStUJ9LQ^ePJ# znW@3K#?xq7$G!TAp77J?5mnJyTv;N*V<0wzFPv~PYjkt(LbBRkA;`cFruwvPQBCZf z^PRdmj*LgJoM9HN_HlcC*8?)NkG3`ICmM=|SlyP?Tk}mKB5Fy+Hq)_2x53^@Y7H25 z51Ipc5>C49mCk(Kmk^r7g4gYHh6jgXujaf)L~68LB#JeNtI9^2hZ)aT7k=SGFossU zmt4Qn1($r1Vy)gygoiB?26tFxW1+!Ttl$+MPSVcSR~)}!YZbp?uWk4}-XP{fDDYnA za39w|M6%LqNUYHA(Q%-M;8BJ*4<^OVv|P<5oo!1F)E8Hp)lP9$tnbLoU@nLETy6YY z$8Wy64C3lHtbk*MgsduKqjJlB^i?*>n zt|uX8ZQqv^d10$BCCA&H8nH{SVle66Rxcg!Q47husGPS}4YH9TGTpFJg(2!hrC0Yl zsYv5-#ET^&SXl3Rv#!(Z0YMiMBC{(+aMOOw9`O*VT1}!<-6Cs}JXEKE*zqYx<>YiJ zH`>?~4YC0%uBKig=m?YzCNnd8*!mD7jd_K)vvhGE>y&6cM@I&eX5%Qo+dd@}WKIXg z<8y>ZIjvhYh)LhpF^-Zf;D+oa#VxKw+pO}TokfXR*4U;txpQZ^wNL|1%}zPzr`qXM zT|%0i9-AyBv#UYG(jiGZP?Tm(dQlXPVzf#4EHVLK@NizB!t$pTXY7Mp4qFk)cW=+o z-9p^&gyST3MNa7XzJd4ZOUoJ~n=;0kv9uO>=7%@FjPvv|kS|eQiiT(` zAK5bdpjRveD>Y#r_EscR_Sq}}ZXKinq+1=O$?1u*IG@OHo|=$eYa$y*Zqq|1t#WXi zjk%5@2O&A|^yIR7v$2HyQ@a9;IrgnBzrr~c=yt5yB(%}zkc7iuXU9rJ=?)BPryG61 z_iL0P)qlJ7{fetYtBBzy*;cDGKAy-p|_oR z0YqyR{I-Ug^`6*F&Tu5Vz}K_qSsN!-al98=4+tNwbDe8ML=d7o_MQ)CA%d}+PoZk@ zh;gP-x=2zaz{Wfa#{h_yWUR-JH0FZpdng;^@P()ShWV7)UB!O&>8 z8NMHoZnq)(3{C_wp7CiPU-@Z^KmlQiI@C5MhMcnORhIzvRN`Amc$Q8&I34`;;|+bEt#mQ1dW zGPj16wCAozu<`*pyU4bHk8f_(S%qn38IwW6XB!xkJyLIk2-{SAEgZn9$&v?<22MK? z9Uc*OmZ{c&Wp$;d5Bjc1mLz)3w+TJ&F1OKR1AlGSTZ_mBG|{{Rd>okix~ zjIGL4lZj+$CL`LJM-g+WmOZ)9M%M{+n$A6*8%EZuZOfTK)EMpa7Mh2oKs_TVKK^ce zI~{afABJ3}`&gf9XRnr`-mO#zu2mCuV`YIc4_xOGBqqCtWaBI%+eERTG(yMKg)e8l z>-zsMqQ^f0-Cp`XD!KhEq4PI^Zv}4SyIX-CFbljAu;;_GoBwQLU=stI7}&(XCI&V! zu!(_93~XXx69bzV*u=npd<;lKjaq7Es!VZ!V0Nrky1Ae7AhxR3BA(8f8Lam*`D3zn zi>sTN(K#0}L(1^is7b-BpE$eQe#^dKOC$oLgL7N9`CuqayDLi-TW{#B3Rr-@D-d{|tKnG2nT?bAjJQ=f4H`VPFjS3O0kk1>ONX8Te-46#oBffWyEO zfK&MYKMK4B=mH&J5cm=?0QUn&fWO4x@Fn2Kfdjzr;Q#+^;Elj{0jd$O1$cxQfG-1g z1J47V3;a2806T#lz~ABj{{V0;pxSRIfl)wp=I#MLhu{BKfmPsq;5V4>YXF<~qd%sy z7A3f6Vp^$9F!B%q&?Rk#=#F};vin-BG$in`jjtQPG1~5I zQD@Qgj728m9zB4 zkOl|R;p9?W5Q}XMgTq8fPHk|DI(-?=(K^O3Ss3{O1Alh%qqBuUn&XE_>nS`fvK&VG zAh+t}LP9jV$|%fPV<;QYVunbIdpTER&RK?!joHST9+CU5g$Z@>e3|hS?PHIh@0Q7_ zojc2=r>lXR7pF%{I#1OgG#wi)XVjdgL9_^`%@s{0C7NQTW4|?Tuzzj{f7O~jf8bcn z{++|$bmVAtWr2_=K5)Fu9bJHq+4n+G{39aB{|5C0QOLZU#W`(U2=nE$Zq1e0g%2$I zt9e8A>kXak*CvC^{vf_7{C>uwX`;4Xaq)15<6b(t`VG5$g-tAG)m+KeQol5B(0^~R zXaM2JzC2dbKgDJ2UqyWz7g4{1FyWJ5Z8?Q9`}-Wr=?BjjP|a;)g$@`{{LNQS55&c@ zhkfm$Q94y@fw_?uNL^bk2GeP_ODnyqLRg$w+8U1T9Gxt61g(LeqmhZxa-L~5D0*e1 z11@bWg`u5$>|xA?)UZ#@f%4+R`}XdhebH4{US5cr%|i6jgR9-)OZV=-Z0`Zzvg9Y1 z^Gc{eam;D)h4t342ASX%%y6vQX&83pxv_Ivj3D+_aU^Vvvx{OwTQ18A%gBqc@R{hGA=MY+`mITd{ySnn;0+YzEOiX+r2F+$|yj`94&J6R~HGR zD!yN_CY>R^nkS;Hqp&I8^a{@nQj`x}&QavmMWj?XG<&huL3lIHL@s)Gjkmz3g~Odk zs)SZGSL`oIRO35KQf)PeRNEZIftxR>bApHS@j%ju0bA(RTO|0xap&rKbV=fCbx{#0 z8ml>$V5N#P-bP`YIO-sZ;>WJxobwVkN9rWV648RNp_$83WxXlD569)8BSmp$!?sRi zTmn-nFhdRe5ROfcmt$sX5Zr9_6Z1sOxfn6uMpZy)pjL=E6^Wr1`BJQ`kilZC%yrr< zM~je1el)K}OWvy*A!CL?kVEMkL@{F2ri#J9|+SqQ%e%sEQUy4M+nvOI^M2d78#JK2mN0rfCpqb=u_MG?v}roDyDUe~9i> z=jZFoJ=Ox+V-W*r3^4-A;uk|q3g-j~A;$XTJ7#WWL50OElxgQgxrpRR8e}8fd)1}Z z75k1|&8BtoZ;={=h7bUGRrUMiJq=nJb^rsbs04a$GupMv&6IHMP3&C4<+H6%y1v;ufy5 z@D~4)(JJCil7dBpW}zKji~oNf`tQX-|Bvtp19t;EfN9{v==vW54gik>wg4YN-@gFZ27DeJzXdD--vfLO z{r)8IYC!t_pQ7V`0k|D_Ch!d4E9m-v3%m_@D{wu~04@f00e^x1|2x2qz_WqhJdYR# z;7jQLe*w$^Rp3d$XPN&G1H!{D;o?#KB>berIqg==E0IEIhfF1RqsIE1{8zhjLyS2BWZ#N zkZsVih6N=9D_NGqqQEH35N43@V=20w+5nMGITgHyULfjpvrWW0dpC-6oR$c8UfWM6 zK$Kl(fczPsdOl~@JtURt?4U3%HrsPm#oN+Tik>i!wa_Fl_A}9#oR<~XVek>%N{gQ>zBPX_-CMOay z7{W4bo^W!@?{e{2YbCSc92}74&jrLRNx|)=dJch!xK%|;vn!oj)@vTVw-q9)C`2Xh zEw-@n2Ia$aB8_*U(_V_fp;vE-=e7@z8BYL}x@c>gvAsBtw3 z7^%b!dc}3BIY#7C! zQyCRZoo6GoOmMX2hTStwAPH)Y?c} zUYJ$;#w2hPW1ytDX6!jmnrM>F&;*Z3o|nOF2{I4zkmET!bdKe(V~8k8b~^3!z;aSc zo5JGC7RkOq>J@HvI=UnP^K0BbwtGC)iYB%gDWTG-f8;UVu60;rVngW`qKIV5Qni=6 z7h13VY|1E!m7?XfK4BW!+7xkS=qlie3Vd!q`8v>{OjPXSEQ31B7bsF1G-eo#$d=|4 zg~3#X{?tHAtQht9fe&8t-#nqAqglERe~iguC#*Vp&hSrxLw%bbBY@VXwWFk>rsuP5 zcw>T`SDa2ZQX=%x1;fky4|^jR&z}!xFd*A!r2}HJ!F-#9LdQJ9bSXpKm>Oh*oN)w( zGg1(Bqk~KPP=~?Jrjh!1EJ97Rbf)jDcjmg+E+^%mqN-hbAO=WIr6h2dnuH_1Z&@CubfS z;q=%d-i1^n?;;>Y{y8c zU1tsAB=)lCSR90Z$ZFPeHe#%*q{ef*e3$IiSCE@p)G!?9KUnXyvH7thGGBoD#CYZ6 ziKhn&O|U>j4VPAzaK|>3S|;jQwOmrD5bQ%d#Oj(`nTVQfvDE5rbjg4w2SaHjy8>0+ zQL=)^Bn{%cuk7=ukfWel8K_Q{CFkSL6{&pe7vi1PBAU>Gfy~m1O)xxKH~s%Qbls|S zUi|;@{=Q#B_kRQMY+x(!&rc<%9ykI#1^5~C{$=3tz->YIp9s4DJJ9#v4!jun8}$6Y z2JQx40Q?rZ{xZ-8z8m;sbp1a9UIRP__&mD)9{?TTMZgPzzeCr*54acD3Y-rp|NjW^ z?Z7Xf+y8eU1^(f@EnD6Tya%`x_-Azce*)eOd@t}lfPDXRfaaWP-v6#Y;uNy-O9cn{ z>{=Ip0!`~XUCxxSwwJQbPtYLlk$uV%O=sbqnT}?;lBRn5zI1ZT#+4K z3Kta79Q>G200xaPPu+#5Vj2$;hOE6Yk(Q(1t#{1D!h~XuUeJ?wluQF1qd~NRq5!PS z*DDv09^`QoE=q-ux8)z_JKr*uO{nu6C(fWMiWG=-Bv?`6G>SA`GE;tx1`+Gx)RC>> zU0fz36Oqbflbm!8Czixxq~1`t9iAz*9P>5#%gCwLP$&(0c!-M1rlG_b{F3y_@u`TR_??i!hh?KzcbkE@|h|Y@KzWI+*5~SQj<$ zka$}o#1Z3qiZk_6y=K3PD|r{D#LHI3fyEqyXMIC==%GtS80rmPL7pRCDcG`!Ml;Nd6)K*m*nsyel79T$c|DXgr1M*^=hs!k!R|8UNm5C zb;#~BG4FGHld1OUycCpztG{ppL2tCR`bf>v5(s=o15HoKm1GGL+mdUd{VX%fQQ-s< z09Tf`Ohr?qQYUj%)sRWbjsdZMEa4G$14H6*EhTD(N!|9elRH$8K)w4v6wb!WU8BL{ z@kp41Z%IyD^}4~PEmLx4VX#Rcs|HJ@+}lYkW+G2Jq*57=NqT*1xImhd5h1YDe&ru0JF{|Lxi@NN}|`$DZM5_ zL#Pd)A}y*NL{JWf#-r#iD1DTHsH8As+-D4NS3(}Yd}JPga(O@qZ*DS4+ahAuNo;9*0AdIeFw~;UC?K z{35Cu7sAGO!8q#_obtC>=mLIR8LZrW;jX`Hs-4T_+l6+jl0=`vU_v2cnT<$U`Ciom zHg0Ye#uCfHsTPPS?NY**Fa|5I14PQq(7n)wt5A`rHW~ z4b-UDLP3kn8+zmT$>`!8<$i|I31Au$A}TsDT~g*$gLppmhAXXdTkO9wHkd$UMKL5B zM}MqFV6Pqzul89RhV@WzF53;--q9sier7Vt#i3Bcc@>pu*95qJ-9 zA8;9Y}y(W}2!X_8o zhB7S2$|aelaNps+%0Ny_GX{)wk;-dnqWv%)Hlh#HqjgH{h$@-6^6Uk6*wT|z?@1 zpR=WFG0t5Vt6ON4*jDCc3Gd3a9lj;8gJ4M;;MP4V%C`?20I%9=6lm+!NBK>i)Y|h_ zAJNR(E-S;%GY&+QpMoo>#dZ{vz!_F=w_Cbgfp2{nHtw-mw38hKCAA~1r`_7J#Y9OQ zmA2GPWMV8;R8UNjKDTl#A7(-8CYq@w99H4${ zq+}wMwL)}cQ7qZU2>tYANh_`zWT&FnA)mo~vu?sghL6IbRnoz~&GPe%t9^)6R^u~B zW|UntcXP8rbXp=N9abz`$>C%_<^+xwyUmWA1#S>lH{VNEmTN2;Ts`x{VKR`#@PcTd zo*FM_eB{6f90$N#%LdY?Y;IHyU_iid>#~V5NxK03uay6G@Wf=jU+gHHkjaMXR#gCX7y*7m#Rpsik#Voq?$>7 zO|GnVj#8P9W0>%hRb6TsFV3YTMCo!?WH40u(#rU!?h)0D#>Y#Z88yhx zOt=zLJ37}LKJIH5*CX5NqXor&mYOiV)M@x=W z4dO^e2a%9H1gq;NcEowbXsyWIR@gBMFfr4$o4?K zdI{gcgRVvxfpWVKtkp|Z+d3bp9uMa)!-(~)W37zpNjt-eP8+h9|QgbUH^XocK{zo&;Jlm1FlEUZvfv5 zyaOHo?ZCyr7trnh1b7Fq9T*1w2p#{2fN@|9_$hS!Q^50p=K_C>em@Jm5_mdr3Vr^g zz$|b9unqX#^N3FX7J&uesld;p-+vZJfo}(%27HovEd!cgqB)lRN%%pK4HisG(G{_kqHB5acteLYFY*O^lwKBBQ{pa!MXWI-V?ge*LdRNK zP1+ZlYoCLGK`g`OEGf-5Ubvi^O|p!6lbskCu7$v}JCcN`bk$P1WGO+0Q|Rgt9m`2%{_mFr?8PQKO>6I12lV#m}#ld_={qZpl&Mb?;U z{98|KU6qBv9mo9##Lzl2IbF^is0LvK++dZfNm`@FtoU?|_cajeA?Yli`TOvHNp-;gKf_!&mv~3U##{&k}`gtuMc7U%xRN zQyNwa-6y8=tN;+R?fY(trhXCuv;>no%3cUSgKP=racTC{IlbwKhp+hEPbqz2ojh@tf&B7=*Id?5A#AlR(Z?$ZNvqC3^U~;^B=Zed$A?`) z*_+4W+A%Ca1ss1y4qkd-k52h~?`6cA7Y~1qtbjlxP2XrWkH8fbaUO#g?4<`p<6e5; z>c%nb-{j;t&i+$ksCmO*}*&GX#HoQO{)KQ z7@hcX>Ba^9{~>(;Hv$&`+khX#4)CMERe);$|1`FMPXP_!3)li=7kDl3JmA-`2Ye1t zy}xGwPY3=0yTDt3Yk;Q!PX>Mx`@kXKJm3NB0w2K^@Br`<;CHYC{5EhD_%`6bV+Z(o zKrsN%2YwYBz^?$4zyzQgfA0pK2>b|o|1RL4nbSW3KMH7mmjVASKa%1kJX>7Qu$PQ%Dg5~h(?k@%C2#H-x6i&jKb^h`PKPm{ruF$xcES&g&fiUh<#LG z%|W9kKF|X}O!`0+kchI3NFhBVmbBPw1voXT6)G1pSVX1WSMQY!71HH+86FGyhE@<~ zR!wUQfkq)GCcQ-V=T+2Q^r7I^pLL@8WHxWmYkvs^yJfsv`JI5SUNVt+>MC;E?F`VEExNd{v(O5VMr2AK|aP|lEup7@UF zf0(QHj_dAHnXj~6wU%0X$*Xa+SiRz}wlZJukWi%PoOg1oO*6ST;a(c{fS1Q1kjvL% zy5udw-0~U({iILSN@e=1oETaiNG{q%v>b1|z(R0?%GTi%1xMQTzqS+6o7;YvabQ|` zsLF}K)uf4AvRe<`QNepwwLILu|7L&7iWdZrgxNSvAUa1)6l z5e_Hmh+ga;Qs|dRLC4FqwKCH z3;v7|pEmiIDX>w?&4Rcd%Pz=5`{mP;AH))N`}?AA><=|f!-nI3F&l6ZEf3mejt`kU zu)ipB&_Zl7!h9K*D%Gu8OXxY^_3YUqmaNOoM^=AK-IH%#{fRp zQ5m(>9K-h;tv)`8;XKqYJQ+?`5NC_^Iql4F$7d<8qVD(%#oTt5&CH^KHys}tFK0ec zgV40Bf1N@S!M~1qUF_R9yY!{~`Ieo^T9q>f*)7yF=ZoaY+-4sBsVo^D+FK(#OBT#fgIM3n!Gv9!caUJnJpz0nZTdRK*RhrTqu>Uij4e-UfdBa->1DFp#TX-lyDC%ad=l-W}I=K zX1r}=c^A~^}++Y zuQb<7OnV>MS9M>gAJZ;U9{m&NA|Z*z4+ z$6?ErNp~N3;X&mM$%BHyL`%G~Y*(GTD2C1zzN{vE%)9WE1-ZT(n*1u;xtNJ|<*G$t*fQdP-$tVQ**?%M=TD zm!B0ewbhhCv`atQ7I-fu=B0=BTz$~GF7oSOKvYJO!UJ8@2yc?qD78cLR8=6H*x@Lc zP7srA<3>ZR3aR-j0g5-{Ty}p9%;TlfM65xOdJ{Ohs#?cLBPWuh(-Y-lAk-inDoY%# z%$UF~G;kg8CBoZavX8T!CurJ*+^w9KSFpgt7cI)#3G6uHd-su)vXgAH1JIB>rmbor4mL2$5Pt@w@DA=UuNQ8 zUjxpM(vZ4!Kk*QDlq-eJ8e_ARd%JlXlIfvp@Hw_b>loGHwB+et_XA9f?<}`V)gTfs zbs{-?)tT&uJnb7VZMT~zE0*KbZ%EwuAfAw^3DQ^Cz*~e+Pcb_iR}-xrpPDKuW6~fF zc{glXF?k{+#wR1G=vt65N5zsThw2iVhA!v7dNLi_7q|y;ZLtI%*fg?d@uWWR*qM%> zoaqERJ86txgt$_psZx9uVdwetE2t)mat7N53GF3q?If70j3BS)eYVi0JYgw%ayN{m z)=*(pS${MX{3uLn4y6v6oI&~oMSrWF%Bo>He_5J#+T{0z+^N(;R&!Ok}hU;~; z)q)rjZDU!4h0hhul_?5UNh+flN74h+^~Z3W9yY^B(pzocXBMa-1Y_0`lhm=GGh*mp9{^b6oHk!|^B_uO~t% ztsROmbu`HsUSyV~DrEvuE0LtE>@qe+S;ANh%Ybr)Q$xPV3wv`mhWqAR*b2q!x#^=^R^s4ub0!#~55Hfw(ON^C9^MjSUy3p*ewuOTo9HFASyQ0&GhZA3JjL?nODJH7GJ#v&X5(?$&H=9T%k{*}-*4%08g z1g$}&?i3*rZAxER*_{Q93?|Fj@4Dj1cB56C9W<(-@u-xS*dXS|^xDy6^ulB$8NKe6 zbKFiOQN_rC^%?CEVNw^xtI$sNzs0yp*iWwH6wwqHM2bu}g6AG^sAlu^U`2s3%gIF; z#JK^=uTDsJtF9crlge(4FXFWJ!BG69VoDaMgl;~@>4!)c*7!0i3N>0D=Hm0!zV#b9 z!p6HEH8SpD_8l20k_gCMJOYi@(*)2nN`~hLuEy;kFr{duDtS}Kh~3m-M8znLQ(FYS zjWr^zSb}*K*jG_?k_6B7T6Up`Mi|3rmE0;jkeS}C^HkH)BmGKmI@fm!3{je{d>6aJ zTO3qhTjM0QF zN*np0FA>uv8@c+b)m;lD<9n7cn*r5VY!tHF@}x{7ub_@%0$kw{N`bKGSPVD-^GE_x zYki@{c9g9$LIWd(+me@=F)rBT`rfZNOn*DWZNL(Z*MpoHUaXQ1{38P+i7oBLRkuUN z^g>%E!&0#Q+CWFA$EQk3Bi0}c^hGK?Kn3@f5dn98uwmdlR8?H`tU-8GyeTd)z-ZDg zl1B^7WMhOgV-*}M^GE|W0mg~9ahd6omB7YmAhId{e+5PO8PbQ*|0jY{yn^1}1HK#h z1@!$nKz08fK0~f@Huq;cK~k(UIc6bK7rm}2c8>j0Kbmze+>A3;8)T4Tfh?V zOyD=r{eK|U5fOP*+ z;PdGGCxM@3PE9~_d%EWLD1Q=uByD(_+fWUQ5;~iu=>!Wvfr&}C%!NF$AMt63Sgd%W z)skT2b~a8e+B`ba3JR8J8wy~d{y7g@v9E%e+GW@*>0i5>gKF2l*!IobM|ODx(rRQ< z?qoNgfb8kvxbK&AdB{JAg#@&NCd$^vRs(nFklb8OPgjG;vn6EN?HpiS1@WTw1gseo ziXshU%_62juB#Z^)8#5jr}9yXe}%|tH=@V~6GZrPBt=Q27h!Ult~p zwI|Lv zV>!=47DnlLTatAoHeayPc?v<)xxG2-jS~tZjY`kv56iG?+V}Hizp_Me--@QBz!sp(;;j|mTRiHX2xzRgh)AzfMgMl1=&(t7IT23j9E zqi+@qFfo>Uq>bNM2LW3ic;et@o?p``R((&I?RJKysLNw8Ta7ep!6` zIL{ukcpPQq`<^yuoY_>ulaM}wU@l~VDSd^=pzR{(e|!_HG(2hV$&~iYm|@!_K2zy( zoI_!h?9tGz@0J3`7BjJ2S-n&|8%AwDS|#XOw{p zy`E%>a^p|M{Doo4WckEex+GSXSb3mnbm{MB;!VZ zG+j293pJL?*Z@v^3?i|S(Q`v*Tw0kbV`(N%y$tfOzIah9Wu~cz0*xEY_QIJBG>Xsy zApwt;y#O8>L_xNO7<#zercw;b)yx9@z}0dEL)Irt)$7GH%`z-jX=S(Q)P)-BmD4K9 zFExcz8WzCtZ}bXUEfS~K_J_Z?e?cz^(xV4Sc<09KrDM!CTC;8?G9({I@RYh}Uj@0? zh1mS#kkhRInCRUdE9VoM7$37571IBu8b40|LI02S|Bj>g9|J0Y?*98I@G{`<(D_vh z;6C6bz~7_qSAi7xGWz~s0Y3ul0xkj`MCboF@Poh_`u-!pTY+x{z6JPi=>6lsX>|T| z;GMt~z!%Z^{}i|txCrcLhae?!?-;pZrK&B3}I7 z8RHjh9+T25d*I#8`Uz@bV@xy_3}aC-0sGomJ6{(|c3Z*I;Ke|EN7oMrdwR57DZU9B z=wLIM*F&gpVJs6iCj&cqR-w-6MonMg{}RPxhbNwe7}7tJJ5=DPx4DV~4ySlP0#1rwDgK>%@Tj7<2zxa}E>%qzZz1A5vSYNIcS8-r8uo8f9}8Eo!jR8-8EfE$ z#f)!_Vr-(UONs{BP7*oGg z-+MfwVX!9AM(^b!qyx*g;u}q(AiW*(<5y54EwYZ>{@(ns+miM&9U|{L-C-n23F21C zp6NyPPgXlg928MPQcLsa19z!3dSvlhXW^3}uSI5A8y1Obta`LuscCMX+99X63X=E; zeP*cB)Kg-5Lrg`5&g2JU3S^<^3ku_TMIo^p zvbjz6Fcp^!88F*yALNM%+J%Uhn%*m06reETSJsTP2<9m{Ibp z?thtmGKJ%yy)ojVC=hwXjSe(f9>D?v<#PE$1Z`FY5II=k8qS4gb$*&`YFA*OnbRV?;y3uu@Q!S#^%si0!Pwl_*Dj2 zQ}=`6bRpDk@TjA|z4y+CvSXUQVs38thOoU?Txy?b9+NxEU9({gA|*d?`PKW9ebqzt zA0T6mdQ_07Ao92$GH0530Gm;Wt_UxOlfZxNmcm*LI$wVA%F?pVx}6I@IUGKSHk2>a zkA*C1YugwU>$i1xvp00nRy#xX`^8(0{&C$btfY$v9%204=&xc8bFUXBTqVKUJr+2T;j`%33fx)7N2>dvS#LX7 z%)StjBDD|IOZEXn^3=%Aa?-3CL}JZ*F#I6X_vBtMozkxK;0kM5SItso*bl@rC~&Sd zx*5{t3FyQzpM=fSO@TPyd&yQ6FKl+Vx{^u6JX_Omw;$BCc@~_@E4W=t*SNvjynu#3 z;*02H&WBJj>owFZmwVtf%AO;Nv!lwQ8Nm;kPzt%+aT3RjG~JL5oH|3)D^+$_bOMZ; zjV?FGxe}{opB^oF6`2~u!=KKrB7BW;r{EcbZgaJOmpv2#j+9KhIK(>fTNUelejA|^ zY#+V33p47RHSd?>F?nVP*<;e7CNxD3YtE_={*SE84WqeiH{Z%W%z+_M1e*(WkhWWc zY(n18S3NlPh|4v0TTU>H#`Ee{W1j}u#b!frn>r#ZF$)dOrIRfttYwkiRLeKQ7YnSt zj8I2-2CKG=Orh-6*u+H1&wf&(QfF1{Q$@ z;9GzK1M7BvX=Z)?0iSd$qoCet*k6ocx;v4dvj6fYi zRF!U@jbW>5;*natRV;f6SD6S6XI6Fqwz4~vbis}$h($y}E=&EiAoBS_{0lpKyOUI` zoA9=1*BmK%AMpeYG%I_z2>}$wZd=s4NRXl#CnOD-wI>!GlEEfO zlP@Pmsck2S1E_||oyM%tyrLT)X6D|=;-7c~MaHBpQ~ zCU`5m`9wQP8N;Qh<~MeV@xi{tVL~B7xJ}^H=VG{NhSf*{-Ih_n*6 zD5ntxqUf)a++ndg!5eg zxD$Rt6+2rpne~I+Vs^QGT%UDs==4;Fftz3A>-;zC{RTx6*%2Ru@tdq-hka$| z2=Pn|8M*yfyp6mN`h%$<9If3Vrb!5(&(t%7NSdN9$QPSkfgxOlNPC;s$mB#h)l?0# zO)Mt@C)Ly6dgSOiszyp4j4>KGs+6!Ncj$7PTS%zl??Sxdx3nagT;R4&g+b0E)XEl) zIFB*LqB_uulrb!wM~&#v*5DAo$6cAE`xOuH9hyqqel2HEbduhyXkhhRB3Mg~Fu_?wmri4VCeJo;i; z7F3NGhvjTQtB}rj=Euk8bBlu!+&u^O4Dl%|s%o(-OHdBix7hQ3bBG_qlITIS$kCJ6 zo;6+95*5uNph!#8k814|(J|Ig!f-6fZ1=d^>qo{*$|*F+@CYe~CvrlyjZ*ziNLi1+ zV<=>v9;W~ru8hTBkH2Hdb$gw7?M0_iS#CUI)dnR2Ui&{p&D*Lg{l45@%JTIQrZIjl z*OeA{)+GC=Oz71}a}3p(wx!fZ!Nd=i57$nPo-%dfl`joEe57nv9t|R?aIBd`!P!^J zq3<|ROh^Z+0&EIefFz>0BnFyW@%2gYF%_(MMkubtgxeNPlj@rZH6q4zuegxVkiYbd zg$RKGqg76)LY;N9E3!J(90NvEd>@aM+(;M&Js5hltPepAtm!ECjg{IE*1+F7hEuQ9 zUQz?Cl=S~+qX&P#^x+Np|4&2z|F+=&zu>9V0R;XZbp96bEa1NaKabA80DKGZC+PhD z15ob&SJ3xA0z3d*4g7C({SN@w1Al{_|JT4fffoahpyz)XcsDQrRDj<^*MAN0eZXI% z>z@Wr0HeU)pz}Wf90hb2z@MS-e;9ZLa2fDV==$#mVhw;1e*ZG_y9Y=B&Gr8R9?cKp zhLh;&lDEg-k*D5qXCi z^$i;vlHG4#Q795#KUFj|Px2PML&8g;J7-jJ3NYj-Z!xNGMjprPY23>Qd-`u@2Y-NqDUSqtsq5@VXcTUagY!QUpWEnf`ja$zO(YrW_D zDsreS-T=PjduAIkYG9e;Y5{(5JQ}&1EIYO#sMv14<$%&w+-ZEWBzIDSfq`(9?U1fB zu?R}jv9;BsS{Kd|9NGjhn`;uN%}}pBloO)@S`Jj8qmF(;7*7kQtVPc$05-GQ zyNT2-kU7QkXl~gl3hv!Nt{5;c}{mF`^X8U z8T%BFk;jIG zr{Jbf(t?Ze9^y8c)hrTJDOYx!TW01_>=2E)K1ysAuQ~QD87%R>hLLU6_goEgnNx|7 zQqL+lc~t0Q0l_Gt(I;}H?5Mh?jAy0ElS@G92Jx!?7K4Nm58_7TOo_vVr>nktTo1IW zk%^#+(-T~TEl@KHK`ICKzYx-3k0>rGW}fhE%!zk0RM0}-73>OCPZ5-RIy0K#Gjf`Wj0S}df3sCN%v9GWa8;d z>Z=Fqy&GRLNR;pHJP`WEmz+FVjQh1`Fan#vFj+FHXo3cjDGGymnIR;BwD4BUHxM*4 z6zYq3p%UkTR9}mrXSgwb^2WXaQ()D0stG?qF3eJ);9#V$C?Sc1VHseaoJ4VRFWLyQ zMuw;C${{=_aJ)sd6v@eU$E(S0)8+1_8XKoUWF1CEte`NdykXIb>V^nF!8I+SXaW>& z+1;{=K-cV2^};id4b%T`LlK^nK8*gqJt)P>`~NQBSJ3%;!1n>t{a1lW;Cl4^2Jl4S z$IifMC_%Fa`(Ct4B90U#k-w*sAI{xc`7Xyz2K7o!e zAODrWKcnBj54almU*~z8|F!)4WZ)Ef{WZY9G4{^@p9VCKD)1lY$7IsXX*7$1>qi-B zX0K-zni`is0qwRY&X>S*EPsk^oy&HaG^33*HD1y;t_E>q<<^622;wi80>gHXm$~k~ zR^z=c8Qvw)R$LqPw0V9-7lmo4HXBRdwNtdU3-zjYwz^6q9|^nGa>*3qh2H0(N2nhU z-*hL`Pe-p=8hYGppEp6i-7#F4_p3-#* zz7;hHt04jY>65au$PFQ3FYP;Z6hsSWvm%rj##S*qonVWEQ=mgYa(8xdI=YQ>4{G>O zTkb{+BpDwY96wnhxVp|IW}{qJF**)R!+DJfPVXpJRc(R>@z}<~T6?Lg72kl^oS=&Z zx%te2^o_vwmRn^)aA0Mef%(TVUNH8|H)x73z}t-?mH4jEz*Q9XwjD=d;9APF?>~86 z?7`gRM(_IKghD$KD-k2v0GL)l7WiSGz;Wr&^aDb7>I-`jKuIUSG1I|8JP<50NQxV> z?rgvK?BgKvxBD3|i^{pE4cwjWr>$+f_yZhC>R!th5h*UGHM`(Z7^Cg2!4VF+6F$)DkN?V%*_~ zRI2o5d@1{2P%p>>w$FjQ)Q97(!w4y@fX7f9$bYlY27X1{=aw$}RKMEC3(dwdin%`S z60~1`l|n0QAQoO>6PzqrjBt_$?k1U0vAwk2NK`7$RK6 zfeqL!7Cza&Kf36}dK_!@3f5uN(*D1)Fc3;nhI>3x*pEHbTGc;F9u0SW*slce+3TzJ zFSZ}YaL@41pZa#beJqBT$TX7QL>`TyQJ3|Q5!V}{ssU3AYaCZKUMiv!?jCp<$RNm7 zUD#tv4_aeZmjou_B^B9Y;@jlVq1u17b6WN7g>42q2peORibSP?@vMQb?l?xbQinzj zA}P)a#~@=X7|8fVRWwji5_VhJP8yheuv!ETgzhYYk<6h~PK13u7^GRgQStpxL z(22}JVQq8Ht~~jLIv2iVQ?v(|q>O)LY1=d^=?@UDRBxbfTU8BFaUJPzxC{oT za1RjH*WEZL?3Ap#w65YsdzWk42+meWD6A^hIO&s8%}m%Sq6SQw^>z@136F?LZmD09 zdCCMp$zd1;Loqq)GZ;UmoCcG0rO+u1cu)~xm$F=o)Y@1S&mtqgHfRhD(XW#SEn9zt zfvH%S9b7Xlx)VJJ)-lfDtIQNTrW=YVnn>xIdByuAkAjgDM$LdPtdw}1@7SIHa0)xP>V+;5-U_Wpr z@Fd`U*aYqe4gr6FP2l%|8-ZWL9`HHfCSZqt$1d=zz)|2yz^9nsLxARawdVTo^%I$0 zI(O7!H@AmhaIZwC2b2+=&O}}ga?0^)M`5dr50S?(Y@#8qF3q(u|D8?d@(l{%=&uA# zP)9i<7k=$5%NW)YqxkhcdBJMq5|w5LF2q=+p{%qV4^!VZEsAJycK+c z2619v?G+`$GPP^M-iH0vYRx6fcz*ui^I<)QuA}bGakaeW zW4u9~dq`>DE3}Qj%BI&qUD9_-2cDH)Qt1e>s#W7R+q8B~fZ?0rY7pRR)z`FqvXtk7_foZUl#1W@z%9q4P=J!6 z>AIX~(FbW791Ka3_tiwDHv1|Yix-I7!$JwULabXu_~iT)3ChPoyqwmYdCbR!%t4+Jr=tTV1^N080rGX)00Acrl+>L!=!h zQ~p-mT&6dZ^0}k#;wbtq({rGp@^JMuJAdM=p%H4dSqcpX)X$xBpX@)ig#GkP$g> z>wU0L7s!G-jMd~25WIw*?PVpEup@A2?D3mIG#N0Z?cc3jHZv15Cg6C1m7>X=lQ~V4 zy=g@aGUgOV+*j02cq!=YP&<|I2+?X2CG#03Xpj*T@$pmhXhV=H^k~*J$l-E>f|MXax(NG1sLceO!+Eda_&G$B6hJSIRt$u5M)CMV0?h z2c2ZmORMYkXH#jy4k(Vf+3t0bI5P&G(cR)hJ~5xtc8>{!ar9;PJrYfcwtlJK(eE_df?*1?&gT1C;Ck zzrwu!CCq8#KM6lE*xBsgM21^+FwuTuYhoohHd`?$TcJxBw<{1rwpir1+UaBCB{O=| zz|U(U>Yi_m81jgQ68H8&i^EZ=^j@;-;)Jrk*IEp;=#^eRIa>0zJT-{KLV8#f+Q0g{ z*?g1>&)y6%j%3a2wnAKAU`T|e;hZJ{SMGNX);Kb@-GJ){f1kV0UCSEZ3s_IEX) zvaU1K6ECRF%sCduCd*!gK?7Wga1brvV;hFJ7iD;rjioEi+}AECEo9dcO~yQ{OG-VE zAr+$l0f5x@#MAE;nNB1xfZxv~%%TvmNw?dQt7PC8kF^G1kbCIFV`Ve|(;B(`KBF4W zN4cp&I|-|;jYgGdm26;X(HVWqS8UiZSWPyjJGz{xj;$_swos$fCFMXhDDE-@j*hIr zbwYCsexOWEM|R+mV+CrQkG6P5!ob7q#fFGnSX4nb98i)ygt91J;kY=`z)OS&s+L@F z#UWwQgT%nqWe2a;ZNfT3qdO;S9oh3xKDVktOkOs0-USa0T4Zb8p(9Sm|U zU%rgEV8Vf^<)h&-G<~K9wh=Cs0Hj+4&(ZYH8578Lq;CWu+Fe zjuOC)pP`SSWD)ELvp$fl0KNx*=&p!DbP#w#UyS#)5PstRE{>c+gwC@6ZPllCl+1`$ zgW@zSmLB0037p^rlc5_+=+lgZhz$N4Of-SQvVK8NDL7X`7ErMEDDYDoIK{(;MkvFb ziL8$Isp;`@`NC=tw`msSghJf&6bU~LnMGP;Iu@53rr2b3L!l?5-gsDa_CQbt4D*H1 zsPL@j01?SG2g01Pi0J-^FH9*d1byij3e~mx*7WKIrTicVjF=7)P-3SVr1}KJt+Sj6 zrjl(3^J0c;`v!f(hidk6(Y6;B6fjh!rc#XRi3csd91AijTu~ztz4*EoBFC#j$0*n! z=Ntpz27=*Xn0odm=4ugP3X`t$tEh4uu6db-_nh+BQV1Ox`LltW*TJ=9%fYZPvMkF% zQBr+D`&Y+d(Y zeaiPvJDmZ9S0AV;^SeN!FLRmMVzr8k7L;9|LcynWmIr;)2FFTzC2IMwLb*E?XH+oAsNhl{qg;lU8o2WW z|5G{Vi5f)KlfwDfJrx^>5ybF8-w4l!?=uA{yn0myA>?!&3Zj4=Z4KR09QiY~991#K zn3I_+*%2mO5z67B{A0ofs%XLwE=KLVUJ80#WOHMu1>8f?f{+kLNo+d;AT>$mtIh-% zELT!2G)_p&HZo`3%BojeB$W;@&3OX(EAkw@W<%;e*|=Z8-VWzK8)V~A>c6Z2zvjQfjfa00Ixy!KM8z4 za1*-!4*|~wegpmg*MTF2IApI{N+^ z@HXIb;8)JuvgMb7!@wcn|Df|L=YIgG0PkWx?*zUB(A=H|Ji4DVS5|&8&w|;ws>St6 z^_Y3*TvHEfIsW2uvYHyWX4~&e^ImxY?!&7tUD0jsGC%a~GR|x$(p6EB%=0V85E|`) z=vEpnYf)4K?GrmjuzdoUOxh(lcJQp`wIXRD-@P{!(g(z!sku~AU!Xzc&nd>^*1Q;y zDZu=qGi60Kl^3Z%c4a8e!#|~iH8bf)@*KLKjxqF69dJpFH@9Pa0Ba7eAtY5|xv=sf z!pEDsa0khtpB^-Saqto_ab=zR6^@cv7n*Gk@0_nU2*MPu;6;}a>d>rWozEnxXjarJ zMU^mn%H)?F<(x-j1 z!?H+vUExN7P_)P-uxv5nOV6=pFZ7hd{3+H zT;_s&`Tdq7*WZmOEmMshb&`Mwd^|0LtEHL0+L7g(a zI*`q<@`~8gIIvV5DTYA#twBk;X9=TFC{>}YLf(t*Y=Tz0!;S7rtD!u5+eH2eHO_U} zF&~~83PpLPa<&N?#LaB4Xmn@u{=b$K1&y#VGQAZIGW8=v#xs+K(33Zob67|k5K2ipgbEK$Vf@4Kn+|l9h)v|+Mz*g zT9(RBi^|(d8{)5m=0a1CU#_dLDofo(_Nw`^u}gH5t(PA-aMgjCr0=PjgvYkJ40$cT z$|!zjlfq5pZr>yxXyz3yHPxylS>Jo15ENdt0nFGsR75E-e~k}pWpN7~Rp`STN1+rG z2S$v%gNoKMMz*27$Bx|FosE(Kz%_~uwT%jIid(;L;@*jveK;!E)tfb$Yr8gNyZHlT z82cSBnSV-nP?mIyh8a8dclz#CCYH=LV!up`xgW}l_}DNcU|U-^Oe1hx0JH@s`%mG)3LPWt>tXzMKI4;BPb7*FZ7?sE(AjIbjqI*&?wjKog=k`=qrXRKcIw?^)f_v7KdoNHp++H$F06F8WgqLetU7aw_aN z4T8?*6HpF_er$TAtmrUAtnF%9;mct~EDXJw}{^LY7R4k(!^{g#m@n zedy!mcIG6>%^JGD$mAbsOk5K)bD+KeLKvIghB3iQ39Hj~7V*G>BkJ0~k1||9Z=>C(y1n@ggB{m;;H82W{=x=oYW#DnZ7T^wa|Nk2} zA4q_Yq5uCB@Pok9fS3uwMC2mT#@ zY@?e4&eca-!tU_FWks^=#Xl>@SD&ikg(S4U#>Yy^P-+nNm(mRzop~y8qTA<}y0Hqg<4%HOS_I*_u@dCSm`B86e3(Sgo|NIrBv;R2nZKqa2Egi&C{m zc3q6zrzC@T{SNfn=WvE5GL9Hk4&gM&205SAT?zxuKX^3gPOG)+b*FM@9R6bMe6at2 zYv&pp>3P-hiWa_bZ>my+XlJ8VolR`7J)RkRce~Ng*Y-Fb zJFK&SxRi^ah^mxp0SUg81Vk!8z!zxyks>vzC<1~~Bq)NG%ZGB4011BobDrmU-?7JQ zzuByM8qdu8ywB}C=Q;NiuR%kMvM~UYUXCu@*I0u2KrBZ z`6vhMIYDnbPevS^hDFu`tKn;0FM0ST>gn($Mie=(ha%3bN_g4CQ)4a%`3-V5XFE8d zp}df6obCcVXqjOXEBW*AAHn=#B%?lA)~-f_xa=9u#K-hRWHWGbAu=OwhZ9bBO`MsZ z2}mJZeo+HguolI&Mp@V;HHoP|c@%}9EOg+&>OiW2Pp5L6j(3N2Om+_pdRJsX z%AFL!vrt;XmOs1Vev}$D<3I40k;;WJ#lFBc5Z@$=nBMugn8ac4l+S~|w-5sqJ2Z!g zdoQB3z4s%`=y*f+!TM}IUeY<&oU2NN^3T3einI~^m&J^$}og+ zB(nk7FoVl$QmaWJgHYY4TDM9pHYOjk>j$ED1XkM= z&!rGS`LLKiY?)Jvt6X@ct8qg&5(rZDGZ86&CEeWXt=SC@k_00&m8Y{2rh0?ppr!Wx z;L}-6%qD+mn_1g6ZxQ|usbRuP?Mr)WF=b4ZuY-Zlsc_i-!lD<3!lp~nQ!pIcg8Eu@ zpR+pyu6)*1X>dFHk;n|l1tc=#F-zq*1-T?LpZ4=Z7RP3ql{ic6c==lJzKy99*PG2%*q?@ zZsA7AJP5)QgZrJXH_ul%I1MTbGfFH)&O~htD!1sxnpj*SSn%giA|6|fX1!U;?MBZ> z?jZ3rW+^i6TdqjmK2;6nhGs|gP;EjQC7#B;Ev;5KA1dFsBx(5=hvYqY&Q=Tlq3i%u zSnO(^e<*)n!kM{iGfIGU2X4`iuB9c-&aC4awR7$fUD2j%VAG`S5%))8-*W7$8pM^- zrbe-d`w?v;dM)cAKOW>-;Cq=e;dpRVi(xb@pb#hE1gcjLg2KKc`TsIP@Tg?rg8%== zk^9$xZv&JA@cRJC|H=XI1?2r#f%gO71-uRTBr^XW1AX9g$onq?JHWeu&mr@_3_Jsz z0Dcv@|5tz*5Abuy{-c260Nw?>6Hwg0?EmM1Pb2St3V0g$CuIFE13wJ>BQpL!06zsZ zfme|6zaRK_=JIdAM*z)h1bAKkiB{~FZQG~fE~dU#4GFoUnr_B$sF4wFqcefTn1TeADU-&M94Pn0cPA#Sx9y^ z>ZgZqBvkc#qnvw*GfwhCf_6)c2eO-Vi=veAl0Pr`6AF{E)O`zOU6st&3#vJVPE4i! z46mEDlHU7j5UHWGYZ8;7bgjz7sAU@=@Tj$XTdY=_9O>&?9r^EUlFPei8Ez1IEGcmd zRUXtr$`lobF%`2)yodCA_JcXki%C-(Q|KjuiM%4)tt}QRxP@8}8;+3_6*3|q>#A0r z_3>5p3^?pjCD5jj6DcMb9Q4QVr4Llw1JMf0DFKcFMM7;uF6N|z5r`WfA7UsB%tocH zaS|EFUKk|dc;FRysO&qaf_=}257N+M-xxPqT;w)71rJ!28!zf4RLadRLGE?$fo9o4 z(P|KhTV_3ip~$CHBFOXdxudkUfNM`ljTJP|?=EpISqfS$gGieX4;(r;x)9Xqo5uJL zooldYxt)ozn1;tD*O)q8N^IBj2c|ZlRVqv|bgM)a2USZlsL6S4_}-Zo$L;T#yK+}r zf$#RSP*BCl7-#5{#G}x{^b(D7sk6{fP1)wzs%9o7D#g3!Eh~IP(?oV}xy$&^oMbpj zQ}gWm7HyV|WW1!|d6EWctv!&{sGx2AWTEmE9(*>K_w=-#A6TqBxS8CGX8iNiLqSR^j-Z$ao)nDNXK#*S0A0*q zDnG1{mm$soBH>TwPx<1)XO|NLXu#rDF0i*Qa^@PbVrTEYdVMVKi!Ij|Ph7q^KX>gh z?S?*zqg!MbaAeq6Vljf=SU+8yTbN(Ge);C&mAR`IqwJ&~RyVc=W@<0uhsAyG)^qoG zzgi6T5%|Q;E?8GMi-TO>-+u5#tZ`{|b3RKnBspqkdd!onAkVJB70TvIT8<8l4W)6~ zEw}145K0^3U9+f&mwvzwQa79(>r(m$X{TY;Id~jyuI_l76he9KZwwXwWvgVGR_?NV z^W9WY>;;_THYSOHJHVa|*|rCk#L(O66=F4UA#R>^#iQ1&lBJ1)HJT;=F)i(9f7kvb zL}+`pMO{OE!cPX4#Znr+^rN;i;jHH6>+hc7B_ZkfsIL3PxE?j)X6*EtE)Rli>dBwHa zcG(Ffs`+l8OehfMPf7#Uoni~s7&TqRA|F(sQ4eIOIXP99AWTiV%Yf=Dm%{2;kl7R% zZPkKSwzf3XA}!5NTF7DNkB=+xHB3ZH6lU8eW2oNd`knN<&#zw2<8*Sep5G>Ekoz=D z!-rZV3K|(|8h-&Svs3q@+j$^ImHfkmk4^BrCh?kAnn7@QeGs>8?e6!Dg;^b_oHA0m zom@H3jUPQ%-@V9tkJ(h4^>PNini>S(F)3-<9fWpRLKDDdDpZpRy47~i>uy3dgYDXe|F*Etqd9`PH6@)}RhEl*~8bwEMt!}r7?ZU!HC>Lo@i2(J=Kd`;$ z3sf^#04&EpA%sWWP`ElM@w&(t^_9-&O~*|BSI)m!|1ZY>e=l@&J4*@HXI+$o#9o3h>pyZzK0F0RQ(!^8N$Y0NMLrK<Nb{-w+*v4iFB_{jD)&rtY^^I*VqV>7B?n<8IQ=y!leE0n!ZjuY9QIc~O35>GHWp33aSBDl5j zvMKFo5EwT0RE%grFgR>TdW<`Ib2U);TG?#yGzeEQ6(Gu8#WY9^<}m7Ecjx_-D?zKH zjogN}-f>iwAPbkIq>Fo{2U_nN6NP7crZ?du#5a&ENq ziE=sECda4d=f7j%N4G`Er#}{_X0;Av*wS5#M3;*R#WNh5ifi_7h+W&6Z zQj}a>Wypfs)*BJpMyvSSoM*%!p5LiZ!6AUlF?DUyaWu(j2}-d9`I?a#Q0- ztfa`mE5BYc08kBru$y)J5bG6<9c$gO^oW2UA8gkv_2s zh^?K~81^bp6z;)gYD|SZ6HqtQQb@}FUbW(WrM>wqZCK$baB*AOjx^8|W&gj5;Cop%a_s*x|NkE#_y0cd-M|}xuL52`_HO`n;4jbtJO`*A z;9G%DBmYkUP2elY|7*Z1@IT1@{|$T?_-WuQ@D+3bKLq?B@Gs~9{u%fv@G$TY&_M^# z2L1;5{|mq_5MuydKnI}OfPak+;1%FW;1=)(UJIahU30t-hkKw;UGQcP*FZU>nMT~v0 zQ#p5B?T$fIvd28+NF_fPluDN)yU94rOCY&6+TnVl7Oji42{bFLNR)W$=CmqtgfMxh5#_94>#1#{x$|b;G=Des?J-`Lyl6nift3eX@g=qt;oh7dmqiAR0uZlW@Qi z5jDc)9=f4h#NhBjUE0*b=ZV_15a=jwK8|>znT)Js+-XwV>FA_w8TMS8DvvB9NUm|vA=i#iy4tzDCYdr%O8Ii3f0qBz-FyNd;Pu5UbQ5HD?pRdNPIjUV=R|D(j^={fl@kinXVT7@}>e;I0Ozm~yR(D%G3QrQGDKL6n6{>MJ0w zNyn44c~P2@cHR@(i520_ci~J_!fVCm;|{LS{Dfc&%cvw1Oi#*+V%bvEftJYyFa5kE zCyl5+YoX%mC)m-*4`nMV`v8lJ@xiSPF^3%n`Hjq%&@}5}r&5Fmbu6}TEBQ%aM9S%! z;auuQtZf2%75WXhbxjOOS=vkT(&PxPR!4(n-oDNcJl-4LlF`^^IC6x?^Jr~ zqz^rlDxr`V(&uc|9E#r_WEvW$%SEDaiRRI;-s%3tjZv=_dLQ;Pn;W@21e*fS>9eUS z2o$=@y`r$tzO(A+u+Q|*EWwn(+VTeMKIba-1+jWOk<)mXrJNGQeb(u*7o{JWP#^Cst6zRpxJi3 zWFE=sapPDe|GxuS_yNhp$p6hC7yk(I{s)0?0KOhrN9Ml`yczgI!@LS0IzX_ZKln3w^nb$7>Zviw%_^>|; zVgE2vLxvO^z7FHLW~qDT+Af}@8}qRB@CWZ+*xVZdqNrM%C}+)S&>$^|-CXbt!!eCheM`1sLFHL z+vP?;i?R{I4oNAFZNmvgNFHrB2Zvh9R4W^SC~R-C1Z*7A?#doFw;O>xfDZtG2yr#o)0_ z*bS2txdD8%c2;PtStoWmP)&cEnNZF;K^th~LasBs#(XVYyL9a-!hty?5Oj(@dd-SU!BQaoNY>!iSH-PN%q>-U zW4-|2p2@O|ISrgKgQ+UuY#J3B0}p0%n|3r6Mdg5U9VNq>NkSOikck+7^hfe>wr%Ye zz$OY2i>b|<8AIx?4|4)J2RdTc?2!4-`+rq-9n4fGGhaakBeZ)PWB#8@Fc{07Drq1# zEjX^zK9~ODwN96s6JBzzBeI^wt}>rtF-98XbE<~v~?9No<- zbsd*LoFnfaId#B)ld`(H1OaRXWUG_5e<-i}zFibjSEwL$>I3@gl%hU6{Zoi3I6X&| zV%EW*VNVAj*KCed9v!JX5nqogzTE3+5O*kxncDZg|IC@|t?u?+bt7tfkE!oMn^t@~ zhQ90Gt<@Nh`-4*q@fu+xkYJJaj}zODN8-BjYF9VLtdSWeNp(p=60(8XS5@r5{g|Ai zIbKq0qy}MgAO+oicqKI?@S=uV9cR80jK~3u;3Av!w%W$cyf0j-!cZVrke}Q;5D#+F zWCrCWlW*{Pb!m46Yd`r}Wd~OS{Z!FahFh?y-|fc`OVXsSVkzWO14k}a#~r%VrBb4K z66w%6rEnqO)5ln?P>nw8AqwL-x>>dH$**oD(*J_tR^pBsf{R4#HJ`u=|BMQl@75{% zlg@D4Dhis)8pV?535Lwtq6F<-STk_M?A3wPk;fsQ{mp5D5)`N&>+%^!cC=2+m@?Z9#j%4t1{@Jv>@JU zXAj&#pBQtE1a3x33B|cvp+=SkwWByzUke(WeW5yg=FF_+Cpa(djjXSd{N-bR(w!62M^JWR0aZa$koZM?=rS^kLz znzH2oaRlNK$;HV3(?K|X9-04X;3?o^$o#(qTmZg^y#IH=PXKQL9sqs@x&I@;H1PMx z{a*w=1Y7{l1AmU}|9M~uXaWC=?Emw?=aKvW4Cnz50B;69f!tpSI)Fby?r#AZ@GZbw zfme|IZv$Tkd@b<&o5&deyc75g^8cRzSAa)>k0bx9CO`)KGV}Ww5c2^%d<;E6Sc?2V zCVD`aH!+W))X@oQRcd*OaVK$h#`TmR@hP&jm!jBe5U{aQxizm+ysh=w=-qpmp3Zoe zt5O^fY2k5*Q)LZUYT$z7RJ|n2qy|o>xOP&&-g^3r95)uiw{Cy9Xt6E|RiwC4=Nw5# z2Z09J9Qro=jOeb(OwddQ%pi6mB0}H9{swPOxFnVT-RYql-o){>E4Kg>MX(Q)qaJFI zQxD^uxk)Y1;mCt*PZI)XPaEy3l}uY+r$OGkEHPaqhNC*xO2BHaw!5nqtPs6(lO`QL zB-B|L3)dL#TgqOh;=>ZSEjO(`_|+G7Fh1d54jR6Fb?YTPCz>=!h(r!}Wjj;txkv?|@wgQ#9mEe>znoF=? zbSSnA5BdvI`YXM&no`GDYS#m=j7@yO#!EVdHEEC*Ox=ZnSYMjV(JWp#Z{O4EavbfJ zUFpE@qwPlLvC!(@_6*?CbZ%JM4X}v?BWt^~B@!TJO%Ng{-9uc^F33qoh%mo!Y0kpU`QzH-3w&ig^NF1CMZywqa$z|cM&zcX_EsJt{DEo2 z9SABF6)j8If>SM#rfQqSCX!O*KE9X;>{M^*EG#bVEm{gUXqKWnx5PBTqD)Sf z^w(2^xU16OVCt|a#h@FgWDI9u7x zY~5rDsVb23z>ZCFN0qwM)F2K&CEv6h0QM=*24H;}h9=!@(u0YuCkYPH5h_+T9&?I4 zj=6=+(??led;)H;fy}{IGC|9*W)V8FTEc%)HQwe(wHQzwqJo330ycBQVAhV|`;D@> z(PT5DakNknuBhS)3R@2mapp=lkdj0+I3u-PgN}y<7*! z_YJ$SQbmzZHU!Bh9>hqf*;XLdUiLJF-1vcrd-XbwRdgsy^&1K?@1}GxTsUTM;$)h6g(G40q%nk=8)wL=6%`TrRjh4j)~3s8`P3kwPo<*h8_)ip zFBprDs(~{Z(+zoshp0Sq%Knl_kT5VE5L0I@TMe#_XT$X@a#GYuFK?0G zs$*na8Y}ktSRyf{LQm)#SPy>~bw{A)+rVUum-LsK8V}*Mjp?#3s5D5JgnFaswuMYp y>gH_FAg*&}eCZ-gom3$vDn%9hfOCf;T)Fhvh+^a`G}`V9*ZRMA8}2uI!~X-0_0j_X literal 0 HcmV?d00001 diff --git a/src/NEWS.md b/src/NEWS.md index 1c98766..29b3eb0 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -499,6 +499,13 @@ This section lists changes that do not have deprecation warnings. This change makes `@schedule` redundant with `@async`, so `@schedule` has been deprecated ([#27164](https://github.com/JuliaLang/julia/issues/27164)). + * `norm(A::AbstractMatrix, p=2)` computes no longer the operator/matrix norm but the `norm` of `A` + as for other iterables, i.e. as if it were a vector. Especially, `norm(A::AbstractMatrix)` is the + Frobenius norm. To compute the operator/matrix norm, use the new function `opnorm` ([#27401](https://github.com/JuliaLang/julia/issues/27401)). + + * `dot(u, v)` now acts recursively. Instead of `sum(u[i]' * v[i] for i in ...)`, it computes + `sum(dot(u[i], v[i]) for i in ...)`, similarly to `vecdot` before ([#27401](https://github.com/JuliaLang/julia/issues/27401)). + Library improvements -------------------- @@ -679,6 +686,9 @@ Library improvements * `IOBuffer` can take the `sizehint` keyword argument to suggest a capacity of the buffer ([#25944](https://github.com/JuliaLang/julia/issues/25944)). + * `lstrip` and `rstrip` now accept a predicate function that defaults to `isspace` + ([#27309](https://github.com/JuliaLang/julia/issues/27309)). + * `trunc`, `floor`, `ceil`, and `round` specify `digits`, `sigdigits` and `base` using keyword arguments. ([#26156](https://github.com/JuliaLang/julia/issues/26156), [#26670](https://github.com/JuliaLang/julia/issues/26670)) @@ -1118,9 +1128,6 @@ Deprecated or removed `normalize`, and moved to the new `Unicode` standard library module. `graphemes` has also been moved to that module ([#25021](https://github.com/JuliaLang/julia/issues/25021)). - * The functions `eigs` and `svds` have been moved to the `IterativeEigensolvers` standard - library module ([#24714](https://github.com/JuliaLang/julia/issues/24714)). - * Sparse array functionality has moved to the `SparseArrays` standard library module ([#25249](https://github.com/JuliaLang/julia/issues/25249)). * Linear algebra functionality, and specifically the `LinAlg` module has moved to the @@ -1260,6 +1267,10 @@ Deprecated or removed * `atan2` is now a 2-argument method of `atan` ([#27248](https://github.com/JuliaLang/julia/issues/27248)). + * The functions `eigs` and `svds` have been moved to the `Arpack.jl` package ([#27616](https://github.com/JuliaLang/julia/issues/27616)). + + * `vecdot` and `vecnorm` are deprecated in favor of `dot` and `norm`, respectively ([#27401](https://github.com/JuliaLang/julia/issues/27401)). + Command-line option changes --------------------------- diff --git a/src/base/strings.md b/src/base/strings.md index d178271..95e07e3 100644 --- a/src/base/strings.md +++ b/src/base/strings.md @@ -21,6 +21,8 @@ Base.codeunit Base.codeunits Base.ascii Base.@r_str +Base.SubstitutionString +Base.@s_str Base.@raw_str Base.Docs.@html_str Base.Docs.@text_str diff --git a/src/manual/documentation.md b/src/manual/documentation.md index bfb24a4..20983fd 100644 --- a/src/manual/documentation.md +++ b/src/manual/documentation.md @@ -126,8 +126,8 @@ As in the example above, we recommend following some simple conventions when wri Note that whitespace in your doctest is significant! The doctest will fail if you misalign the output of pretty-printing an array, for example. - You can then run `make -C doc doctest` to run all the doctests in the Julia Manual, which will - ensure that your example works. + You can then run `make -C doc doctest=true` to run all the doctests in the Julia Manual and API + documentation, which will ensure that your example works. To indicate that the output result is truncated, you may write `[...]` at the line where checking should stop. This is useful to diff --git a/src/manual/noteworthy-differences.md b/src/manual/noteworthy-differences.md index 20ba324..da423bc 100644 --- a/src/manual/noteworthy-differences.md +++ b/src/manual/noteworthy-differences.md @@ -49,9 +49,6 @@ may trip up Julia users accustomed to MATLAB: * In Julia, reductions such as [`sum`](@ref), [`prod`](@ref), and [`max`](@ref) are performed over every element of an array when called with a single argument, as in `sum(A)`, even if `A` has more than one dimension. - * In Julia, functions such as [`sort`](@ref) that operate column-wise by default (`sort(A)` is - equivalent to `sort(A,1)`) do not have special behavior for `1xN` arrays; the argument is returned - unmodified since it still performs `sort(A,1)`. To sort a `1xN` matrix like a vector, use `sort(A,2)`. * In Julia, parentheses must be used to call a function with zero arguments, like in [`rand()`](@ref). * Julia discourages the used of semicolons to end statements. The results of statements are not automatically printed (except at the interactive prompt), and lines of code do not need to end diff --git a/src/stdlib/IterativeEigensolvers.md b/src/stdlib/IterativeEigensolvers.md deleted file mode 100644 index 185d2dc..0000000 --- a/src/stdlib/IterativeEigensolvers.md +++ /dev/null @@ -1,208 +0,0 @@ -# [Iterative Eigensolvers](@id lib-itereigen) - -```@meta -DocTestSetup = :(using IterativeEigensolvers, LinearAlgebra, SparseArrays) -``` - -Julia provides bindings to [ARPACK](http://www.caam.rice.edu/software/ARPACK/), which -can be used to perform iterative solutions for eigensystems (using [`eigs`](@ref)) -or singular value decompositions (using [`svds`](@ref)). - -`eigs` calculates the eigenvalues and, optionally, eigenvectors of its input(s) -using implicitly restarted Lanczos or Arnoldi iterations for real symmetric or -general nonsymmetric matrices respectively. - -For the single matrix version, - -`eigs(A; nev=6, ncv=max(20,2*nev+1), which=:LM, tol=0.0, maxiter=300, sigma=nothing, ritzvec=true, v0=zeros((0,))) -> (d,[v,],nconv,niter,nmult,resid)` - -the following keyword arguments are supported: - -* `nev`: Number of eigenvalues -* `ncv`: Number of Krylov vectors used in the computation; should satisfy `nev+1 <= ncv <= n` - for real symmetric problems and `nev+2 <= ncv <= n` for other problems, where `n` is the - size of the input matrix `A`. The default is `ncv = max(20,2*nev+1)`. Note that these - restrictions limit the input matrix `A` to be of dimension at least 2. -* `which`: type of eigenvalues to compute. See the note below. - -| `which` | type of eigenvalues | -|:--------|:--------------------------------------------------------------------------------------------------------------------------| -| `:LM` | eigenvalues of largest magnitude (default) | -| `:SM` | eigenvalues of smallest magnitude | -| `:LR` | eigenvalues of largest real part | -| `:SR` | eigenvalues of smallest real part | -| `:LI` | eigenvalues of largest imaginary part (nonsymmetric or complex `A` only) | -| `:SI` | eigenvalues of smallest imaginary part (nonsymmetric or complex `A` only) | -| `:BE` | compute half of the eigenvalues from each end of the spectrum, biased in favor of the high end. (real symmetric `A` only) | - -* `tol`: parameter defining the relative tolerance for convergence of Ritz values (eigenvalue estimates). - A Ritz value ``θ`` is considered converged when its associated residual - is less than or equal to the product of `tol` and ``max(ɛ^{2/3}, |θ|)``, - where `ɛ = eps(real(eltype(A)))/2` is LAPACK's machine epsilon. - The residual associated with ``θ`` and its corresponding Ritz vector ``v`` - is defined as the norm ``||Av - vθ||``. - The specified value of `tol` should be positive; otherwise, it is ignored - and ``ɛ`` is used instead. - Default: ``ɛ``. - -* `maxiter`: Maximum number of iterations (default = 300) -* `sigma`: Specifies the level shift used in inverse iteration. If `nothing` (default), - defaults to ordinary (forward) iterations. Otherwise, find eigenvalues close to `sigma` - using shift and invert iterations. -* `ritzvec`: Returns the Ritz vectors `v` (eigenvectors) if `true` -* `v0`: starting vector from which to start the iterations - -We can see the various keywords in action in the following examples: -```jldoctest; filter = r"(1|2)-element Array{(Float64|Complex{Float64}),1}:\n (.|\s)*$" -julia> A = Diagonal(1:4); - -julia> λ, ϕ = eigs(A, nev = 2, which=:SM); - -julia> λ -2-element Array{Float64,1}: - 1.0000000000000002 - 2.0 - -julia> B = Diagonal([1., 2., -3im, 4im]); - -julia> λ, ϕ = eigs(B, nev=1, which=:LI); - -julia> λ -1-element Array{Complex{Float64},1}: - 1.3322676295501878e-15 + 4.0im - -julia> λ, ϕ = eigs(B, nev=1, which=:SI); - -julia> λ -1-element Array{Complex{Float64},1}: - -2.498001805406602e-16 - 3.0000000000000018im - -julia> λ, ϕ = eigs(B, nev=1, which=:LR); - -julia> λ -1-element Array{Complex{Float64},1}: - 2.0000000000000004 + 4.0615212488780827e-17im - -julia> λ, ϕ = eigs(B, nev=1, which=:SR); - -julia> λ -1-element Array{Complex{Float64},1}: - -8.881784197001252e-16 + 3.999999999999997im - -julia> λ, ϕ = eigs(B, nev=1, sigma=1.5); - -julia> λ -1-element Array{Complex{Float64},1}: - 1.0000000000000004 + 4.0417078924070745e-18im -``` - -!!! note - The `sigma` and `which` keywords interact: the description of eigenvalues - searched for by `which` do *not* necessarily refer to the eigenvalues of - `A`, but rather the linear operator constructed by the specification of the - iteration mode implied by `sigma`. - - | `sigma` | iteration mode | `which` refers to eigenvalues of | - |:----------------|:---------------------------------|:---------------------------------| - | `nothing` | ordinary (forward) | ``A`` | - | real or complex | inverse with level shift `sigma` | ``(A - \\sigma I )^{-1}`` | - -!!! note - Although `tol` has a default value, the best choice depends strongly on the - matrix `A`. We recommend that users _always_ specify a value for `tol` - which suits their specific needs. - - For details of how the errors in the computed eigenvalues are estimated, see: - - * B. N. Parlett, "The Symmetric Eigenvalue Problem", SIAM: Philadelphia, 2/e - (1998), Ch. 13.2, "Accessing Accuracy in Lanczos Problems", pp. 290-292 ff. - * R. B. Lehoucq and D. C. Sorensen, "Deflation Techniques for an Implicitly - Restarted Arnoldi Iteration", SIAM Journal on Matrix Analysis and - Applications (1996), 17(4), 789–821. doi:10.1137/S0895479895281484 - -For the two-input generalized eigensolution version, - -`eigs(A, B; nev=6, ncv=max(20,2*nev+1), which=:LM, tol=0.0, maxiter=300, sigma=nothing, ritzvec=true, v0=zeros((0,))) -> (d,[v,],nconv,niter,nmult,resid)` - -the following keyword arguments are supported: - -* `nev`: Number of eigenvalues -* `ncv`: Number of Krylov vectors used in the computation; should satisfy `nev+1 <= ncv <= n` - for real symmetric problems and `nev+2 <= ncv <= n` for other problems, where `n` is the - size of the input matrices `A` and `B`. The default is `ncv = max(20,2*nev+1)`. Note that - these restrictions limit the input matrix `A` to be of dimension at least 2. -* `which`: type of eigenvalues to compute. See the note below. - -| `which` | type of eigenvalues | -|:--------|:--------------------------------------------------------------------------------------------------------------------------| -| `:LM` | eigenvalues of largest magnitude (default) | -| `:SM` | eigenvalues of smallest magnitude | -| `:LR` | eigenvalues of largest real part | -| `:SR` | eigenvalues of smallest real part | -| `:LI` | eigenvalues of largest imaginary part (nonsymmetric or complex `A` only) | -| `:SI` | eigenvalues of smallest imaginary part (nonsymmetric or complex `A` only) | -| `:BE` | compute half of the eigenvalues from each end of the spectrum, biased in favor of the high end. (real symmetric `A` only) | - -* `tol`: relative tolerance used in the convergence criterion for eigenvalues, similar to - `tol` in the [`eigs(A)`](@ref) method for the ordinary eigenvalue - problem, but effectively for the eigenvalues of ``B^{-1} A`` instead of ``A``. - See the documentation for the ordinary eigenvalue problem in - [`eigs(A)`](@ref) and the accompanying note about `tol`. -* `maxiter`: Maximum number of iterations (default = 300) -* `sigma`: Specifies the level shift used in inverse iteration. If `nothing` (default), - defaults to ordinary (forward) iterations. Otherwise, find eigenvalues close to `sigma` - using shift and invert iterations. -* `ritzvec`: Returns the Ritz vectors `v` (eigenvectors) if `true` -* `v0`: starting vector from which to start the iterations - -`eigs` returns the `nev` requested eigenvalues in `d`, the corresponding Ritz vectors `v` -(only if `ritzvec=true`), the number of converged eigenvalues `nconv`, the number of -iterations `niter` and the number of matrix vector multiplications `nmult`, as well as the -final residual vector `resid`. - -We can see the various keywords in action in the following examples: -```jldoctest; filter = r"(1|2)-element Array{(Float64|Complex{Float64}),1}:\n (.|\s)*$" -julia> A = sparse(1.0I, 4, 4); B = Diagonal(1:4); - -julia> λ, ϕ = eigs(A, B, nev = 2); - -julia> λ -2-element Array{Float64,1}: - 1.0000000000000002 - 0.5 - -julia> A = Diagonal([1, -2im, 3, 4im]); B = sparse(1.0I, 4, 4); - -julia> λ, ϕ = eigs(A, B, nev=1, which=:SI); - -julia> λ -1-element Array{Complex{Float64},1}: - -1.5720931501039814e-16 - 1.9999999999999984im - -julia> λ, ϕ = eigs(A, B, nev=1, which=:LI); - -julia> λ -1-element Array{Complex{Float64},1}: - 0.0 + 4.000000000000002im -``` - -!!! note - The `sigma` and `which` keywords interact: the description of eigenvalues searched for by - `which` do *not* necessarily refer to the eigenvalue problem ``Av = Bv\\lambda``, but rather - the linear operator constructed by the specification of the iteration mode implied by `sigma`. - - | `sigma` | iteration mode | `which` refers to the problem | - |:----------------|:---------------------------------|:-----------------------------------| - | `nothing` | ordinary (forward) | ``Av = Bv\\lambda`` | - | real or complex | inverse with level shift `sigma` | ``(A - \\sigma B )^{-1}B = v\\nu`` | - - -```@docs -IterativeEigensolvers.eigs(::Any) -IterativeEigensolvers.eigs(::Any, ::Any) -IterativeEigensolvers.svds -``` - -```@meta -DocTestSetup = nothing -``` diff --git a/src/stdlib/LibGit2.md b/src/stdlib/LibGit2.md index 48af940..421540d 100644 --- a/src/stdlib/LibGit2.md +++ b/src/stdlib/LibGit2.md @@ -137,6 +137,7 @@ LibGit2.revcount LibGit2.set_remote_url LibGit2.shortname LibGit2.snapshot +LibGit2.split_cfg_entry LibGit2.status LibGit2.stage LibGit2.tag_create diff --git a/src/stdlib/LinearAlgebra.md b/src/stdlib/LinearAlgebra.md index 3b3d6c9..6e7d122 100644 --- a/src/stdlib/LinearAlgebra.md +++ b/src/stdlib/LinearAlgebra.md @@ -299,7 +299,6 @@ Linear algebra functions in Julia are largely implemented by calling functions f Base.:*(::AbstractMatrix, ::AbstractMatrix) Base.:\(::AbstractMatrix, ::AbstractVecOrMat) LinearAlgebra.dot -LinearAlgebra.vecdot LinearAlgebra.cross LinearAlgebra.factorize LinearAlgebra.Diagonal @@ -358,7 +357,7 @@ LinearAlgebra.diag LinearAlgebra.diagm LinearAlgebra.rank LinearAlgebra.norm -LinearAlgebra.vecnorm +LinearAlgebra.opnorm LinearAlgebra.normalize! LinearAlgebra.normalize LinearAlgebra.cond diff --git a/src/stdlib/Pkg.md b/src/stdlib/Pkg.md index a6bb9ba..f84fc76 100644 --- a/src/stdlib/Pkg.md +++ b/src/stdlib/Pkg.md @@ -58,7 +58,7 @@ official release again. **Project:** a source tree with a standard layout, including a `src` directory for the main body of Julia code, a `test` directory for testing the project, -`docs` for documentation files, and optionally a `build` directory for a build +`docs` for documentation files, and optionally a `deps` directory for a build script and its outputs. A project will typically also have a project file and may optionally have a manifest file: @@ -172,7 +172,7 @@ which is populated at startup based on the value of the `JULIA_DEPOT_PATH` environment variable. The first entry is the “user depot” and should be writable by and owned by the current user. The user depot is where: registries are cloned, new package versions are installed, named environments are created and -updated, package repos are cloned, new compiled package image files are saved, +updated, package repos are cloned, newly compiled package image files are saved, log files are written, development packages are checked out by default, and global configuration data is saved. Later entries in the depot path are treated as read-only and are appropriate for registries, packages, etc. installed and @@ -193,7 +193,317 @@ Since we haven't created our own project yet, we are in the default project, loc To return to the `julia>` prompt, either press backspace when the input line is empty or press Ctrl+C. Help is available by calling `pkg> help`. -To generate files for a new project, use `pkg> generate`. +The documentation here describes using Pkg from the REPL mode. Documentation of using +the Pkg API (by calling `Pkg.` functions) is in progress of being written. + +### Adding packages + +There are two ways of adding packages, either using the `add` command or the `dev` command. +The most frequently used one is `add` and its usage is described first. + +#### Adding registered packages + +In the Pkg REPL packages can be added with the `add` command followed by the name of the package, for example: + +``` +(v0.7) pkg> add Example + Cloning default registries into /Users/kristoffer/.julia/registries + Cloning registry Uncurated from "https://github.com/JuliaRegistries/Uncurated.git" + Updating registry at `~/.julia/registries/Uncurated` + Updating git-repo `https://github.com/JuliaRegistries/Uncurated.git` + Resolving package versions... + Updating `~/.julia/environments/v0.7/Project.toml` + [7876af07] + Example v0.5.1 + Updating `~/.julia/environments/v0.7/Manifest.toml` + [7876af07] + Example v0.5.1 + [8dfed614] + Test +``` + +Here we added the package Example to the current project. In this example, we are using a fresh Julia installation, +and this is our first time adding a package using Pkg. By default, Pkg clones Julia's Uncurated registry, +and uses this registry to look up packages requested for inclusion in the current environment. +The status update shows a short form of the package UUID to the left, then the package name, and the version. +Since standard libraries (e.g. `Test`) are shipped with Julia, they do not have a version. The project status contains the packages +you have added yourself, in this case, `Example`: + +``` +(v0.7) pkg> st + Status `Project.toml` + [7876af07] Example v0.5.1 +``` + +The manifest status, in addition, includes the dependencies of explicitly added packages. + +``` +(v0.7) pkg> st --manifest + Status `Manifest.toml` + [7876af07] Example v0.5.1 + [8dfed614] Test +``` + +It is possible to add multiple packages in one command as `pkg> add A B C`. + +After a package is added to the project, it can be loaded in Julia: + +``` +julia> using Example + +julia> Example.hello("User") +"Hello, User" +``` + +A specific version can be installed by appending a version after a `@` symbol, e.g. `@v0.4`, to the package name: + +``` +(v0.7) pkg> add Example@0.4 + Resolving package versions... + Updating `~/.julia/environments/v0.7/Project.toml` + [7876af07] + Example v0.4.1 + Updating `~/.julia/environments/v0.7/Manifest.toml` + [7876af07] + Example v0.4.1 +``` + +If the master branch (or a certain commit SHA) of `Example` has a hotfix that has not yet included in a registered version, +we can explicitly track a branch (or commit) by appending `#branch` (or `#commit`) to the package name: + +``` +(v0.7) pkg> add Example#master + Updating git-repo `https://github.com/JuliaLang/Example.jl.git` + Resolving package versions... + Updating `~/.julia/environments/v0.7/Project.toml` + [7876af07] ~ Example v0.5.1 ⇒ v0.5.1+ #master [https://github.com/JuliaLang/Example.jl.git] + Updating `~/.julia/environments/v0.7/Manifest.toml` + [7876af07] ~ Example v0.5.1 ⇒ v0.5.1+ #master [https://github.com/JuliaLang/Example.jl.git] +``` + +The status output now shows that we are tracking the `master` branch of `Example`. +When updating packages, we will pull updates from that branch. + +To go back to tracking the registry version of `Example`, the command `free` is used: + +``` +(v0.7) pkg> free Example + Resolving package versions... + Updating `~/.julia/environments/v0.7/Project.toml` + [7876af07] ~ Example v0.5.1+ #master [https://github.com/JuliaLang/Example.jl.git] ⇒ v0.5.1 + Updating `~/.julia/environments/v0.7/Manifest.toml` + [7876af07] ~ Example v0.5.1+ #master [https://github.com/JuliaLang/Example.jl.git] ⇒ v0.5.1 +``` + + +#### Adding unregistered packages + +If a package is not in a registry, it can still be added by instead of the package name giving the URL to the repository to `add`. + +``` +(v0.7) pkg> add https://github.com/fredrikekre/ImportMacros.jl + Updating git-repo `https://github.com/fredrikekre/ImportMacros.jl` + Resolving package versions... +Downloaded MacroTools ─ v0.4.1 + Updating `~/.julia/environments/v0.7/Project.toml` + [e6797606] + ImportMacros v0.0.0 # [https://github.com/fredrikekre/ImportMacros.jl] + Updating `~/.julia/environments/v0.7/Manifest.toml` + [e6797606] + ImportMacros v0.0.0 # [https://github.com/fredrikekre/ImportMacros.jl] + [1914dd2f] + MacroTools v0.4.1 +``` + +The dependencies of the unregistered package (here `MacroTools`) got installed. +For unregistered packages we could have given a branch (or commit SHA) to track using `#`, just like for registered packages. + + +#### Adding a local package + +Instead of giving a URL of a git repo to `add` we could instead have given a local path to a git repo. +This works similarly to adding a URL. The local repository will be tracked (at some branch) and updates +from that local repo are pulled when packages are updated. +Note that changes to files in the local package repository will not immediately be reflected when loading that package. +The changes would have to be committed and the packages updated in order to pull in the changes. + +#### Developing packages + +By only using `add` your Manifest will always have a "reproducible state", in other words, as long as the repositories and registries used are still accessible +it is possible to retrieve the exact state of all the dependencies in the project. This has the advantage that you can send your project (`Project.toml` +and `Manifest.toml`) to someone else and they can "instantiate" that project in the same state as you had it locally. +However, when you are developing a package, it is more convenient to load packages at their current state at some path. For this reason, the `dev` command exists. + +Let's try to `dev` a registered package: + +``` +(v0.7) pkg> dev Example + Updating git-repo `https://github.com/JuliaLang/Example.jl.git` + Resolving package versions... + Updating `~/.julia/environments/v0.7/Project.toml` + [7876af07] + Example v0.5.1+ [`~/.julia/dev/Example`] + Updating `~/.julia/environments/v0.7/Manifest.toml` + [7876af07] + Example v0.5.1+ [`~/.julia/dev/Example`] +``` + +The `dev` command fetches a full clone of the package to `~/.julia/dev/` (the path can be changed by setting the environment variable `JULIA_PKG_DEVDIR`). +When importing `Example` julia will now import it from `~/.julia/dev/Example` and whatever local changes have been made to the files in that path are consequently +reflected in the code loaded. When we used `add` we said that we tracked the package repository, we here say that we track the path itself. +Note that the package manager will never touch any of the files at a tracked path. It is therefore up to you to pull updates, change branches etc. +If we try to `dev` a package at some branch that already exists at `~/.julia/dev/` the package manager we will simply use the existing path. +For example: + +``` +(v0.7) pkg> dev Example#master + Updating git-repo `https://github.com/JuliaLang/Example.jl.git` +[ Info: Path `/Users/kristoffer/.julia/dev/Example` exists and looks like the correct package, using existing path instead of cloning +``` + +Note the info message saying that it is using the existing path. This means that you cannot use `dev` to e.g. change branches of +an already developed package. + +If `dev` is used on a local path, that path to that package is recorded and used when loading that package. + +To stop tracking a path and use the registered version again, use `free` + +``` +(v0.7) pkg> free Example + Resolving package versions... + Updating `~/.julia/environments/v0.7/Project.toml` + [7876af07] ↓ Example v0.5.1+ [`~/.julia/dev/Example`] ⇒ v0.5.1 + Updating `~/.julia/environments/v0.7/Manifest.toml` + [7876af07] ↓ Example v0.5.1+ [`~/.julia/dev/Example`] ⇒ v0.5.1 +``` + +It should be pointed out that by using `dev` your project is now inherently stateful. +Its state depends on the current content of the files at the path and the manifest cannot be "instantiated" by someone else without +knowing the exact content of all the packages that are tracking a path. + +Note that if you add a dependency to a package that tracks a local path, the Manifest (which contains the whole dependency graph) will become +out of sync with the actual dependency graph. This means that the package will not be able to load that dependency since it is not recorded +in the Manifest. To update sync the Manifest, use the REPL command `resolve`. + +### Removing packages + +Packages can be removed from the current project by using `pkg> rm Package`. +This will only remove packages that exist in the project, to remove a package that only +exists as a dependency use `pkg> rm --manifest DepPackage`. +Note that this will remove all packages that depends on `DepPackage`. + +### Updating packages + +When new versions of packages the project is using are released, it is a good idea to update. Simply calling `up` will try to update *all* the dependencies of the project +to the latest compatible version. Sometimes this is not what you want. You can specify a subset of the dependencies to upgrade by giving them as arguments to `up`, e.g: + +``` +(v0.7) pkg> up Example +``` + +The version of all other packages direct dependencies will stay the same. If you only want to update the minor version of packages, to reduce the risk that your project breaks, you can give the `--minor` flag, e.g: + +``` +(v0.7) pkg> up --minor Example +``` + +Packages that track a repository are not updated when a minor upgrade is done. +Packages that track a path are never touched by the package manager. + +### Pinning a package + +A pinned package will never be updated. A package can be pinned using `pin` as for example + +``` +(v0.7) pkg> pin Example + Resolving package versions... + Updating `~/.julia/environments/v0.7/Project.toml` + [7876af07] ~ Example v0.5.1 ⇒ v0.5.1 ⚲ + Updating `~/.julia/environments/v0.7/Manifest.toml` + [7876af07] ~ Example v0.5.1 ⇒ v0.5.1 ⚲ +``` + +Note the pin symbol `⚲` showing that the package is pinned. Removing the pin is done using `free` + +``` +(v0.7) pkg> free Example + Updating `~/.julia/environments/v0.7/Project.toml` + [7876af07] ~ Example v0.5.1 ⚲ ⇒ v0.5.1 + Updating `~/.julia/environments/v0.7/Manifest.toml` + [7876af07] ~ Example v0.5.1 ⚲ ⇒ v0.5.1 +``` + +### Testing packages + +The tests for a package can be run using `test`command: + +``` +(v0.7) pkg> test Example + Testing Example + Testing Example tests passed +``` + +### Building packages + +The build step of a package is automatically run when a package is first installed. +The output of the build process is directed to a file. +To explicitly run the build step for a package the `build` command is used: + +``` +(v0.7) pkg> build MbedTLS + Building MbedTLS → `~/.julia/packages/MbedTLS/h1Vu/deps/build.log` + +shell> cat ~/.julia/packages/MbedTLS/h1Vu/deps/build.log +┌ Warning: `wait(t::Task)` is deprecated, use `fetch(t)` instead. +│ caller = macro expansion at OutputCollector.jl:63 [inlined] +└ @ Core OutputCollector.jl:63 +... +[ Info: using prebuilt binaries +``` + +## Creating your own projects + +So far we have added packages to the default project at `~/.julia/environments/v0.7`, it is, however, easy to create other, independent, projects. +It should be pointed out if two projects uses the same package at the same version, the content of this package is not duplicated. +This is done using the `init` command. Below we make a new directory and create a new project in it: + +``` +shell> mkdir MyProject + +shell> cd MyProject +/Users/kristoffer/MyProject + +(v0.7) pkg> init +Initialized project at /Users/kristoffer/MyProject/Project.toml + +(MyProject) pkg> st + Status `Project.toml` +``` + +Note that the REPL prompt changed when the new project was initiated. Since this is a newly created project, the status command show it contains no packages. +Packages added here again in a completely separate environment from the one earlier used. + +## Garbage collecting old, unused packages + +As packages are updated and projects are deleted, installed packages that were once used will inevitably +become old and not used from any existing project. +Pkg keeps a log of all projects used so it can go through the log and see exactly which projects still exist +and what packages those projects used. The rest can be deleted. +This is done with the `gc` command: + +``` +(v0.7) pkg> gc + Active manifests at: + `/Users/kristoffer/BinaryProvider/Manifest.toml` + ... + `/Users/kristoffer/Compat.jl/Manifest.toml` + Deleted /Users/kristoffer/.julia/packages/BenchmarkTools/1cAj: 146.302 KiB + Deleted /Users/kristoffer/.julia/packages/Cassette/BXVB: 795.557 KiB + ... + Deleted /Users/kristoffer/.julia/packages/WeakRefStrings/YrK6: 27.328 KiB + Deleted 36 package installations: 113.205 MiB +``` + +Note that only packages in `~/.julia/packages` are deleted. + +## Creating your own packages + +A package is a project with a `name`, `uuid` and `version` entry in the `Project.toml` file `src/PackageName.jl` file that defines the module `PackageName`. +This file is executed when the package is loaded. + +### Generating files for a package + +To generate files for a new package, use `pkg> generate`. ``` (v0.7) pkg> generate HelloWorld @@ -242,7 +552,7 @@ julia> HelloWorld.greet() Hello World! ``` -### Adding packages to the project +### Adding dependencies to the project Let’s say we want to use the standard library package `Random` and the registered package `JSON` in our project. We simply `add` these packages (note how the prompt now shows the name of the newly generated project, @@ -285,130 +595,90 @@ julia> HelloWorld.greet_alien() Hello aT157rHV ``` -Sometimes we might want to use the very latest, unreleased version of a package, or perhaps a specific branch in the package -git repository. We can use e.g. the `master` branch of `JSON` by specifying the branch after a `#` when adding the package: +### Adding a build step to the package. -``` -(HelloWorld) pkg> add JSON#master - Cloning package from https://github.com/JuliaIO/JSON.jl.git - Resolving package versions... - Updating "~/Documents/HelloWorld/Project.toml" - [682c06a0] ~ JSON v0.17.1 ⇒ v0.17.1+ #master - Updating "~/Documents/HelloWorld/Manifest.toml" - [682c06a0] ~ JSON v0.17.1 ⇒ v0.17.1+ #master -``` - -If we want to use a package that has not been registered in a registry, we can `add` its git repository url: +The build step is executed the first time a package is installed or when explicitly invoked with `build`. +A package is built by executing the file `deps/build.jl`. ``` -(HelloWorld) pkg> add https://github.com/fredrikekre/ImportMacros.jl - Cloning package from https://github.com/fredrikekre/ImportMacros.jl - Resolving package versions... -Downloaded MacroTools ─ v0.4.0 - Updating "~/Documents/HelloWorld/Project.toml" - [5adcef86] + ImportMacros v0.1.0 #master - Updating "~/Documents/HelloWorld/Manifest.toml" - [5adcef86] + ImportMacros v0.1.0 #master - [1914dd2f] + MacroTools v0.4.0 -``` - -The dependencies of the unregistered package (here `MacroTools`) got installed. -For unregistered packages we could have given a branch (or commit SHA) to track using `#`, just like for registered packages. - - -## Developing packages +shell> cat deps/build.log +I am being built... -Let’s say we found a bug in one of our dependencies, e.g. `JSON` that we want to fix. We can get the full git-repo using the `develop` command - -``` -(HelloWorld) pkg> develop JSON - Cloning package from https://github.com/JuliaIO/JSON.jl.git - Resolving package versions... - Updating "~/Documents/HelloWorld/Project.toml" - [682c06a0] + JSON v0.17.1+ [~/.julia/dev/JSON] -... -``` - -By default, the package gets cloned to the `~/.julia/dev` folder but can also be set by the `JULIA_PKG_DEVDIR` environment variable. -When we have fixed the bug and checked that `JSON` now works correctly with our project, we can make a PR to the `JSON` repository. -When the PR has been merged we can go over to track the master branch and finally when a new release of `JSON` is made, we can go back to using the versioned `JSON` using the command `free` and `update` (see next section): - -``` -(HelloWorld) pkg> free JSON +(HelloWorld) pkg> build + Building HelloWorld → `deps/build.log` Resolving package versions... - Updating "~/Documents/HelloWorld/Project.toml" - [682c06a0] ~ JSON v0.17.1+ #master ⇒ v0.17.1 - Updating "~/Documents/HelloWorld/Manifest.toml" - [682c06a0] ~ JSON v0.17.1+ #master ⇒ v0.17.1 -``` - -It is also possible to give a local path as the argument to `develop` which will not clone anything but simply use that directory for the package. - -Overriding the dependency path for a non-registered package is done by giving the git-repo url as an argument to `develop`. - -## Updating dependencies - -When new versions of packages the project is using are released, it is a good idea to update. Simply calling `up` will try to update *all* the dependencies of the project. Sometimes this is not what you want. You can specify a subset of the dependencies to upgrade by giving them as arguments to `up`, e.g: -``` -(HelloWorld) pkg> up JSON +shell> cat deps/build.log +I am being built... ``` -The version of all other direct dependencies will stay the same. If you only want to update the minor version of packages, to reduce the risk that your project breaks, you can give the `--minor` flag, e.g: +If the build step fails, the output of the build step is printed to the console ``` -(HelloWorld) pkg> up --minor JSON -``` - -Packages that track a branch are not updated when a minor upgrade is done. -Developed packages are never touched by the package manager. - -If you just want to install the packages that are given by the current `Manifest.toml` use +shell> cat deps/build.jl +error("Ooops") -``` -(HelloWorld) pkg> instantiate +(HelloWorld) pkg> build + Building HelloWorld → `deps/build.log` + Resolving package versions... +┌ Error: Error building `HelloWorld`: +│ ERROR: LoadError: Ooops +│ Stacktrace: +│ [1] error(::String) at ./error.jl:33 +│ [2] top-level scope at none:0 +│ [3] include at ./boot.jl:317 [inlined] +│ [4] include_relative(::Module, ::String) at ./loading.jl:1071 +│ [5] include(::Module, ::String) at ./sysimg.jl:29 +│ [6] include(::String) at ./client.jl:393 +│ [7] top-level scope at none:0 +│ in expression starting at /Users/kristoffer/.julia/dev/Pkg/HelloWorld/deps/build.jl:1 +└ @ Pkg.Operations Operations.jl:938 ``` -## Precompiling the project +### Adding tests to the package -The REPL command `precompile` can be used to precompile all the dependencies in the project. You can for example do +When a package is tested the file `test/runtests.jl` is executed. ``` -(HelloWorld) pkg> update; precompile +shell> cat test/runtests.jl +println("Testing...") +(HelloWorld) pkg> test + Testing HelloWorld + Resolving package versions... +Testing... + Testing HelloWorld tests passed ``` -do update the dependencies and then precompile them. - -## Preview mode +#### Test-specific dependencies -If you just want to see the effects of running a command, but not change your state you can `preview` a command. -For example: +Sometimes one might to want to use some packages only at testing time but not enforce a dependency on them when the package is used. +This is possible by adding dependencies to a "test target" to the Project file. Here we add the `Test` standard library as a +test-only dependency by adding the following to the Project file: ``` -(HelloWorld) pkg> preview add Plots +[target.test.deps] +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" ``` -or +We can now use `Test` in the test script and we can see that it gets installed on testing: ``` -(HelloWorld) pkg> preview up -``` - -will show you the effects of adding `Plots`, or doing a full upgrade, respectively, would have on your project. -However, nothing would be installed and your `Project.toml` and `Manfiest.toml` are untouched. +shell> cat test/runtests.jl +using Test +@test 1 == 1 -## Using someone else's project - -Simple clone their project using e.g. `git clone`, `cd` to the project directory and call - -``` -(SomeProject) pkg> instantiate +(HelloWorld) pkg> test + Testing HelloWorld + Resolving package versions... + Updating `/var/folders/64/76tk_g152sg6c6t0b4nkn1vw0000gn/T/tmpPzUPPw/Project.toml` + [d8327f2a] + HelloWorld v0.1.0 [`~/.julia/dev/Pkg/HelloWorld`] + [8dfed614] + Test + Updating `/var/folders/64/76tk_g152sg6c6t0b4nkn1vw0000gn/T/tmpPzUPPw/Manifest.toml` + [d8327f2a] + HelloWorld v0.1.0 [`~/.julia/dev/Pkg/HelloWorld`] + Testing HelloWorld tests passed``` ``` -If the project contains a manifest, this will install the packages in the same state that is given by that manifest. -Otherwise, it will resolve the latest versions of the dependencies compatible with the project. - -## Compatibility +### Compatibility Compatibility refers to the ability to restrict what version of the dependencies that your project is compatible with. If the compatibility for a dependency is not given, the project is assumed to be compatible with all versions of that dependency. @@ -427,14 +697,14 @@ The format of the version specifier is described in detail below. !!! info There is currently no way to give compatibility from the Pkg REPL mode so for now, one has to manually edit the project file. -### Version specifier format +#### Version specifier format Similar to other package managers, the Julia package manager respects [semantic versioning](https://semver.org/) (semver). As an example, a version specifier is given as e.g. `1.2.3` is therefore assumed to be compatible with the versions `[1.2.3 - 2.0.0)` where `)` is a non-inclusive upper bound. More specifically, a version specifier is either given as a **caret specifier**, e.g. `^1.2.3` or a **tilde specifier** `~1.2.3`. Caret specifiers are the default and hence `1.2.3 == ^1.2.3`. The difference between a caret and tilde is described in the next section. -#### Caret specifiers +##### Caret specifiers A caret specifier allows upgrade that would be compatible according to semver. An updated dependency is considered compatible if the new version does not modify the left-most non zero digit in the version specifier. @@ -454,7 +724,7 @@ Some examples are shown below. While the semver specification says that all versions with a major version of 0 are incompatible with each other, we have made that choice that a version given as `0.a.b` is considered compatible with `0.a.c` if `a != 0` and `c >= b`. -#### Tilde specifiers +##### Tilde specifiers A tilde specifier provides more limited upgrade possibilities. With a tilde, only the last specified digit is allowed to increment by one. This gives the following example. @@ -464,3 +734,43 @@ This gives the following example. ~1.2 = [1.2.0, 1.3.0) ~1 = [1.0.0, 2.0.0) ``` + + +## Precompiling a project + +The REPL command `precompile` can be used to precompile all the dependencies in the project. You can for example do + +``` +(HelloWorld) pkg> update; precompile +``` + +do update the dependencies and then precompile them. + +## Preview mode + +If you just want to see the effects of running a command, but not change your state you can `preview` a command. +For example: + +``` +(HelloWorld) pkg> preview add Plots +``` + +or + +``` +(HelloWorld) pkg> preview up +``` + +will show you the effects of adding `Plots`, or doing a full upgrade, respectively, would have on your project. +However, nothing would be installed and your `Project.toml` and `Manifest.toml` are untouched. + +## Using someone else's project + +Simple clone their project using e.g. `git clone`, `cd` to the project directory and call + +``` +(SomeProject) pkg> instantiate +``` + +If the project contains a manifest, this will install the packages in the same state that is given by that manifest. +Otherwise, it will resolve the latest versions of the dependencies compatible with the project. diff --git a/src/stdlib/iterativeeigensolvers.md b/src/stdlib/iterativeeigensolvers.md deleted file mode 100644 index 185d2dc..0000000 --- a/src/stdlib/iterativeeigensolvers.md +++ /dev/null @@ -1,208 +0,0 @@ -# [Iterative Eigensolvers](@id lib-itereigen) - -```@meta -DocTestSetup = :(using IterativeEigensolvers, LinearAlgebra, SparseArrays) -``` - -Julia provides bindings to [ARPACK](http://www.caam.rice.edu/software/ARPACK/), which -can be used to perform iterative solutions for eigensystems (using [`eigs`](@ref)) -or singular value decompositions (using [`svds`](@ref)). - -`eigs` calculates the eigenvalues and, optionally, eigenvectors of its input(s) -using implicitly restarted Lanczos or Arnoldi iterations for real symmetric or -general nonsymmetric matrices respectively. - -For the single matrix version, - -`eigs(A; nev=6, ncv=max(20,2*nev+1), which=:LM, tol=0.0, maxiter=300, sigma=nothing, ritzvec=true, v0=zeros((0,))) -> (d,[v,],nconv,niter,nmult,resid)` - -the following keyword arguments are supported: - -* `nev`: Number of eigenvalues -* `ncv`: Number of Krylov vectors used in the computation; should satisfy `nev+1 <= ncv <= n` - for real symmetric problems and `nev+2 <= ncv <= n` for other problems, where `n` is the - size of the input matrix `A`. The default is `ncv = max(20,2*nev+1)`. Note that these - restrictions limit the input matrix `A` to be of dimension at least 2. -* `which`: type of eigenvalues to compute. See the note below. - -| `which` | type of eigenvalues | -|:--------|:--------------------------------------------------------------------------------------------------------------------------| -| `:LM` | eigenvalues of largest magnitude (default) | -| `:SM` | eigenvalues of smallest magnitude | -| `:LR` | eigenvalues of largest real part | -| `:SR` | eigenvalues of smallest real part | -| `:LI` | eigenvalues of largest imaginary part (nonsymmetric or complex `A` only) | -| `:SI` | eigenvalues of smallest imaginary part (nonsymmetric or complex `A` only) | -| `:BE` | compute half of the eigenvalues from each end of the spectrum, biased in favor of the high end. (real symmetric `A` only) | - -* `tol`: parameter defining the relative tolerance for convergence of Ritz values (eigenvalue estimates). - A Ritz value ``θ`` is considered converged when its associated residual - is less than or equal to the product of `tol` and ``max(ɛ^{2/3}, |θ|)``, - where `ɛ = eps(real(eltype(A)))/2` is LAPACK's machine epsilon. - The residual associated with ``θ`` and its corresponding Ritz vector ``v`` - is defined as the norm ``||Av - vθ||``. - The specified value of `tol` should be positive; otherwise, it is ignored - and ``ɛ`` is used instead. - Default: ``ɛ``. - -* `maxiter`: Maximum number of iterations (default = 300) -* `sigma`: Specifies the level shift used in inverse iteration. If `nothing` (default), - defaults to ordinary (forward) iterations. Otherwise, find eigenvalues close to `sigma` - using shift and invert iterations. -* `ritzvec`: Returns the Ritz vectors `v` (eigenvectors) if `true` -* `v0`: starting vector from which to start the iterations - -We can see the various keywords in action in the following examples: -```jldoctest; filter = r"(1|2)-element Array{(Float64|Complex{Float64}),1}:\n (.|\s)*$" -julia> A = Diagonal(1:4); - -julia> λ, ϕ = eigs(A, nev = 2, which=:SM); - -julia> λ -2-element Array{Float64,1}: - 1.0000000000000002 - 2.0 - -julia> B = Diagonal([1., 2., -3im, 4im]); - -julia> λ, ϕ = eigs(B, nev=1, which=:LI); - -julia> λ -1-element Array{Complex{Float64},1}: - 1.3322676295501878e-15 + 4.0im - -julia> λ, ϕ = eigs(B, nev=1, which=:SI); - -julia> λ -1-element Array{Complex{Float64},1}: - -2.498001805406602e-16 - 3.0000000000000018im - -julia> λ, ϕ = eigs(B, nev=1, which=:LR); - -julia> λ -1-element Array{Complex{Float64},1}: - 2.0000000000000004 + 4.0615212488780827e-17im - -julia> λ, ϕ = eigs(B, nev=1, which=:SR); - -julia> λ -1-element Array{Complex{Float64},1}: - -8.881784197001252e-16 + 3.999999999999997im - -julia> λ, ϕ = eigs(B, nev=1, sigma=1.5); - -julia> λ -1-element Array{Complex{Float64},1}: - 1.0000000000000004 + 4.0417078924070745e-18im -``` - -!!! note - The `sigma` and `which` keywords interact: the description of eigenvalues - searched for by `which` do *not* necessarily refer to the eigenvalues of - `A`, but rather the linear operator constructed by the specification of the - iteration mode implied by `sigma`. - - | `sigma` | iteration mode | `which` refers to eigenvalues of | - |:----------------|:---------------------------------|:---------------------------------| - | `nothing` | ordinary (forward) | ``A`` | - | real or complex | inverse with level shift `sigma` | ``(A - \\sigma I )^{-1}`` | - -!!! note - Although `tol` has a default value, the best choice depends strongly on the - matrix `A`. We recommend that users _always_ specify a value for `tol` - which suits their specific needs. - - For details of how the errors in the computed eigenvalues are estimated, see: - - * B. N. Parlett, "The Symmetric Eigenvalue Problem", SIAM: Philadelphia, 2/e - (1998), Ch. 13.2, "Accessing Accuracy in Lanczos Problems", pp. 290-292 ff. - * R. B. Lehoucq and D. C. Sorensen, "Deflation Techniques for an Implicitly - Restarted Arnoldi Iteration", SIAM Journal on Matrix Analysis and - Applications (1996), 17(4), 789–821. doi:10.1137/S0895479895281484 - -For the two-input generalized eigensolution version, - -`eigs(A, B; nev=6, ncv=max(20,2*nev+1), which=:LM, tol=0.0, maxiter=300, sigma=nothing, ritzvec=true, v0=zeros((0,))) -> (d,[v,],nconv,niter,nmult,resid)` - -the following keyword arguments are supported: - -* `nev`: Number of eigenvalues -* `ncv`: Number of Krylov vectors used in the computation; should satisfy `nev+1 <= ncv <= n` - for real symmetric problems and `nev+2 <= ncv <= n` for other problems, where `n` is the - size of the input matrices `A` and `B`. The default is `ncv = max(20,2*nev+1)`. Note that - these restrictions limit the input matrix `A` to be of dimension at least 2. -* `which`: type of eigenvalues to compute. See the note below. - -| `which` | type of eigenvalues | -|:--------|:--------------------------------------------------------------------------------------------------------------------------| -| `:LM` | eigenvalues of largest magnitude (default) | -| `:SM` | eigenvalues of smallest magnitude | -| `:LR` | eigenvalues of largest real part | -| `:SR` | eigenvalues of smallest real part | -| `:LI` | eigenvalues of largest imaginary part (nonsymmetric or complex `A` only) | -| `:SI` | eigenvalues of smallest imaginary part (nonsymmetric or complex `A` only) | -| `:BE` | compute half of the eigenvalues from each end of the spectrum, biased in favor of the high end. (real symmetric `A` only) | - -* `tol`: relative tolerance used in the convergence criterion for eigenvalues, similar to - `tol` in the [`eigs(A)`](@ref) method for the ordinary eigenvalue - problem, but effectively for the eigenvalues of ``B^{-1} A`` instead of ``A``. - See the documentation for the ordinary eigenvalue problem in - [`eigs(A)`](@ref) and the accompanying note about `tol`. -* `maxiter`: Maximum number of iterations (default = 300) -* `sigma`: Specifies the level shift used in inverse iteration. If `nothing` (default), - defaults to ordinary (forward) iterations. Otherwise, find eigenvalues close to `sigma` - using shift and invert iterations. -* `ritzvec`: Returns the Ritz vectors `v` (eigenvectors) if `true` -* `v0`: starting vector from which to start the iterations - -`eigs` returns the `nev` requested eigenvalues in `d`, the corresponding Ritz vectors `v` -(only if `ritzvec=true`), the number of converged eigenvalues `nconv`, the number of -iterations `niter` and the number of matrix vector multiplications `nmult`, as well as the -final residual vector `resid`. - -We can see the various keywords in action in the following examples: -```jldoctest; filter = r"(1|2)-element Array{(Float64|Complex{Float64}),1}:\n (.|\s)*$" -julia> A = sparse(1.0I, 4, 4); B = Diagonal(1:4); - -julia> λ, ϕ = eigs(A, B, nev = 2); - -julia> λ -2-element Array{Float64,1}: - 1.0000000000000002 - 0.5 - -julia> A = Diagonal([1, -2im, 3, 4im]); B = sparse(1.0I, 4, 4); - -julia> λ, ϕ = eigs(A, B, nev=1, which=:SI); - -julia> λ -1-element Array{Complex{Float64},1}: - -1.5720931501039814e-16 - 1.9999999999999984im - -julia> λ, ϕ = eigs(A, B, nev=1, which=:LI); - -julia> λ -1-element Array{Complex{Float64},1}: - 0.0 + 4.000000000000002im -``` - -!!! note - The `sigma` and `which` keywords interact: the description of eigenvalues searched for by - `which` do *not* necessarily refer to the eigenvalue problem ``Av = Bv\\lambda``, but rather - the linear operator constructed by the specification of the iteration mode implied by `sigma`. - - | `sigma` | iteration mode | `which` refers to the problem | - |:----------------|:---------------------------------|:-----------------------------------| - | `nothing` | ordinary (forward) | ``Av = Bv\\lambda`` | - | real or complex | inverse with level shift `sigma` | ``(A - \\sigma B )^{-1}B = v\\nu`` | - - -```@docs -IterativeEigensolvers.eigs(::Any) -IterativeEigensolvers.eigs(::Any, ::Any) -IterativeEigensolvers.svds -``` - -```@meta -DocTestSetup = nothing -``` diff --git a/src/stdlib/linearalgebra.md b/src/stdlib/linearalgebra.md index 3b3d6c9..6e7d122 100644 --- a/src/stdlib/linearalgebra.md +++ b/src/stdlib/linearalgebra.md @@ -299,7 +299,6 @@ Linear algebra functions in Julia are largely implemented by calling functions f Base.:*(::AbstractMatrix, ::AbstractMatrix) Base.:\(::AbstractMatrix, ::AbstractVecOrMat) LinearAlgebra.dot -LinearAlgebra.vecdot LinearAlgebra.cross LinearAlgebra.factorize LinearAlgebra.Diagonal @@ -358,7 +357,7 @@ LinearAlgebra.diag LinearAlgebra.diagm LinearAlgebra.rank LinearAlgebra.norm -LinearAlgebra.vecnorm +LinearAlgebra.opnorm LinearAlgebra.normalize! LinearAlgebra.normalize LinearAlgebra.cond From c51e5f46e22b44b671dcebb047c4f07af863621e Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Thu, 28 Jun 2018 14:03:10 +0900 Subject: [PATCH 038/153] update Julia Commit e2de9b3d2e --- codex/NEWS.md | 7 ++ codex/base/base.md | 3 +- codex/manual/arrays.md | 42 ++++---- codex/manual/faq.md | 54 +++++++++- codex/manual/functions.md | 6 ++ codex/manual/interfaces.md | 2 +- codex/manual/mathematical-operations.md | 2 +- codex/manual/metaprogramming.md | 43 ++++++-- codex/manual/performance-tips.md | 128 ++++++++++++++++++------ codex/manual/style-guide.md | 21 ---- codex/manual/types.md | 17 +++- codex/manual/variables-and-scoping.md | 6 +- codex/stdlib/InteractiveUtils.md | 1 + codex/stdlib/Pkg.md | 24 +++-- codex/stdlib/Random.md | 2 +- codex/stdlib/random.md | 2 +- src/.NEWS.md.swp | Bin 110592 -> 0 bytes src/NEWS.md | 7 ++ src/base/base.md | 3 +- src/manual/arrays.md | 41 ++++---- src/manual/faq.md | 54 +++++++++- src/manual/functions.md | 6 ++ src/manual/interfaces.md | 2 +- src/manual/mathematical-operations.md | 2 +- src/manual/metaprogramming.md | 43 ++++++-- src/manual/performance-tips.md | 128 ++++++++++++++++++------ src/manual/style-guide.md | 21 ---- src/manual/types.md | 17 +++- src/manual/variables-and-scoping.md | 6 +- src/stdlib/InteractiveUtils.md | 1 + src/stdlib/Pkg.md | 24 +++-- src/stdlib/Random.md | 2 +- src/stdlib/random.md | 2 +- 33 files changed, 513 insertions(+), 206 deletions(-) delete mode 100644 src/.NEWS.md.swp diff --git a/codex/NEWS.md b/codex/NEWS.md index 16d93d3..40c86ba 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -552,6 +552,9 @@ Library improvements [ANSI color codes](https://en.wikipedia.org/wiki/ANSI_escape_code) ([#25067](https://github.com/JuliaLang/julia/issues/25067)), rather than using the undocumented `Base.have_color` global flag. + * `print_with_color` has been deprecated in favor of + `printstyled([io], xs...; bold=false, color=:normal)` for printing styled text ([#25522](https://github.com/JuliaLang/julia/issues/25522)). + * Functions `first` and `last` now accept `nchar` argument for `AbstractString`. If this argument is used they return a string consisting of first/last `nchar` characters from the original string ([#23960](https://github.com/JuliaLang/julia/issues/23960)). @@ -1283,6 +1286,10 @@ Deprecated or removed * `vecdot` and `vecnorm` are deprecated in favor of `dot` and `norm`, respectively ([#27401](https://github.com/JuliaLang/julia/issues/27401)). + * `clipboard` has been moved to the `InteractiveUtils` standard library package + (along with other utilities mostly used at the interactive prompt, such as `edit` + and `less`) ([#27635](https://github.com/JuliaLang/julia/issues/27635)). + Command-line option changes --------------------------- diff --git a/codex/base/base.md b/codex/base/base.md index 030ffe3..cea99f4 100644 --- a/codex/base/base.md +++ b/codex/base/base.md @@ -22,8 +22,6 @@ Base.exit Base.atexit Base.isinteractive Base.summarysize -Base.clipboard(::Any) -Base.clipboard() Base.require Base.compilecache Base.__precompile__ @@ -219,6 +217,7 @@ Base.gensym Base.@gensym Base.@goto Base.@label +Base.@simd Base.@polly ``` diff --git a/codex/manual/arrays.md b/codex/manual/arrays.md index f53271c..a2f59b6 100644 --- a/codex/manual/arrays.md +++ b/codex/manual/arrays.md @@ -29,9 +29,7 @@ they don't intend to change. Many non- mutating functions are implemented by calling a function of the same name with an added `!` at the end on an explicit copy of the input, and returning that copy. -## Arrays - -### Basic Functions +## Basic Functions | Function | Description | |:---------------------- |:-------------------------------------------------------------------------------- | @@ -46,7 +44,7 @@ copy of the input, and returning that copy. | [`stride(A,k)`](@ref) | the stride (linear index distance between adjacent elements) along dimension `k` | | [`strides(A)`](@ref) | a tuple of the strides in each dimension | -### Construction and Initialization +## Construction and Initialization Many functions for constructing and initializing arrays are provided. In the following list of such functions, calls with a `dims...` argument can either take a single tuple of dimension sizes @@ -98,7 +96,7 @@ julia> zeros((2, 2)) ``` Here, `(2, 2)` is a [`Tuple`](@ref). -### Concatenation +## Concatenation Arrays can be constructed and also concatenated using the following functions: @@ -149,7 +147,7 @@ julia> [[1 2]; [3 4]] 3 4 ``` -### Typed array initializers +## Typed array initializers An array with a specific element type can be constructed using the syntax `T[A, B, C, ...]`. This will construct a 1-d array with element type `T`, initialized to contain elements `A`, `B`, `C`, @@ -168,7 +166,7 @@ julia> Int8[[1 2] [3 4]] 1 2 3 4 ``` -### Comprehensions +## Comprehensions Comprehensions provide a general and powerful way to construct arrays. Comprehension syntax is similar to set construction notation in mathematics: @@ -216,7 +214,7 @@ the result in single precision by writing: Float32[ 0.25*x[i-1] + 0.5*x[i] + 0.25*x[i+1] for i=2:length(x)-1 ] ``` -### Generator Expressions +## Generator Expressions Comprehensions can also be written without the enclosing square brackets, producing an object known as a generator. This object can be iterated to produce values on demand, instead of allocating @@ -246,6 +244,14 @@ julia> map(tuple, (1/(i+j) for i=1:2, j=1:2), [1 3; 2 4]) (0.333333, 2) (0.25, 4) ``` +Generators are implemented via inner functions. As in other cases of +inner functions in the language, variables from the enclosing scope can be +"captured" in the inner function. For example, `sum(p[i] - q[i] for i=1:n)` +captures the three variables `p`, `q` and `n` from the enclosing scope. +Captured variables can present performance challenges described in +[performance tips](@ref man-performance-tips). + + Ranges in generators and comprehensions can depend on previous ranges by writing multiple `for` keywords: @@ -271,7 +277,7 @@ julia> [(i,j) for i=1:3 for j=1:i if i+j == 4] (3, 1) ``` -### [Indexing](@id man-array-indexing) +## [Indexing](@id man-array-indexing) The general syntax for indexing into an n-dimensional array A is: @@ -402,7 +408,7 @@ julia> searchsorted(a, 3) 3:2 ``` -### Assignment +## Assignment The general syntax for assigning values in an n-dimensional array A is: @@ -451,7 +457,7 @@ julia> x 3 6 -9 ``` -### [Supported index types](@id man-supported-index-types) +## [Supported index types](@id man-supported-index-types) In the expression `A[I_1, I_2, ..., I_n]`, each `I_k` may be a scalar index, an array of scalar indices, or an object that represents an array of scalar @@ -514,7 +520,7 @@ julia> A[:, 3] 17 ``` -#### Cartesian indices +### Cartesian indices The special `CartesianIndex{N}` object represents a scalar index that behaves like an `N`-tuple of integers spanning multiple dimensions. For example: @@ -588,7 +594,7 @@ julia> A[CartesianIndex.(axes(A, 1), axes(A, 2)), :] `end` keyword to represent the last index of a dimension. Do not use `end` in indexing expressions that may contain either `CartesianIndex` or arrays thereof. -#### Logical indexing +### Logical indexing Often referred to as logical indexing or indexing with a logical mask, indexing by a boolean array selects elements at the indices where its values are `true`. @@ -630,7 +636,7 @@ julia> x[mask] 16 ``` -### Iteration +## Iteration The recommended ways to iterate over a whole array are @@ -667,7 +673,7 @@ i = CartesianIndex(3, 2) In contrast with `for i = 1:length(A)`, iterating with [`eachindex`](@ref) provides an efficient way to iterate over any array type. -### Array traits +## Array traits If you write a custom [`AbstractArray`](@ref) type, you can specify that it has fast linear indexing using @@ -678,7 +684,7 @@ Base.IndexStyle(::Type{<:MyArray}) = IndexLinear() This setting will cause `eachindex` iteration over a `MyArray` to use integers. If you don't specify this trait, the default value `IndexCartesian()` is used. -### Array and Vectorized Operators and Functions +## Array and Vectorized Operators and Functions The following operators are supported for arrays: @@ -709,7 +715,7 @@ Also notice the difference between `max.(a,b)`, which [`broadcast`](@ref)s [`max elementwise over `a` and `b`, and [`maximum(a)`](@ref), which finds the largest value within `a`. The same relationship holds for `min.(a,b)` and `minimum(a)`. -### Broadcasting +## Broadcasting It is sometimes useful to perform element-by-element binary operations on arrays of different sizes, such as adding a vector to each column of a matrix. An inefficient way to do this would @@ -774,7 +780,7 @@ julia> string.(1:3, ". ", ["First", "Second", "Third"]) "3. Third" ``` -### Implementation +## Implementation The base array type in Julia is the abstract type [`AbstractArray{T,N}`](@ref). It is parametrized by the number of dimensions `N` and the element type `T`. [`AbstractVector`](@ref) and [`AbstractMatrix`](@ref) are diff --git a/codex/manual/faq.md b/codex/manual/faq.md index da68118..a578023 100644 --- a/codex/manual/faq.md +++ b/codex/manual/faq.md @@ -613,7 +613,7 @@ all/many future usages of the other functions in module Foo that depend on calli ## Nothingness and missing values -### How does "null" or "nothingness" work in Julia? +### [How does "null", "nothingness" or "missingness" work in Julia?](@id faq-nothing) Unlike many languages (for example, C and Java), Julia objects cannot be "null" by default. When a reference (variable, object field, or array element) is uninitialized, accessing it @@ -627,10 +627,14 @@ this convention, and that the REPL does not print anything for it. Some language would not otherwise have a value also yield `nothing`, for example `if false; end`. For situations where a value `x` of type `T` exists only sometimes, the `Union{T, Nothing}` -type can be used. If the value itself can be `nothing` (notably, when `T` is `Any`), +type can be used for function arguments, object fields and array element types +as the equivalent of [`Nullable`, `Option` or `Maybe`](https://en.wikipedia.org/wiki/Nullable_type) +in other languages. If the value itself can be `nothing` (notably, when `T` is `Any`), the `Union{Some{T}, Nothing}` type is more appropriate since `x == nothing` then indicates the absence of a value, and `x == Some(nothing)` indicates the presence of a value equal -to `nothing`. +to `nothing`. The [`something`](@ref) function allows unwrapping `Some` objects and +using a default value instead of `nothing` arguments. Note that the compiler is able to +generate efficient code when working with `Union{T, Nothing}` arguments or fields. To represent missing data in the statistical sense (`NA` in R or `NULL` in SQL), use the [`missing`](@ref) object. See the [`Missing Values`](@ref missing) section for more details. @@ -732,6 +736,50 @@ julia> @sync for i in 1:3 1 Foo Bar 2 Foo Bar 3 Foo Bar ``` +## Arrays + +### What are the differences between zero-dimensional arrays and scalars? + +Zero-dimensional arrays are arrays of the form `Array{T,0}`. They behave similar +to scalars, but there are important differences. They deserve a special mention +because they are a special case which makes logical sense given the generic +definition of arrays, but might be a bit unintuitive at first. The following +line defines a zero-dimensional array: + +``` +julia> A = zeros() +0-dimensional Array{Float64,0}: +0.0 +``` + +In this example, `A` is a mutable container that contains one element, which can +be set by `A[] = 1.0` and retrieved with `A[]`. All zero-dimensional arrays have +the same size (`size(A) == ()`), and length (`length(A) == 1`). In particular, +zero-dimensional arrays are not empty. If you find this unintuitive, here are +some ideas that might help to understand Julia's definition. + +* Zero-dimensional arrays are the "point" to vector's "line" and matrix's +"plane". Just as a line has no area (but still represents a set of things), a +point has no length or any dimensions at all (but still represents a thing). +* We define `prod(())` to be 1, and the total number of elements in an array is +the product of the size. The size of a zero-dimensional array is `()`, and +therefore its length is `1`. +* Zero-dimensional arrays don't natively have any dimensions into which you +index -- they’re just `A[]`. We can apply the same "trailing one" rule for them +as for all other array dimensionalities, so you can indeed index them as +`A[1]`, `A[1,1]`, etc. + +It is also important to understand the differences to ordinary scalars. Scalars +are not mutable containers (even though they are iterable and define things +like `length`, `getindex`, *e.g.* `1[] == 1`). In particular, if `x = 0.0` is +defined as a scalar, it is an error to attempt to change its value via +`x[] = 1.0`. A scalar `x` can be converted into a zero-dimensional array +containing it via `fill(x)`, and conversely, a zero-dimensional array `a` can +be converted to the contained scalar via `a[]`. Another difference is that +a scalar can participate in linear algebra operations such as `2 * rand(2,2)`, +but the analogous operation with a zero-dimensional array +`fill(2) * rand(2,2)` is an error. + ## Julia Releases ### Do I want to use a release, beta, or nightly version of Julia? diff --git a/codex/manual/functions.md b/codex/manual/functions.md index 599a118..a24e382 100644 --- a/codex/manual/functions.md +++ b/codex/manual/functions.md @@ -654,6 +654,12 @@ normally or threw an exception. (The `try/finally` construct will be described i With the `do` block syntax, it helps to check the documentation or implementation to know how the arguments of the user function are initialized. +A `do` block, like any other inner function, can "capture" variables from its +enclosing scope. For example, the variable `data` in the above example of +`open...do` is captured from the outer scope. Captured variables +can create performance challenges as discussed in [performance tips](@ref man-performance-tips). + + ## [Dot Syntax for Vectorizing Functions](@id man-vectorized) In technical-computing languages, it is common to have "vectorized" versions of functions, which diff --git a/codex/manual/interfaces.md b/codex/manual/interfaces.md index 2e859fe..abdf611 100644 --- a/codex/manual/interfaces.md +++ b/codex/manual/interfaces.md @@ -437,7 +437,7 @@ V = view(A, [1,2,4], :) # is not strided, as the spacing between rows is not f | `Base.similar(bc::Broadcasted{DestStyle}, ::Type{ElType})` | Allocation of output container | | **Optional methods** | | | | `Base.BroadcastStyle(::Style1, ::Style2) = Style12()` | Precedence rules for mixing styles | -| `Base.broadcast_axes(::StyleA, A)` | Declaration of the indices of `A` for broadcasting purposes (defaults to [`axes(A)`](@ref)) | +| `Base.broadcast_axes(x)` | Declaration of the indices of `x` for broadcasting purposes (defaults to [`axes(x)`](@ref)) | | `Base.broadcastable(x)` | Convert `x` to an object that has `axes` and supports indexing | | **Bypassing default machinery** | | | `Base.copy(bc::Broadcasted{DestStyle})` | Custom implementation of `broadcast` | diff --git a/codex/manual/mathematical-operations.md b/codex/manual/mathematical-operations.md index 35417b6..0e60705 100644 --- a/codex/manual/mathematical-operations.md +++ b/codex/manual/mathematical-operations.md @@ -250,7 +250,7 @@ julia> NaN > NaN false ``` -and can cause especial headaches with [Arrays](@ref): +and can cause especial headaches with [arrays](@ref man-multi-dim-arrays): ```jldoctest julia> [1 NaN] == [1 NaN] diff --git a/codex/manual/metaprogramming.md b/codex/manual/metaprogramming.md index 6cc4e01..4d07565 100644 --- a/codex/manual/metaprogramming.md +++ b/codex/manual/metaprogramming.md @@ -907,15 +907,40 @@ When a significant amount of repetitive boilerplate code is required, it is comm it programmatically to avoid redundancy. In most languages, this requires an extra build step, and a separate program to generate the repetitive code. In Julia, expression interpolation and [`eval`](@ref) allow such code generation to take place in the normal course of program execution. -For example, the following code defines a series of operators on three arguments in terms of their -2-argument forms: +For example, consider the following custom type -```julia -for op = (:+, :*, :&, :|, :$) +```jldoctest mynumber-codegen +struct MyNumber + x::Float64 +end +# output + +``` + +for which we want to add a number of methods to. We can do this programmatically in the +following loop: + +```jldoctest mynumber-codegen +for op = (:sin, :cos, :tan, :log, :exp) eval(quote - ($op)(a,b,c) = ($op)(($op)(a,b),c) + Base.$op(a::MyNumber) = MyNumber($op(a.x)) end) end +# output + +``` + +and we can now use those functions with our custom type: + +```jldoctest mynumber-codegen +julia> x = MyNumber(π) +MyNumber(3.141592653589793) + +julia> sin(x) +MyNumber(1.2246467991473532e-16) + +julia> cos(x) +MyNumber(-1.0) ``` In this manner, Julia acts as its own [preprocessor](https://en.wikipedia.org/wiki/Preprocessor), @@ -923,8 +948,8 @@ and allows code generation from inside the language. The above code could be wri more tersely using the `:` prefix quoting form: ```julia -for op = (:+, :*, :&, :|, :$) - eval(:(($op)(a,b,c) = ($op)(($op)(a,b),c))) +for op = (:sin, :cos, :tan, :log, :exp) + eval(:(Base.$op(a::MyNumber) = MyNumber($op(a.x)))) end ``` @@ -932,8 +957,8 @@ This sort of in-language code generation, however, using the `eval(quote(...))` enough that Julia comes with a macro to abbreviate this pattern: ```julia -for op = (:+, :*, :&, :|, :$) - @eval ($op)(a,b,c) = ($op)(($op)(a,b),c) +for op = (:sin, :cos, :tan, :log, :exp) + @eval Base.$op(a::MyNumber) = MyNumber($op(a.x)) end ``` diff --git a/codex/manual/performance-tips.md b/codex/manual/performance-tips.md index a0c2d0b..30dc9ec 100644 --- a/codex/manual/performance-tips.md +++ b/codex/manual/performance-tips.md @@ -1133,12 +1133,18 @@ These are some minor points that might help in tight inner loops. Sometimes you can enable better optimization by promising certain program properties. - * Use `@inbounds` to eliminate array bounds checking within expressions. Be certain before doing + * Use [`@inbounds`](@ref) to eliminate array bounds checking within expressions. Be certain before doing this. If the subscripts are ever out of bounds, you may suffer crashes or silent corruption. - * Use `@fastmath` to allow floating point optimizations that are correct for real numbers, but lead + * Use [`@fastmath`](@ref) to allow floating point optimizations that are correct for real numbers, but lead to differences for IEEE numbers. Be careful when doing this, as this may change numerical results. This corresponds to the `-ffast-math` option of clang. - * Write `@simd` in front of `for` loops that are amenable to vectorization. **This feature is experimental** + * Write [`@simd`](@ref) in front of `for` loops to promise that the iterations are independent and may be + reordered. Note that in many cases, Julia can automatically vectorize code without the `@simd` macro; + it is only beneficial in cases where such a transformation would otherwise be illegal, including cases + like allowing floating-point re-associativity and ignoring dependent memory accesses (`@simd ivdep`). + Again, be very careful when asserting `@simd` as erroneously annotating a loop with dependent iterations + may result in unexpected results. In particular, note that `setindex!` on some `AbstractArray` subtypes is + inherently dependent upon iteration order. **This feature is experimental** and could change or disappear in future versions of Julia. The common idiom of using 1:n to index into an AbstractArray is not safe if the Array uses unconventional indexing, @@ -1146,9 +1152,9 @@ and may cause a segmentation fault if bounds checking is turned off. Use `Linear instead (see also [offset-arrays](https://docs.julialang.org/en/latest/devdocs/offset-arrays)). !!!note - While `@simd` needs to be placed directly in front of a loop, both `@inbounds` and `@fastmath` - can be applied to several statements at once, e.g. using `begin` ... `end`, or even to a whole - function. + While `@simd` needs to be placed directly in front of an innermost `for` loop, both `@inbounds` and `@fastmath` + can be applied to either single expressions or all the expressions that appear within nested blocks of code, e.g., + using `@inbounds begin` or `@inbounds for ...`. Here is an example with both `@inbounds` and `@simd` markup (we here use `@noinline` to prevent the optimizer from trying to be too clever and defeat our benchmark): @@ -1194,33 +1200,7 @@ GFlop/sec = 1.9467069505224963 GFlop/sec (SIMD) = 17.578554163920018 ``` -(`GFlop/sec` measures the performance, and larger numbers are better.) The range for a `@simd for` -loop should be a one-dimensional range. A variable used for accumulating, such as `s` in the example, -is called a *reduction variable*. By using `@simd`, you are asserting several properties of the -loop: - - * It is safe to execute iterations in arbitrary or overlapping order, with special consideration - for reduction variables. - * Floating-point operations on reduction variables can be reordered, possibly causing different - results than without `@simd`. - * No iteration ever waits on another iteration to make forward progress. - -A loop containing `break`, `continue`, or `@goto` will cause a compile-time error. - -Using `@simd` merely gives the compiler license to vectorize. Whether it actually does so depends -on the compiler. To actually benefit from the current implementation, your loop should have the -following additional properties: - - * The loop must be an innermost loop. - * The loop body must be straight-line code. This is why `@inbounds` is currently needed for all - array accesses. The compiler can sometimes turn short `&&`, `||`, and `?:` expressions into straight-line - code, if it is safe to evaluate all operands unconditionally. Consider using the [`ifelse`](@ref) - function instead of `?:` in the loop if it is safe to do so. - * Accesses must have a stride pattern and cannot be "gathers" (random-index reads) or "scatters" - (random-index writes). - * The stride should be unit stride. - * In some simple cases, for example with 2-3 arrays accessed in a loop, the LLVM auto-vectorization - may kick in automatically, leading to no further speedup with `@simd`. +(`GFlop/sec` measures the performance, and larger numbers are better.) Here is an example with all three kinds of markup. This program first calculates the finite difference of a one-dimensional array, and then evaluates the L2-norm of the result: @@ -1479,3 +1459,85 @@ The following examples may help you interpret expressions marked as containing n field `data::Array{T}`. But `Array` needs the dimension `N`, too, to be a concrete type. * Suggestion: use concrete types like `Array{T,3}` or `Array{T,N}`, where `N` is now a parameter of `ArrayContainer` + +## [Performance of captured variable](@id man-performance-captured) + +Consider the following example that defines an inner function: +```julia +function abmult(r::Int) + if r < 0 + r = -r + end + f = x -> x * r + return f +end +``` + +Function `abmult` returns a function `f` that multiplies its argument by +the absolute value of `r`. The inner function assigned to `f` is called a +"closure". Inner functions are also used by the +language for `do`-blocks and for generator expressions. + +This style of code presents performance challenges for the language. +The parser, when translating it into lower-level instructions, +substantially reorganizes the above code by extracting the +inner function to a separate code block. "Captured" variables such as `r` +that are shared by inner functions and their enclosing scope are +also extracted into a heap-allocated "box" accessible to both inner and +outer functions because the language specifies that `r` in the +inner scope must be identical to `r` in the outer scope even after the +outer scope (or another inner function) modifies `r`. + +The discussion in the preceding paragraph referred to the "parser", that is, the phase +of compilation that takes place when the module containing `abmult` is first loaded, +as opposed to the later phase when it is first invoked. The parser does not "know" that +`Int` is a fixed type, or that the statement `r = -r` tranforms an `Int` to another `Int`. +The magic of type inference takes place in the later phase of compilation. + +Thus, the parser does not know that `r` has a fixed type (`Int`). +nor that `r` does not change value once the inner function is created (so that +the box is unneeded). Therefore, the parser emits code for +box that holds an object with an abstract type such as `Any`, which +requires run-time type dispatch for each occurrence of `r`. This can be +verified by applying `@code_warntype` to the above function. Both the boxing +and the run-time type dispatch can cause loss of performance. + +If captured variables are used in a performance-critical section of the code, +then the following tips help ensure that their use is performant. First, if +it is known that a captured variable does not change its type, then this can +be declared explicitly with a type annotation (on the variable, not the +right-hand side): +```julia +function abmult2(r0::Int) + r::Int = r0 + if r < 0 + r = -r + end + f = x -> x * r + return f +end +``` +The type annotation partially recovers lost performance due to capturing because +the parser can associate a concrete type to the object in the box. +Going further, if the captured variable does not need to be boxed at all (because it +will not be reassigned after the closure is created), this can be indicated +with `let` blocks as follows. +```julia +function abmult3(r::Int) + if r < 0 + r = -r + end + f = let r = r + x -> x * r + end + return f +end +``` +The `let` block creates a new variable `r` whose scope is only the +inner function. The second technique recovers full language performance +in the presence of captured variables. Note that this is a rapidly +evolving aspect of the compiler, and it is likely that future releases +will not require this degree of programmer annotation to attain peformance. +In the mean time, some user-contributed packages like +[FastClosures](https://github.com/c42f/FastClosures.jl) automate the +insertion of `let` statements as in `abmult3`. diff --git a/codex/manual/style-guide.md b/codex/manual/style-guide.md index 10355e4..624297d 100644 --- a/codex/manual/style-guide.md +++ b/codex/manual/style-guide.md @@ -119,27 +119,6 @@ is typical for such functions to also return the modified array for convenience. Types such as `Union{Function,AbstractString}` are often a sign that some design could be cleaner. -## Avoid type Unions in fields - -When creating a type such as: - -```julia -mutable struct MyType - ... - x::Union{Nothing,T} -end -``` - -ask whether the option for `x` to be `nothing` (of type `Nothing`) is really necessary. Here are -some alternatives to consider: - - * Find a safe default value to initialize `x` with - * Introduce another type that lacks `x` - * If there are many fields like `x`, store them in a dictionary - * Determine whether there is a simple rule for when `x` is `nothing`. For example, often the field - will start as `nothing` but get initialized at some well-defined point. In that case, consider - leaving it undefined at first. - ## Avoid elaborate container types It is usually not much help to construct arrays like the following: diff --git a/codex/manual/types.md b/codex/manual/types.md index 514c5a0..a56ffd2 100644 --- a/codex/manual/types.md +++ b/codex/manual/types.md @@ -442,7 +442,7 @@ To recap, two essential properties define immutability in Julia: always refer to the same mutable value even though that mutable value's content may itself be modified. * An object with an immutable type may be copied freely by the compiler since its - immutabity makes it impossible to programmatically distinguish between the original + immutability makes it impossible to programmatically distinguish between the original object and a copy. * In particular, this means that small enough immutable values like integers and floats are typically passed to functions in registers (or stack allocated). @@ -480,7 +480,7 @@ Every concrete value in the system is an instance of some `DataType`. ## Type Unions A type union is a special abstract type which includes as objects all instances of any of its -argument types, constructed using the special `Union` function: +argument types, constructed using the special `Union` keyword: ```jldoctest julia> IntOrString = Union{Int,AbstractString} @@ -497,7 +497,16 @@ ERROR: TypeError: in typeassert, expected Union{Int64, AbstractString}, got Floa ``` The compilers for many languages have an internal union construct for reasoning about types; Julia -simply exposes it to the programmer. +simply exposes it to the programmer. The Julia compiler is able to generate efficient code in the +presence of `Union` types with a small number of types [^1], by generating specialized code +in separate branches for each possible type. + +A particularly useful case of a `Union` type is `Union{T, Nothing}`, where `T` can be any type and +[`Nothing`](@ref) is the singleton type whose only instance is the object `nothing`. This pattern +is the Julia equivalent of [`Nullable`, `Option` or `Maybe`](https://en.wikipedia.org/wiki/Nullable_type) +types in other languages. Declaring a function argument or a field as `Union{T, Nothing}` allows +setting it either to a value of type `T`, or to `nothing` to indicate that there is no value. +See [this FAQ entry](@ref faq-nothing) for more information. ## Parametric Types @@ -1403,3 +1412,5 @@ It's worth noting that it's extremely easy to mis-use parametric "value" types, in unfavorable cases, you can easily end up making the performance of your code much *worse*. In particular, you would never want to write actual code as illustrated above. For more information about the proper (and improper) uses of `Val`, please read the more extensive discussion in [the performance tips](@ref man-performance-tips). + +[^1]: "Small" is defined by the `MAX_UNION_SPLITTING` constant, which is currently set to 4. diff --git a/codex/manual/variables-and-scoping.md b/codex/manual/variables-and-scoping.md index 45a150f..496730a 100644 --- a/codex/manual/variables-and-scoping.md +++ b/codex/manual/variables-and-scoping.md @@ -262,7 +262,11 @@ julia> counter() 2 ``` -See also the closures in the examples in the next two sections. +See also the closures in the examples in the next two sections. A variable +such as `x` in the first example and `state` in the second that is inherited +from the enclosing scope by the inner function is sometimes called a +*captured* variable. Captured variables can present performance challenges +discussed in [performance tips](@ref man-performance-tips). The distinction between inheriting global scope and nesting local scope can lead to some slight differences between functions diff --git a/codex/stdlib/InteractiveUtils.md b/codex/stdlib/InteractiveUtils.md index 656780c..7e313b8 100644 --- a/codex/stdlib/InteractiveUtils.md +++ b/codex/stdlib/InteractiveUtils.md @@ -26,6 +26,7 @@ InteractiveUtils.code_llvm InteractiveUtils.@code_llvm InteractiveUtils.code_native InteractiveUtils.@code_native +InteractiveUtils.clipboard ``` ```@meta diff --git a/codex/stdlib/Pkg.md b/codex/stdlib/Pkg.md index f84fc76..0f08a5c 100644 --- a/codex/stdlib/Pkg.md +++ b/codex/stdlib/Pkg.md @@ -92,9 +92,9 @@ since that could conflict with the configuration of the main application. !!! note **Projects _vs._ Packages _vs._ Applications:** - 1. Project is an umbrella term: packages and applications are kinds of projects. - 2. Packages should have UUIDs, applications can have a UUIDs but don't need them. - 3. Applications can provide global configuration, whereas packages cannot. + 1. **Project** is an umbrella term: packages and applications are kinds of projects. + 2. **Packages** should have UUIDs, applications can have a UUIDs but don't need them. + 3. **Applications** can provide global configuration, whereas packages cannot. **Library (future work):** a compiled binary dependency (not written in Julia) packaged to be used by a Julia project. These are currently typically built in- @@ -470,7 +470,8 @@ Initialized project at /Users/kristoffer/MyProject/Project.toml Status `Project.toml` ``` -Note that the REPL prompt changed when the new project was initiated. Since this is a newly created project, the status command show it contains no packages. +Note that the REPL prompt changed when the new project was initiated, in other words, Pkg automatically set the current environment to the +one that just got initiated. Since this is a newly created project, the status command show it contains no packages. Packages added here again in a completely separate environment from the one earlier used. ## Garbage collecting old, unused packages @@ -512,7 +513,8 @@ To generate files for a new package, use `pkg> generate`. This creates a new project `HelloWorld` with the following files (visualized with the external [`tree` command](https://linux.die.net/man/1/tree)): ```jl -julia> cd("HelloWorld") +shell> cd HelloWorld + shell> tree . . ├── Project.toml @@ -543,9 +545,11 @@ greet() = print("Hello World!") end # module ``` -We can now load the project and use it: +We can now activate the project and load the package: ```jl +pkg> activate + julia> import HelloWorld julia> HelloWorld.greet() @@ -651,7 +655,7 @@ Testing... #### Test-specific dependencies -Sometimes one might to want to use some packages only at testing time but not enforce a dependency on them when the package is used. +Sometimes one might want to use some packages only at testing time but not enforce a dependency on them when the package is used. This is possible by adding dependencies to a "test target" to the Project file. Here we add the `Test` standard library as a test-only dependency by adding the following to the Project file: @@ -744,7 +748,7 @@ The REPL command `precompile` can be used to precompile all the dependencies in (HelloWorld) pkg> update; precompile ``` -do update the dependencies and then precompile them. +to update the dependencies and then precompile them. ## Preview mode @@ -766,9 +770,11 @@ However, nothing would be installed and your `Project.toml` and `Manifest.toml` ## Using someone else's project -Simple clone their project using e.g. `git clone`, `cd` to the project directory and call +Simply clone their project using e.g. `git clone`, `cd` to the project directory and call ``` +(v0.7) pkg> activate + (SomeProject) pkg> instantiate ``` diff --git a/codex/stdlib/Random.md b/codex/stdlib/Random.md index 5607ba0..86afd63 100644 --- a/codex/stdlib/Random.md +++ b/codex/stdlib/Random.md @@ -21,7 +21,7 @@ A `MersenneTwister` or `RandomDevice` RNG can generate random numbers of the fol [`UInt32`](@ref), [`Int64`](@ref), [`UInt64`](@ref), [`Int128`](@ref), [`UInt128`](@ref), [`BigInt`](@ref) (or complex numbers of those types). Random floating point numbers are generated uniformly in ``[0, 1)``. As `BigInt` represents -unbounded integers, the interval must be specified (e.g. `rand(big(1:6))`). +unbounded integers, the interval must be specified (e.g. `rand(big.(1:6))`). ```@docs Random.srand diff --git a/codex/stdlib/random.md b/codex/stdlib/random.md index 5607ba0..86afd63 100644 --- a/codex/stdlib/random.md +++ b/codex/stdlib/random.md @@ -21,7 +21,7 @@ A `MersenneTwister` or `RandomDevice` RNG can generate random numbers of the fol [`UInt32`](@ref), [`Int64`](@ref), [`UInt64`](@ref), [`Int128`](@ref), [`UInt128`](@ref), [`BigInt`](@ref) (or complex numbers of those types). Random floating point numbers are generated uniformly in ``[0, 1)``. As `BigInt` represents -unbounded integers, the interval must be specified (e.g. `rand(big(1:6))`). +unbounded integers, the interval must be specified (e.g. `rand(big.(1:6))`). ```@docs Random.srand diff --git a/src/.NEWS.md.swp b/src/.NEWS.md.swp deleted file mode 100644 index 1ee7cb4c898c94aaecab1627b2894633c57d704b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 110592 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 diff --git a/src/NEWS.md b/src/NEWS.md index 29b3eb0..99b814b 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -540,6 +540,9 @@ Library improvements [ANSI color codes](https://en.wikipedia.org/wiki/ANSI_escape_code) ([#25067](https://github.com/JuliaLang/julia/issues/25067)), rather than using the undocumented `Base.have_color` global flag. + * `print_with_color` has been deprecated in favor of + `printstyled([io], xs...; bold=false, color=:normal)` for printing styled text ([#25522](https://github.com/JuliaLang/julia/issues/25522)). + * Functions `first` and `last` now accept `nchar` argument for `AbstractString`. If this argument is used they return a string consisting of first/last `nchar` characters from the original string ([#23960](https://github.com/JuliaLang/julia/issues/23960)). @@ -1271,6 +1274,10 @@ Deprecated or removed * `vecdot` and `vecnorm` are deprecated in favor of `dot` and `norm`, respectively ([#27401](https://github.com/JuliaLang/julia/issues/27401)). + * `clipboard` has been moved to the `InteractiveUtils` standard library package + (along with other utilities mostly used at the interactive prompt, such as `edit` + and `less`) ([#27635](https://github.com/JuliaLang/julia/issues/27635)). + Command-line option changes --------------------------- diff --git a/src/base/base.md b/src/base/base.md index 030ffe3..cea99f4 100644 --- a/src/base/base.md +++ b/src/base/base.md @@ -22,8 +22,6 @@ Base.exit Base.atexit Base.isinteractive Base.summarysize -Base.clipboard(::Any) -Base.clipboard() Base.require Base.compilecache Base.__precompile__ @@ -219,6 +217,7 @@ Base.gensym Base.@gensym Base.@goto Base.@label +Base.@simd Base.@polly ``` diff --git a/src/manual/arrays.md b/src/manual/arrays.md index 8acb2a0..3d49470 100644 --- a/src/manual/arrays.md +++ b/src/manual/arrays.md @@ -27,9 +27,7 @@ they don't intend to change. Many non- mutating functions are implemented by calling a function of the same name with an added `!` at the end on an explicit copy of the input, and returning that copy. -## [배열](@id Arrays) - -### 기본 함수 +## 기본 함수 | 함수 | 설명 | |:---------------------- |:-------------------------------------------------------------- | @@ -44,7 +42,7 @@ copy of the input, and returning that copy. | [`stride(A,k)`](@ref) | `k` 차원 방향의 스트라이드 (연속한 원소 간의 선형 인덱스 거리) | | [`strides(A)`](@ref) | 모든 차원의 스트라이드 투플 | -### 생성과 초기화 +## 생성과 초기화 배열을 생성하고 초기화 하는 많은 함수가 있다. 다음에 나열된 함수들에서, `dims...` 인수는 차원의 크기들을 나타내는 투플 하나를 받거나, 혹은 각 차원의 크기를 여러 인수로 받을 수 있다. @@ -92,7 +90,7 @@ julia> zeros((2, 2)) ``` Here, `(2, 2)` is a [`Tuple`](@ref). -### 병합(Concatenation) +## 병합(Concatenation) 배열은 다음의 함수를 사용하여 생성하고 병합할 수 있다. @@ -143,7 +141,7 @@ julia> [[1 2]; [3 4]] 3 4 ``` -### 타입이 있는 배열의 초기화 +## 타입이 있는 배열의 초기화 특정 원소 타입의 배열은 `T[A, B, C, ...]` 문법을 통해 생성할 수 있다. 이는 원소 타입이 `T`인 일차원 배열을 생성하고, 원소 `A`, `B`, `C` 등을 담도록 초기화한다. @@ -161,7 +159,7 @@ julia> Int8[[1 2] [3 4]] 1 2 3 4 ``` -### [컴프리헨션(Comprehensions)](@id Comprehensions) +## [컴프리헨션(Comprehensions)](@id Comprehensions) 컴프리헨션은 배열을 생성하는 일반적이면서도 강력한 방법을 제공한다. 컴프리헨션의 문법은 수학에서 쓰이는 집합의 조건제시법과 유사하다: @@ -207,7 +205,7 @@ julia> [ 0.25*x[i-1] + 0.5*x[i] + 0.25*x[i+1] for i=2:length(x)-1 ] Float32[ 0.25*x[i-1] + 0.5*x[i] + 0.25*x[i+1] for i=2:length(x)-1 ] ``` -### 제너레이터 표현식 (Generator Expressions) +## 제너레이터 표현식 (Generator Expressions) 컴프리헨션은 대괄호 없이도 쓸 수 있으며, 이 경우 제너레이터 객체를 생성한다. 제너레이터는 배열을 미리 할당하고 값을 저장하는 것이 아니라, 필요에 따라 값을 생성하도록 반복할 수 있다 ([반복](@ref Iteration) 참조). @@ -234,6 +232,13 @@ julia> map(tuple, (1/(i+j) for i=1:2, j=1:2), [1 3; 2 4]) (0.333333, 2) (0.25, 4) ``` +Generators are implemented via inner functions. As in other cases of +inner functions in the language, variables from the enclosing scope can be +"captured" in the inner function. For example, `sum(p[i] - q[i] for i=1:n)` +captures the three variables `p`, `q` and `n` from the enclosing scope. +Captured variables can present performance challenges described in +[performance tips](@ref man-performance-tips). + 제너레이터와 컴프리헨션에서 `for` 키워드를 여러번 사용함으로써 범위가 앞선 범위에 의존하도록 할 수 있다. ```jldoctest @@ -258,7 +263,7 @@ julia> [(i,j) for i=1:3 for j=1:i if i+j == 4] (3, 1) ``` -### [인덱싱](@id man-array-indexing) +## [인덱싱](@id man-array-indexing) n차원 배열 `A`를 인덱싱 하는 일반적인 문법은 다음과 같다: @@ -383,7 +388,7 @@ julia> searchsorted(a, 3) 3:2 ``` -### 대입 +## 대입 n차원 배열 `A`에 값을 대입하는 일반적인 문법은 다음과 같다: @@ -426,7 +431,7 @@ julia> x 3 6 -9 ``` -### [지원하는 인덱스 타입](@id man-supported-index-types) +## [지원하는 인덱스 타입](@id man-supported-index-types) 표현식 `A[I_1, I_2, ..., I_n]`에서, `I_k`는 스칼라 인덱스, 스칼라 인덱스의 배열, 혹은 [`to_indices`](@ref)를 통해 스칼라 인덱스 배열로 변환될 수 있는 객체 중 하나이다: @@ -487,7 +492,7 @@ julia> A[:, 3] 17 ``` -#### 직교 인덱스(Cartesian indices) +### 직교 인덱스(Cartesian indices) `CartesianIndex{N}` 객체는 여러 차원을 포괄하는 정수의 `N`투플처럼 동작하는 스칼라 인덱스를 나타낸다. @@ -553,7 +558,7 @@ julia> A[CartesianIndex.(axes(A, 1), axes(A, 2)), :] `CartesianIndex`와 `CartesianIndex`의 배열은 차원의 마지막 인덱스를 나타내는 `end` 키워드와 호환되지 않으므로, `CartesianIndex` 혹은 `CartesianIndex`의 배열을 포함할 수도 있는 표현식에서는 `end`를 사용해서는 안된다. -#### 논리적 인덱싱 +### 논리적 인덱싱 부울 배열을 이용한 인덱싱은 값이 `true`인 곳의 인덱스를 선택한다. 주로 논리적 인덱싱, 혹은 논리적 마스크를 사용한 인덱싱이라고 부르며, 부울 벡터 `B`를 통한 인덱싱은 [`findall(B)`](@ref)가 리턴하는 정수의 벡터를 통한 인덱싱과 동일하다. @@ -590,7 +595,7 @@ julia> x[mask] 16 ``` -### [반복(Iteration)](@id Iteration) +## [반복(Iteration)](@id Iteration) 배열 전체를 반복하는 방법으로는 다음을 추천한다: @@ -625,7 +630,7 @@ i = CartesianIndex(3, 2) `for i = 1:length(A)`에 비해, [`eachindex`](@ref)는 모든 종류의 배열을 효율적으로 반복할 수 있도록 해준다. -### 배열 특성(trait) +## 배열 특성(trait) 커스텀 [`AbstractArray`](@ref) 타입을 정의하는 경우, 빠른 선형 인덱싱이 가능함을 지정할 수 있다: @@ -636,7 +641,7 @@ Base.IndexStyle(::Type{<:MyArray}) = IndexLinear() 이 설정은 `eachindex`가 정수를 사용하여 `MyArray`를 반복하도록 한다. 이 특성을 지정하지 않으면, 기본값인 `IndexCartesian()`를 사용한다. -### 배열과 벡터화된 연산자/함수 +## 배열과 벡터화된 연산자/함수 배열은 다음의 연산자를 지원한다: @@ -662,7 +667,7 @@ Base.IndexStyle(::Type{<:MyArray}) = IndexLinear() 또한, [`max`](@ref)를 `a`와 `b`에 원소별로 [`broadcast`](@ref) 하는 `max.(a,b)`와 , `a`의 최대값을 찾는 [`maximum(a)`](@ref)의 차이에 유의하라. `min.(a,b)` 와 `minimum(a)` 의 관계도 마찬가지이다. -### [브로드캐스팅](@id Broadcasting) +## [브로드캐스팅](@id Broadcasting) 행렬의 각 배열을 더하는 것 처럼, 다른 크기의 배열들을 원소별로 이항 연산할 필요가 종종 있다. 이를 비효율적으로 하는 방법은 벡터를 행렬과 같은 크기로 복사하는 것이다: @@ -722,7 +727,7 @@ julia> string.(1:3, ". ", ["First", "Second", "Third"]) "3. Third" ``` -### 구현 +## 구현 Julia에서 기본 배열 타입은 추상 타입인 [`AbstractArray{T,N}`](@ref)이다. `AbstractArray{T,N}`는 차원수 `N`과 원소 타입 `T`로 매개변수화 되어 있다. diff --git a/src/manual/faq.md b/src/manual/faq.md index da68118..a578023 100644 --- a/src/manual/faq.md +++ b/src/manual/faq.md @@ -613,7 +613,7 @@ all/many future usages of the other functions in module Foo that depend on calli ## Nothingness and missing values -### How does "null" or "nothingness" work in Julia? +### [How does "null", "nothingness" or "missingness" work in Julia?](@id faq-nothing) Unlike many languages (for example, C and Java), Julia objects cannot be "null" by default. When a reference (variable, object field, or array element) is uninitialized, accessing it @@ -627,10 +627,14 @@ this convention, and that the REPL does not print anything for it. Some language would not otherwise have a value also yield `nothing`, for example `if false; end`. For situations where a value `x` of type `T` exists only sometimes, the `Union{T, Nothing}` -type can be used. If the value itself can be `nothing` (notably, when `T` is `Any`), +type can be used for function arguments, object fields and array element types +as the equivalent of [`Nullable`, `Option` or `Maybe`](https://en.wikipedia.org/wiki/Nullable_type) +in other languages. If the value itself can be `nothing` (notably, when `T` is `Any`), the `Union{Some{T}, Nothing}` type is more appropriate since `x == nothing` then indicates the absence of a value, and `x == Some(nothing)` indicates the presence of a value equal -to `nothing`. +to `nothing`. The [`something`](@ref) function allows unwrapping `Some` objects and +using a default value instead of `nothing` arguments. Note that the compiler is able to +generate efficient code when working with `Union{T, Nothing}` arguments or fields. To represent missing data in the statistical sense (`NA` in R or `NULL` in SQL), use the [`missing`](@ref) object. See the [`Missing Values`](@ref missing) section for more details. @@ -732,6 +736,50 @@ julia> @sync for i in 1:3 1 Foo Bar 2 Foo Bar 3 Foo Bar ``` +## Arrays + +### What are the differences between zero-dimensional arrays and scalars? + +Zero-dimensional arrays are arrays of the form `Array{T,0}`. They behave similar +to scalars, but there are important differences. They deserve a special mention +because they are a special case which makes logical sense given the generic +definition of arrays, but might be a bit unintuitive at first. The following +line defines a zero-dimensional array: + +``` +julia> A = zeros() +0-dimensional Array{Float64,0}: +0.0 +``` + +In this example, `A` is a mutable container that contains one element, which can +be set by `A[] = 1.0` and retrieved with `A[]`. All zero-dimensional arrays have +the same size (`size(A) == ()`), and length (`length(A) == 1`). In particular, +zero-dimensional arrays are not empty. If you find this unintuitive, here are +some ideas that might help to understand Julia's definition. + +* Zero-dimensional arrays are the "point" to vector's "line" and matrix's +"plane". Just as a line has no area (but still represents a set of things), a +point has no length or any dimensions at all (but still represents a thing). +* We define `prod(())` to be 1, and the total number of elements in an array is +the product of the size. The size of a zero-dimensional array is `()`, and +therefore its length is `1`. +* Zero-dimensional arrays don't natively have any dimensions into which you +index -- they’re just `A[]`. We can apply the same "trailing one" rule for them +as for all other array dimensionalities, so you can indeed index them as +`A[1]`, `A[1,1]`, etc. + +It is also important to understand the differences to ordinary scalars. Scalars +are not mutable containers (even though they are iterable and define things +like `length`, `getindex`, *e.g.* `1[] == 1`). In particular, if `x = 0.0` is +defined as a scalar, it is an error to attempt to change its value via +`x[] = 1.0`. A scalar `x` can be converted into a zero-dimensional array +containing it via `fill(x)`, and conversely, a zero-dimensional array `a` can +be converted to the contained scalar via `a[]`. Another difference is that +a scalar can participate in linear algebra operations such as `2 * rand(2,2)`, +but the analogous operation with a zero-dimensional array +`fill(2) * rand(2,2)` is an error. + ## Julia Releases ### Do I want to use a release, beta, or nightly version of Julia? diff --git a/src/manual/functions.md b/src/manual/functions.md index 599a118..a24e382 100644 --- a/src/manual/functions.md +++ b/src/manual/functions.md @@ -654,6 +654,12 @@ normally or threw an exception. (The `try/finally` construct will be described i With the `do` block syntax, it helps to check the documentation or implementation to know how the arguments of the user function are initialized. +A `do` block, like any other inner function, can "capture" variables from its +enclosing scope. For example, the variable `data` in the above example of +`open...do` is captured from the outer scope. Captured variables +can create performance challenges as discussed in [performance tips](@ref man-performance-tips). + + ## [Dot Syntax for Vectorizing Functions](@id man-vectorized) In technical-computing languages, it is common to have "vectorized" versions of functions, which diff --git a/src/manual/interfaces.md b/src/manual/interfaces.md index 2e859fe..abdf611 100644 --- a/src/manual/interfaces.md +++ b/src/manual/interfaces.md @@ -437,7 +437,7 @@ V = view(A, [1,2,4], :) # is not strided, as the spacing between rows is not f | `Base.similar(bc::Broadcasted{DestStyle}, ::Type{ElType})` | Allocation of output container | | **Optional methods** | | | | `Base.BroadcastStyle(::Style1, ::Style2) = Style12()` | Precedence rules for mixing styles | -| `Base.broadcast_axes(::StyleA, A)` | Declaration of the indices of `A` for broadcasting purposes (defaults to [`axes(A)`](@ref)) | +| `Base.broadcast_axes(x)` | Declaration of the indices of `x` for broadcasting purposes (defaults to [`axes(x)`](@ref)) | | `Base.broadcastable(x)` | Convert `x` to an object that has `axes` and supports indexing | | **Bypassing default machinery** | | | `Base.copy(bc::Broadcasted{DestStyle})` | Custom implementation of `broadcast` | diff --git a/src/manual/mathematical-operations.md b/src/manual/mathematical-operations.md index 35417b6..0e60705 100644 --- a/src/manual/mathematical-operations.md +++ b/src/manual/mathematical-operations.md @@ -250,7 +250,7 @@ julia> NaN > NaN false ``` -and can cause especial headaches with [Arrays](@ref): +and can cause especial headaches with [arrays](@ref man-multi-dim-arrays): ```jldoctest julia> [1 NaN] == [1 NaN] diff --git a/src/manual/metaprogramming.md b/src/manual/metaprogramming.md index 6cc4e01..4d07565 100644 --- a/src/manual/metaprogramming.md +++ b/src/manual/metaprogramming.md @@ -907,15 +907,40 @@ When a significant amount of repetitive boilerplate code is required, it is comm it programmatically to avoid redundancy. In most languages, this requires an extra build step, and a separate program to generate the repetitive code. In Julia, expression interpolation and [`eval`](@ref) allow such code generation to take place in the normal course of program execution. -For example, the following code defines a series of operators on three arguments in terms of their -2-argument forms: +For example, consider the following custom type -```julia -for op = (:+, :*, :&, :|, :$) +```jldoctest mynumber-codegen +struct MyNumber + x::Float64 +end +# output + +``` + +for which we want to add a number of methods to. We can do this programmatically in the +following loop: + +```jldoctest mynumber-codegen +for op = (:sin, :cos, :tan, :log, :exp) eval(quote - ($op)(a,b,c) = ($op)(($op)(a,b),c) + Base.$op(a::MyNumber) = MyNumber($op(a.x)) end) end +# output + +``` + +and we can now use those functions with our custom type: + +```jldoctest mynumber-codegen +julia> x = MyNumber(π) +MyNumber(3.141592653589793) + +julia> sin(x) +MyNumber(1.2246467991473532e-16) + +julia> cos(x) +MyNumber(-1.0) ``` In this manner, Julia acts as its own [preprocessor](https://en.wikipedia.org/wiki/Preprocessor), @@ -923,8 +948,8 @@ and allows code generation from inside the language. The above code could be wri more tersely using the `:` prefix quoting form: ```julia -for op = (:+, :*, :&, :|, :$) - eval(:(($op)(a,b,c) = ($op)(($op)(a,b),c))) +for op = (:sin, :cos, :tan, :log, :exp) + eval(:(Base.$op(a::MyNumber) = MyNumber($op(a.x)))) end ``` @@ -932,8 +957,8 @@ This sort of in-language code generation, however, using the `eval(quote(...))` enough that Julia comes with a macro to abbreviate this pattern: ```julia -for op = (:+, :*, :&, :|, :$) - @eval ($op)(a,b,c) = ($op)(($op)(a,b),c) +for op = (:sin, :cos, :tan, :log, :exp) + @eval Base.$op(a::MyNumber) = MyNumber($op(a.x)) end ``` diff --git a/src/manual/performance-tips.md b/src/manual/performance-tips.md index a0c2d0b..30dc9ec 100644 --- a/src/manual/performance-tips.md +++ b/src/manual/performance-tips.md @@ -1133,12 +1133,18 @@ These are some minor points that might help in tight inner loops. Sometimes you can enable better optimization by promising certain program properties. - * Use `@inbounds` to eliminate array bounds checking within expressions. Be certain before doing + * Use [`@inbounds`](@ref) to eliminate array bounds checking within expressions. Be certain before doing this. If the subscripts are ever out of bounds, you may suffer crashes or silent corruption. - * Use `@fastmath` to allow floating point optimizations that are correct for real numbers, but lead + * Use [`@fastmath`](@ref) to allow floating point optimizations that are correct for real numbers, but lead to differences for IEEE numbers. Be careful when doing this, as this may change numerical results. This corresponds to the `-ffast-math` option of clang. - * Write `@simd` in front of `for` loops that are amenable to vectorization. **This feature is experimental** + * Write [`@simd`](@ref) in front of `for` loops to promise that the iterations are independent and may be + reordered. Note that in many cases, Julia can automatically vectorize code without the `@simd` macro; + it is only beneficial in cases where such a transformation would otherwise be illegal, including cases + like allowing floating-point re-associativity and ignoring dependent memory accesses (`@simd ivdep`). + Again, be very careful when asserting `@simd` as erroneously annotating a loop with dependent iterations + may result in unexpected results. In particular, note that `setindex!` on some `AbstractArray` subtypes is + inherently dependent upon iteration order. **This feature is experimental** and could change or disappear in future versions of Julia. The common idiom of using 1:n to index into an AbstractArray is not safe if the Array uses unconventional indexing, @@ -1146,9 +1152,9 @@ and may cause a segmentation fault if bounds checking is turned off. Use `Linear instead (see also [offset-arrays](https://docs.julialang.org/en/latest/devdocs/offset-arrays)). !!!note - While `@simd` needs to be placed directly in front of a loop, both `@inbounds` and `@fastmath` - can be applied to several statements at once, e.g. using `begin` ... `end`, or even to a whole - function. + While `@simd` needs to be placed directly in front of an innermost `for` loop, both `@inbounds` and `@fastmath` + can be applied to either single expressions or all the expressions that appear within nested blocks of code, e.g., + using `@inbounds begin` or `@inbounds for ...`. Here is an example with both `@inbounds` and `@simd` markup (we here use `@noinline` to prevent the optimizer from trying to be too clever and defeat our benchmark): @@ -1194,33 +1200,7 @@ GFlop/sec = 1.9467069505224963 GFlop/sec (SIMD) = 17.578554163920018 ``` -(`GFlop/sec` measures the performance, and larger numbers are better.) The range for a `@simd for` -loop should be a one-dimensional range. A variable used for accumulating, such as `s` in the example, -is called a *reduction variable*. By using `@simd`, you are asserting several properties of the -loop: - - * It is safe to execute iterations in arbitrary or overlapping order, with special consideration - for reduction variables. - * Floating-point operations on reduction variables can be reordered, possibly causing different - results than without `@simd`. - * No iteration ever waits on another iteration to make forward progress. - -A loop containing `break`, `continue`, or `@goto` will cause a compile-time error. - -Using `@simd` merely gives the compiler license to vectorize. Whether it actually does so depends -on the compiler. To actually benefit from the current implementation, your loop should have the -following additional properties: - - * The loop must be an innermost loop. - * The loop body must be straight-line code. This is why `@inbounds` is currently needed for all - array accesses. The compiler can sometimes turn short `&&`, `||`, and `?:` expressions into straight-line - code, if it is safe to evaluate all operands unconditionally. Consider using the [`ifelse`](@ref) - function instead of `?:` in the loop if it is safe to do so. - * Accesses must have a stride pattern and cannot be "gathers" (random-index reads) or "scatters" - (random-index writes). - * The stride should be unit stride. - * In some simple cases, for example with 2-3 arrays accessed in a loop, the LLVM auto-vectorization - may kick in automatically, leading to no further speedup with `@simd`. +(`GFlop/sec` measures the performance, and larger numbers are better.) Here is an example with all three kinds of markup. This program first calculates the finite difference of a one-dimensional array, and then evaluates the L2-norm of the result: @@ -1479,3 +1459,85 @@ The following examples may help you interpret expressions marked as containing n field `data::Array{T}`. But `Array` needs the dimension `N`, too, to be a concrete type. * Suggestion: use concrete types like `Array{T,3}` or `Array{T,N}`, where `N` is now a parameter of `ArrayContainer` + +## [Performance of captured variable](@id man-performance-captured) + +Consider the following example that defines an inner function: +```julia +function abmult(r::Int) + if r < 0 + r = -r + end + f = x -> x * r + return f +end +``` + +Function `abmult` returns a function `f` that multiplies its argument by +the absolute value of `r`. The inner function assigned to `f` is called a +"closure". Inner functions are also used by the +language for `do`-blocks and for generator expressions. + +This style of code presents performance challenges for the language. +The parser, when translating it into lower-level instructions, +substantially reorganizes the above code by extracting the +inner function to a separate code block. "Captured" variables such as `r` +that are shared by inner functions and their enclosing scope are +also extracted into a heap-allocated "box" accessible to both inner and +outer functions because the language specifies that `r` in the +inner scope must be identical to `r` in the outer scope even after the +outer scope (or another inner function) modifies `r`. + +The discussion in the preceding paragraph referred to the "parser", that is, the phase +of compilation that takes place when the module containing `abmult` is first loaded, +as opposed to the later phase when it is first invoked. The parser does not "know" that +`Int` is a fixed type, or that the statement `r = -r` tranforms an `Int` to another `Int`. +The magic of type inference takes place in the later phase of compilation. + +Thus, the parser does not know that `r` has a fixed type (`Int`). +nor that `r` does not change value once the inner function is created (so that +the box is unneeded). Therefore, the parser emits code for +box that holds an object with an abstract type such as `Any`, which +requires run-time type dispatch for each occurrence of `r`. This can be +verified by applying `@code_warntype` to the above function. Both the boxing +and the run-time type dispatch can cause loss of performance. + +If captured variables are used in a performance-critical section of the code, +then the following tips help ensure that their use is performant. First, if +it is known that a captured variable does not change its type, then this can +be declared explicitly with a type annotation (on the variable, not the +right-hand side): +```julia +function abmult2(r0::Int) + r::Int = r0 + if r < 0 + r = -r + end + f = x -> x * r + return f +end +``` +The type annotation partially recovers lost performance due to capturing because +the parser can associate a concrete type to the object in the box. +Going further, if the captured variable does not need to be boxed at all (because it +will not be reassigned after the closure is created), this can be indicated +with `let` blocks as follows. +```julia +function abmult3(r::Int) + if r < 0 + r = -r + end + f = let r = r + x -> x * r + end + return f +end +``` +The `let` block creates a new variable `r` whose scope is only the +inner function. The second technique recovers full language performance +in the presence of captured variables. Note that this is a rapidly +evolving aspect of the compiler, and it is likely that future releases +will not require this degree of programmer annotation to attain peformance. +In the mean time, some user-contributed packages like +[FastClosures](https://github.com/c42f/FastClosures.jl) automate the +insertion of `let` statements as in `abmult3`. diff --git a/src/manual/style-guide.md b/src/manual/style-guide.md index 10355e4..624297d 100644 --- a/src/manual/style-guide.md +++ b/src/manual/style-guide.md @@ -119,27 +119,6 @@ is typical for such functions to also return the modified array for convenience. Types such as `Union{Function,AbstractString}` are often a sign that some design could be cleaner. -## Avoid type Unions in fields - -When creating a type such as: - -```julia -mutable struct MyType - ... - x::Union{Nothing,T} -end -``` - -ask whether the option for `x` to be `nothing` (of type `Nothing`) is really necessary. Here are -some alternatives to consider: - - * Find a safe default value to initialize `x` with - * Introduce another type that lacks `x` - * If there are many fields like `x`, store them in a dictionary - * Determine whether there is a simple rule for when `x` is `nothing`. For example, often the field - will start as `nothing` but get initialized at some well-defined point. In that case, consider - leaving it undefined at first. - ## Avoid elaborate container types It is usually not much help to construct arrays like the following: diff --git a/src/manual/types.md b/src/manual/types.md index 514c5a0..a56ffd2 100644 --- a/src/manual/types.md +++ b/src/manual/types.md @@ -442,7 +442,7 @@ To recap, two essential properties define immutability in Julia: always refer to the same mutable value even though that mutable value's content may itself be modified. * An object with an immutable type may be copied freely by the compiler since its - immutabity makes it impossible to programmatically distinguish between the original + immutability makes it impossible to programmatically distinguish between the original object and a copy. * In particular, this means that small enough immutable values like integers and floats are typically passed to functions in registers (or stack allocated). @@ -480,7 +480,7 @@ Every concrete value in the system is an instance of some `DataType`. ## Type Unions A type union is a special abstract type which includes as objects all instances of any of its -argument types, constructed using the special `Union` function: +argument types, constructed using the special `Union` keyword: ```jldoctest julia> IntOrString = Union{Int,AbstractString} @@ -497,7 +497,16 @@ ERROR: TypeError: in typeassert, expected Union{Int64, AbstractString}, got Floa ``` The compilers for many languages have an internal union construct for reasoning about types; Julia -simply exposes it to the programmer. +simply exposes it to the programmer. The Julia compiler is able to generate efficient code in the +presence of `Union` types with a small number of types [^1], by generating specialized code +in separate branches for each possible type. + +A particularly useful case of a `Union` type is `Union{T, Nothing}`, where `T` can be any type and +[`Nothing`](@ref) is the singleton type whose only instance is the object `nothing`. This pattern +is the Julia equivalent of [`Nullable`, `Option` or `Maybe`](https://en.wikipedia.org/wiki/Nullable_type) +types in other languages. Declaring a function argument or a field as `Union{T, Nothing}` allows +setting it either to a value of type `T`, or to `nothing` to indicate that there is no value. +See [this FAQ entry](@ref faq-nothing) for more information. ## Parametric Types @@ -1403,3 +1412,5 @@ It's worth noting that it's extremely easy to mis-use parametric "value" types, in unfavorable cases, you can easily end up making the performance of your code much *worse*. In particular, you would never want to write actual code as illustrated above. For more information about the proper (and improper) uses of `Val`, please read the more extensive discussion in [the performance tips](@ref man-performance-tips). + +[^1]: "Small" is defined by the `MAX_UNION_SPLITTING` constant, which is currently set to 4. diff --git a/src/manual/variables-and-scoping.md b/src/manual/variables-and-scoping.md index 45a150f..496730a 100644 --- a/src/manual/variables-and-scoping.md +++ b/src/manual/variables-and-scoping.md @@ -262,7 +262,11 @@ julia> counter() 2 ``` -See also the closures in the examples in the next two sections. +See also the closures in the examples in the next two sections. A variable +such as `x` in the first example and `state` in the second that is inherited +from the enclosing scope by the inner function is sometimes called a +*captured* variable. Captured variables can present performance challenges +discussed in [performance tips](@ref man-performance-tips). The distinction between inheriting global scope and nesting local scope can lead to some slight differences between functions diff --git a/src/stdlib/InteractiveUtils.md b/src/stdlib/InteractiveUtils.md index 656780c..7e313b8 100644 --- a/src/stdlib/InteractiveUtils.md +++ b/src/stdlib/InteractiveUtils.md @@ -26,6 +26,7 @@ InteractiveUtils.code_llvm InteractiveUtils.@code_llvm InteractiveUtils.code_native InteractiveUtils.@code_native +InteractiveUtils.clipboard ``` ```@meta diff --git a/src/stdlib/Pkg.md b/src/stdlib/Pkg.md index f84fc76..0f08a5c 100644 --- a/src/stdlib/Pkg.md +++ b/src/stdlib/Pkg.md @@ -92,9 +92,9 @@ since that could conflict with the configuration of the main application. !!! note **Projects _vs._ Packages _vs._ Applications:** - 1. Project is an umbrella term: packages and applications are kinds of projects. - 2. Packages should have UUIDs, applications can have a UUIDs but don't need them. - 3. Applications can provide global configuration, whereas packages cannot. + 1. **Project** is an umbrella term: packages and applications are kinds of projects. + 2. **Packages** should have UUIDs, applications can have a UUIDs but don't need them. + 3. **Applications** can provide global configuration, whereas packages cannot. **Library (future work):** a compiled binary dependency (not written in Julia) packaged to be used by a Julia project. These are currently typically built in- @@ -470,7 +470,8 @@ Initialized project at /Users/kristoffer/MyProject/Project.toml Status `Project.toml` ``` -Note that the REPL prompt changed when the new project was initiated. Since this is a newly created project, the status command show it contains no packages. +Note that the REPL prompt changed when the new project was initiated, in other words, Pkg automatically set the current environment to the +one that just got initiated. Since this is a newly created project, the status command show it contains no packages. Packages added here again in a completely separate environment from the one earlier used. ## Garbage collecting old, unused packages @@ -512,7 +513,8 @@ To generate files for a new package, use `pkg> generate`. This creates a new project `HelloWorld` with the following files (visualized with the external [`tree` command](https://linux.die.net/man/1/tree)): ```jl -julia> cd("HelloWorld") +shell> cd HelloWorld + shell> tree . . ├── Project.toml @@ -543,9 +545,11 @@ greet() = print("Hello World!") end # module ``` -We can now load the project and use it: +We can now activate the project and load the package: ```jl +pkg> activate + julia> import HelloWorld julia> HelloWorld.greet() @@ -651,7 +655,7 @@ Testing... #### Test-specific dependencies -Sometimes one might to want to use some packages only at testing time but not enforce a dependency on them when the package is used. +Sometimes one might want to use some packages only at testing time but not enforce a dependency on them when the package is used. This is possible by adding dependencies to a "test target" to the Project file. Here we add the `Test` standard library as a test-only dependency by adding the following to the Project file: @@ -744,7 +748,7 @@ The REPL command `precompile` can be used to precompile all the dependencies in (HelloWorld) pkg> update; precompile ``` -do update the dependencies and then precompile them. +to update the dependencies and then precompile them. ## Preview mode @@ -766,9 +770,11 @@ However, nothing would be installed and your `Project.toml` and `Manifest.toml` ## Using someone else's project -Simple clone their project using e.g. `git clone`, `cd` to the project directory and call +Simply clone their project using e.g. `git clone`, `cd` to the project directory and call ``` +(v0.7) pkg> activate + (SomeProject) pkg> instantiate ``` diff --git a/src/stdlib/Random.md b/src/stdlib/Random.md index 5607ba0..86afd63 100644 --- a/src/stdlib/Random.md +++ b/src/stdlib/Random.md @@ -21,7 +21,7 @@ A `MersenneTwister` or `RandomDevice` RNG can generate random numbers of the fol [`UInt32`](@ref), [`Int64`](@ref), [`UInt64`](@ref), [`Int128`](@ref), [`UInt128`](@ref), [`BigInt`](@ref) (or complex numbers of those types). Random floating point numbers are generated uniformly in ``[0, 1)``. As `BigInt` represents -unbounded integers, the interval must be specified (e.g. `rand(big(1:6))`). +unbounded integers, the interval must be specified (e.g. `rand(big.(1:6))`). ```@docs Random.srand diff --git a/src/stdlib/random.md b/src/stdlib/random.md index 5607ba0..86afd63 100644 --- a/src/stdlib/random.md +++ b/src/stdlib/random.md @@ -21,7 +21,7 @@ A `MersenneTwister` or `RandomDevice` RNG can generate random numbers of the fol [`UInt32`](@ref), [`Int64`](@ref), [`UInt64`](@ref), [`Int128`](@ref), [`UInt128`](@ref), [`BigInt`](@ref) (or complex numbers of those types). Random floating point numbers are generated uniformly in ``[0, 1)``. As `BigInt` represents -unbounded integers, the interval must be specified (e.g. `rand(big(1:6))`). +unbounded integers, the interval must be specified (e.g. `rand(big.(1:6))`). ```@docs Random.srand From 8d04aa4a0518a9c5d37dcc3f2cb06d02213dd4ca Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Tue, 3 Jul 2018 12:57:28 +0900 Subject: [PATCH 039/153] update Julia Commit 051056b4fd --- codex/NEWS.md | 10 +++++++ codex/base/collections.md | 9 +------ codex/base/math.md | 12 --------- codex/manual/faq.md | 14 +++++----- .../integers-and-floating-point-numbers.md | 8 ++++-- codex/manual/interfaces.md | 15 ++++++----- codex/manual/missing.md | 2 +- codex/stdlib/Pkg.md | 4 +-- codex/stdlib/Statistics.md | 27 +++++++++++++++++++ src/NEWS.md | 10 +++++++ src/base/collections.md | 9 +------ src/base/math.md | 12 --------- src/manual/faq.md | 14 +++++----- .../integers-and-floating-point-numbers.md | 7 ++++- src/manual/interfaces.md | 15 ++++++----- src/manual/missing.md | 2 +- src/stdlib/Pkg.md | 4 +-- src/stdlib/Statistics.md | 27 +++++++++++++++++++ 18 files changed, 126 insertions(+), 75 deletions(-) create mode 100644 codex/stdlib/Statistics.md create mode 100644 src/stdlib/Statistics.md diff --git a/codex/NEWS.md b/codex/NEWS.md index 40c86ba..f3ec58c 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -72,6 +72,9 @@ Language changes * Juxtaposing binary, octal, and hexadecimal literals is deprecated, since it can lead to confusing code such as `0xapi == 0xa * pi` ([#16356](https://github.com/JuliaLang/julia/issues/16356)). + * Numeric literal juxtaposition now has slighty lower precedence than unary operators, + so for example `√2x` parses as `(√2) * x` ([#27641](https://github.com/JuliaLang/julia/issues/27641)). + * Declaring arguments as `x::ANY` to avoid specialization has been replaced by `@nospecialize x`. ([#22666](https://github.com/JuliaLang/julia/issues/22666)). @@ -713,6 +716,13 @@ Library improvements * Added an optimized method of `vecdot` for taking the Frobenius inner product of sparse matrices. ([#27470](https://github.com/JuliaLang/julia/issues/27470)) + * Added an optimized method of `kron` for taking the tensor product of two + `Diagonal` matrices. ([27581]) + + * The initial element `v0` in `reduce(op, v0, itr)` has been replaced with an `init` + optional keyword argument, as in `reduce(op, itr; init=v0)`. Similarly for `foldl`, + `foldr`, `mapreduce`, `mapfoldl` and `mapfoldr`. ([#27711](https://github.com/JuliaLang/julia/issues/27711)) + Compiler/Runtime improvements ----------------------------- diff --git a/codex/base/collections.md b/codex/base/collections.md index 4a64aea..0396091 100644 --- a/codex/base/collections.md +++ b/codex/base/collections.md @@ -82,18 +82,14 @@ Base.indexin Base.unique Base.unique! Base.allunique -Base.reduce(::Any, ::Any, ::Any) Base.reduce(::Any, ::Any) -Base.foldl(::Any, ::Any, ::Any) Base.foldl(::Any, ::Any) -Base.foldr(::Any, ::Any, ::Any) Base.foldr(::Any, ::Any) Base.maximum Base.maximum! Base.minimum Base.minimum! -Base.extrema(::Any) -Base.extrema(::AbstractArray, ::Any) +Base.extrema Base.argmax Base.argmin Base.findmax @@ -116,11 +112,8 @@ Base.all(::Any, ::Any) Base.foreach Base.map Base.map! -Base.mapreduce(::Any, ::Any, ::Any, ::Any) Base.mapreduce(::Any, ::Any, ::Any) -Base.mapfoldl(::Any, ::Any, ::Any, ::Any) Base.mapfoldl(::Any, ::Any, ::Any) -Base.mapfoldr(::Any, ::Any, ::Any, ::Any) Base.mapfoldr(::Any, ::Any, ::Any) Base.first Base.last diff --git a/codex/base/math.md b/codex/base/math.md index 91e8d07..0fa973d 100644 --- a/codex/base/math.md +++ b/codex/base/math.md @@ -177,15 +177,3 @@ Base.widemul Base.Math.@evalpoly Base.FastMath.@fastmath ``` - -## Statistics - -```@docs -Base.mean -Base.mean! -Base.middle -Base.median -Base.median! -Base.quantile -Base.quantile! -``` diff --git a/codex/manual/faq.md b/codex/manual/faq.md index a578023..25b69d8 100644 --- a/codex/manual/faq.md +++ b/codex/manual/faq.md @@ -759,15 +759,15 @@ zero-dimensional arrays are not empty. If you find this unintuitive, here are some ideas that might help to understand Julia's definition. * Zero-dimensional arrays are the "point" to vector's "line" and matrix's -"plane". Just as a line has no area (but still represents a set of things), a -point has no length or any dimensions at all (but still represents a thing). + "plane". Just as a line has no area (but still represents a set of things), a + point has no length or any dimensions at all (but still represents a thing). * We define `prod(())` to be 1, and the total number of elements in an array is -the product of the size. The size of a zero-dimensional array is `()`, and -therefore its length is `1`. + the product of the size. The size of a zero-dimensional array is `()`, and + therefore its length is `1`. * Zero-dimensional arrays don't natively have any dimensions into which you -index -- they’re just `A[]`. We can apply the same "trailing one" rule for them -as for all other array dimensionalities, so you can indeed index them as -`A[1]`, `A[1,1]`, etc. + index -- they’re just `A[]`. We can apply the same "trailing one" rule for them + as for all other array dimensionalities, so you can indeed index them as + `A[1]`, `A[1,1]`, etc. It is also important to understand the differences to ordinary scalars. Scalars are not mutable containers (even though they are iterable and define things diff --git a/codex/manual/integers-and-floating-point-numbers.md b/codex/manual/integers-and-floating-point-numbers.md index ab2f2a6..b218ab8 100644 --- a/codex/manual/integers-and-floating-point-numbers.md +++ b/codex/manual/integers-and-floating-point-numbers.md @@ -618,8 +618,12 @@ julia> 2^2x 64 ``` -The precedence of numeric literal coefficients is the same as that of unary operators such as -negation. So `2^3x` is parsed as `2^(3x)`, and `2x^3` is parsed as `2*(x^3)`. +The precedence of numeric literal coefficients is slightly lower than that of +unary operators such as negation. +So `-2x` is parsed as `(-2) * x` and `√2x` is parsed as `(√2) * x`. +However, numeric literal coefficients parse similarly to unary operators when +combined with exponentiation. +For example `2^3x` is parsed as `2^(3x)`, and `2x^3` is parsed as `2*(x^3)`. Numeric literals also work as coefficients to parenthesized expressions: diff --git a/codex/manual/interfaces.md b/codex/manual/interfaces.md index abdf611..618f55f 100644 --- a/codex/manual/interfaces.md +++ b/codex/manual/interfaces.md @@ -83,18 +83,21 @@ julia> for i in Squares(7) 49 ``` -We can use many of the builtin methods that work with iterables, like [`in`](@ref), -[`sum`](@ref) and [`mean`](@ref): +We can use many of the builtin methods that work with iterables, +like [`in`](@ref), or [`mean`](@ref) and [`std`](@ref) from the +`Statistics` standard library module: ```jldoctest squaretype julia> 25 in Squares(10) true -julia> sum(Squares(100)) -338350 +julia> using Statistics julia> mean(Squares(100)) 3383.5 + +julia> std(Squares(100)) +3024.355854282583 ``` There are a few more methods we can extend to give Julia more information about this iterable @@ -388,8 +391,8 @@ julia> A[SquaresVector(3)] 4.0 9.0 -julia> mean(A) -5.0 +julia> sum(A) +45.0 ``` If you are defining an array type that allows non-traditional indexing (indices that start at diff --git a/codex/manual/missing.md b/codex/manual/missing.md index 4467f58..67b349f 100644 --- a/codex/manual/missing.md +++ b/codex/manual/missing.md @@ -294,7 +294,7 @@ julia> sum(skipmissing([1, missing])) This convenience function returns an iterator which filters out `missing` values efficiently. It can therefore be used with any function which supports iterators -```jldoctest +```jldoctest; setup = :(using Statistics) julia> maximum(skipmissing([3, missing, 2, 1])) 3 diff --git a/codex/stdlib/Pkg.md b/codex/stdlib/Pkg.md index 0f08a5c..6b88225 100644 --- a/codex/stdlib/Pkg.md +++ b/codex/stdlib/Pkg.md @@ -548,7 +548,7 @@ end # module We can now activate the project and load the package: ```jl -pkg> activate +pkg> activate . julia> import HelloWorld @@ -773,7 +773,7 @@ However, nothing would be installed and your `Project.toml` and `Manifest.toml` Simply clone their project using e.g. `git clone`, `cd` to the project directory and call ``` -(v0.7) pkg> activate +(v0.7) pkg> activate . (SomeProject) pkg> instantiate ``` diff --git a/codex/stdlib/Statistics.md b/codex/stdlib/Statistics.md new file mode 100644 index 0000000..5a68454 --- /dev/null +++ b/codex/stdlib/Statistics.md @@ -0,0 +1,27 @@ +# Statistics + +```@meta +DocTestSetup = :(using Statistics) +``` + +The Statistics module contains basic statistics functionality. + +```@docs +Statistics.std +Statistics.stdm +Statistics.var +Statistics.varm +Statistics.cor +Statistics.cov +Statistics.mean! +Statistics.mean +Statistics.median! +Statistics.median +Statistics.middle +Statistics.quantile! +Statistics.quantile +``` + +```@meta +DocTestSetup = nothing +``` diff --git a/src/NEWS.md b/src/NEWS.md index 99b814b..880f76f 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -60,6 +60,9 @@ Language changes * Juxtaposing binary, octal, and hexadecimal literals is deprecated, since it can lead to confusing code such as `0xapi == 0xa * pi` ([#16356](https://github.com/JuliaLang/julia/issues/16356)). + * Numeric literal juxtaposition now has slighty lower precedence than unary operators, + so for example `√2x` parses as `(√2) * x` ([#27641](https://github.com/JuliaLang/julia/issues/27641)). + * Declaring arguments as `x::ANY` to avoid specialization has been replaced by `@nospecialize x`. ([#22666](https://github.com/JuliaLang/julia/issues/22666)). @@ -701,6 +704,13 @@ Library improvements * Added an optimized method of `vecdot` for taking the Frobenius inner product of sparse matrices. ([#27470](https://github.com/JuliaLang/julia/issues/27470)) + * Added an optimized method of `kron` for taking the tensor product of two + `Diagonal` matrices. ([27581]) + + * The initial element `v0` in `reduce(op, v0, itr)` has been replaced with an `init` + optional keyword argument, as in `reduce(op, itr; init=v0)`. Similarly for `foldl`, + `foldr`, `mapreduce`, `mapfoldl` and `mapfoldr`. ([#27711](https://github.com/JuliaLang/julia/issues/27711)) + Compiler/Runtime improvements ----------------------------- diff --git a/src/base/collections.md b/src/base/collections.md index 4a64aea..0396091 100644 --- a/src/base/collections.md +++ b/src/base/collections.md @@ -82,18 +82,14 @@ Base.indexin Base.unique Base.unique! Base.allunique -Base.reduce(::Any, ::Any, ::Any) Base.reduce(::Any, ::Any) -Base.foldl(::Any, ::Any, ::Any) Base.foldl(::Any, ::Any) -Base.foldr(::Any, ::Any, ::Any) Base.foldr(::Any, ::Any) Base.maximum Base.maximum! Base.minimum Base.minimum! -Base.extrema(::Any) -Base.extrema(::AbstractArray, ::Any) +Base.extrema Base.argmax Base.argmin Base.findmax @@ -116,11 +112,8 @@ Base.all(::Any, ::Any) Base.foreach Base.map Base.map! -Base.mapreduce(::Any, ::Any, ::Any, ::Any) Base.mapreduce(::Any, ::Any, ::Any) -Base.mapfoldl(::Any, ::Any, ::Any, ::Any) Base.mapfoldl(::Any, ::Any, ::Any) -Base.mapfoldr(::Any, ::Any, ::Any, ::Any) Base.mapfoldr(::Any, ::Any, ::Any) Base.first Base.last diff --git a/src/base/math.md b/src/base/math.md index 91e8d07..0fa973d 100644 --- a/src/base/math.md +++ b/src/base/math.md @@ -177,15 +177,3 @@ Base.widemul Base.Math.@evalpoly Base.FastMath.@fastmath ``` - -## Statistics - -```@docs -Base.mean -Base.mean! -Base.middle -Base.median -Base.median! -Base.quantile -Base.quantile! -``` diff --git a/src/manual/faq.md b/src/manual/faq.md index a578023..25b69d8 100644 --- a/src/manual/faq.md +++ b/src/manual/faq.md @@ -759,15 +759,15 @@ zero-dimensional arrays are not empty. If you find this unintuitive, here are some ideas that might help to understand Julia's definition. * Zero-dimensional arrays are the "point" to vector's "line" and matrix's -"plane". Just as a line has no area (but still represents a set of things), a -point has no length or any dimensions at all (but still represents a thing). + "plane". Just as a line has no area (but still represents a set of things), a + point has no length or any dimensions at all (but still represents a thing). * We define `prod(())` to be 1, and the total number of elements in an array is -the product of the size. The size of a zero-dimensional array is `()`, and -therefore its length is `1`. + the product of the size. The size of a zero-dimensional array is `()`, and + therefore its length is `1`. * Zero-dimensional arrays don't natively have any dimensions into which you -index -- they’re just `A[]`. We can apply the same "trailing one" rule for them -as for all other array dimensionalities, so you can indeed index them as -`A[1]`, `A[1,1]`, etc. + index -- they’re just `A[]`. We can apply the same "trailing one" rule for them + as for all other array dimensionalities, so you can indeed index them as + `A[1]`, `A[1,1]`, etc. It is also important to understand the differences to ordinary scalars. Scalars are not mutable containers (even though they are iterable and define things diff --git a/src/manual/integers-and-floating-point-numbers.md b/src/manual/integers-and-floating-point-numbers.md index a3b43b6..35c831c 100644 --- a/src/manual/integers-and-floating-point-numbers.md +++ b/src/manual/integers-and-floating-point-numbers.md @@ -550,7 +550,12 @@ julia> 2^2x 64 ``` -수치형 리터럴 계수의 선행(precedence)도 부정연산과 같은 단항 연산과 같이 작동한다. 따라서 `2^3x`는 `2^(3x)`으로, `2x^3`은 `2*(x^3)`으로 파싱(parsing)된다. +The precedence of numeric literal coefficients is slightly lower than that of +unary operators such as negation. +So `-2x` is parsed as `(-2) * x` and `√2x` is parsed as `(√2) * x`. +However, numeric literal coefficients parse similarly to unary operators when +combined with exponentiation. +For example `2^3x` is parsed as `2^(3x)`, and `2x^3` is parsed as `2*(x^3)`. 수치형 리터럴은 괄호가 있는 식에서도 계수(coeffiients)로 작동할 수 있다: diff --git a/src/manual/interfaces.md b/src/manual/interfaces.md index abdf611..618f55f 100644 --- a/src/manual/interfaces.md +++ b/src/manual/interfaces.md @@ -83,18 +83,21 @@ julia> for i in Squares(7) 49 ``` -We can use many of the builtin methods that work with iterables, like [`in`](@ref), -[`sum`](@ref) and [`mean`](@ref): +We can use many of the builtin methods that work with iterables, +like [`in`](@ref), or [`mean`](@ref) and [`std`](@ref) from the +`Statistics` standard library module: ```jldoctest squaretype julia> 25 in Squares(10) true -julia> sum(Squares(100)) -338350 +julia> using Statistics julia> mean(Squares(100)) 3383.5 + +julia> std(Squares(100)) +3024.355854282583 ``` There are a few more methods we can extend to give Julia more information about this iterable @@ -388,8 +391,8 @@ julia> A[SquaresVector(3)] 4.0 9.0 -julia> mean(A) -5.0 +julia> sum(A) +45.0 ``` If you are defining an array type that allows non-traditional indexing (indices that start at diff --git a/src/manual/missing.md b/src/manual/missing.md index 4467f58..67b349f 100644 --- a/src/manual/missing.md +++ b/src/manual/missing.md @@ -294,7 +294,7 @@ julia> sum(skipmissing([1, missing])) This convenience function returns an iterator which filters out `missing` values efficiently. It can therefore be used with any function which supports iterators -```jldoctest +```jldoctest; setup = :(using Statistics) julia> maximum(skipmissing([3, missing, 2, 1])) 3 diff --git a/src/stdlib/Pkg.md b/src/stdlib/Pkg.md index 0f08a5c..6b88225 100644 --- a/src/stdlib/Pkg.md +++ b/src/stdlib/Pkg.md @@ -548,7 +548,7 @@ end # module We can now activate the project and load the package: ```jl -pkg> activate +pkg> activate . julia> import HelloWorld @@ -773,7 +773,7 @@ However, nothing would be installed and your `Project.toml` and `Manifest.toml` Simply clone their project using e.g. `git clone`, `cd` to the project directory and call ``` -(v0.7) pkg> activate +(v0.7) pkg> activate . (SomeProject) pkg> instantiate ``` diff --git a/src/stdlib/Statistics.md b/src/stdlib/Statistics.md new file mode 100644 index 0000000..5a68454 --- /dev/null +++ b/src/stdlib/Statistics.md @@ -0,0 +1,27 @@ +# Statistics + +```@meta +DocTestSetup = :(using Statistics) +``` + +The Statistics module contains basic statistics functionality. + +```@docs +Statistics.std +Statistics.stdm +Statistics.var +Statistics.varm +Statistics.cor +Statistics.cov +Statistics.mean! +Statistics.mean +Statistics.median! +Statistics.median +Statistics.middle +Statistics.quantile! +Statistics.quantile +``` + +```@meta +DocTestSetup = nothing +``` From 0f3e8a2905f451d963a8f4e5a554dd126ba30838 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Sat, 7 Jul 2018 23:06:57 +0900 Subject: [PATCH 040/153] update Julia Commit 069314b687 --- codex/NEWS.md | 5 +++++ codex/manual/parallel-computing.md | 9 ++++++--- codex/stdlib/Pkg.md | 17 +++++++++++++++-- codex/stdlib/Random.md | 1 - codex/stdlib/random.md | 1 - src/NEWS.md | 5 +++++ src/manual/parallel-computing.md | 9 ++++++--- src/stdlib/Pkg.md | 17 +++++++++++++++-- src/stdlib/Random.md | 1 - src/stdlib/random.md | 1 - 10 files changed, 52 insertions(+), 14 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index f3ec58c..e5ea9c0 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -1228,6 +1228,9 @@ Deprecated or removed * `rand(t::Tuple{Vararg{Int}})` is deprecated in favor of `rand(Float64, t)` or `rand(t...)`; `rand(::Tuple)` will have another meaning in the future ([#25429](https://github.com/JuliaLang/julia/issues/25429), [#25278](https://github.com/JuliaLang/julia/issues/25278)). + * `randjump`, which produced an array, is deprecated in favor of the + scalar version `Future.randjump` used with `accumulate` ([#27746](https://github.com/JuliaLang/julia/issues/27746)). + * The `assert` function (and `@assert` macro) have been documented that they are not guaranteed to run under various optimization levels and should therefore not be used to e.g. verify passwords. * `ObjectIdDict` has been deprecated in favor of `IdDict{Any,Any}` ([#25210](https://github.com/JuliaLang/julia/issues/25210)). @@ -1300,6 +1303,8 @@ Deprecated or removed (along with other utilities mostly used at the interactive prompt, such as `edit` and `less`) ([#27635](https://github.com/JuliaLang/julia/issues/27635)). + * `ndigits(n, b, [pad])` is deprecated in favor of `ndigits(n, base=b, pad=pad)` ([#27908](https://github.com/JuliaLang/julia/issues/27908)). + Command-line option changes --------------------------- diff --git a/codex/manual/parallel-computing.md b/codex/manual/parallel-computing.md index 640a3e3..a88dd04 100644 --- a/codex/manual/parallel-computing.md +++ b/codex/manual/parallel-computing.md @@ -1576,11 +1576,11 @@ creates separate instances of `Regex` object for each entry of `rx` vector. The case of `rand` is a bit more complex as we have to ensure that each thread uses non-overlapping pseudorandom number sequences. This can be simply ensured -by using [`randjump`](@ref) function: +by using the `Future.randjump` function: ```julia-repl -julia> using Random +julia> using Random; import Future julia> function g_fix(r) a = zeros(1000) @@ -1591,7 +1591,10 @@ julia> function g_fix(r) end g_fix (generic function with 1 method) -julia> r = randjump(MersenneTwister(1), big(10)^20, nthreads()); +julia> r = let m = MersenneTwister(1) + [m; accumulate(Future.randjump, m, fill(big(10)^20, nthreads()-1))] + end; + julia> g_fix(r) 1000 ``` diff --git a/codex/stdlib/Pkg.md b/codex/stdlib/Pkg.md index 6b88225..6e9c8f4 100644 --- a/codex/stdlib/Pkg.md +++ b/codex/stdlib/Pkg.md @@ -84,8 +84,9 @@ identify the package in projects that depend on it. **Application:** a project which provides standalone functionality not intended to be reused by other Julia projects. For example a web application or a -commmand-line utility. An application may have a UUID but does not need one. An -application may also provide global configuration options for packages it +commmand-line utility, or simulation/analytics code accompanying a scientific paper. +An application may have a UUID but does not need one. +An application may also provide global configuration options for packages it depends on. Packages, on the other hand, may not provide global configuration since that could conflict with the configuration of the main application. @@ -707,6 +708,7 @@ Similar to other package managers, the Julia package manager respects [semantic As an example, a version specifier is given as e.g. `1.2.3` is therefore assumed to be compatible with the versions `[1.2.3 - 2.0.0)` where `)` is a non-inclusive upper bound. More specifically, a version specifier is either given as a **caret specifier**, e.g. `^1.2.3` or a **tilde specifier** `~1.2.3`. Caret specifiers are the default and hence `1.2.3 == ^1.2.3`. The difference between a caret and tilde is described in the next section. +The intersection of multiple version specifiers can be formed by comma separating indiviual version specifiers. ##### Caret specifiers @@ -739,6 +741,17 @@ This gives the following example. ~1 = [1.0.0, 2.0.0) ``` +#### Inequality specifiers + +Inequalities can also be used to specify version ranges: + +``` +>= 1.2.3 = [1.2.3, ∞) +≥ 1.2.3 = [1.2.3, ∞) += 1.2.3 = [1.2.3, 1.2.3] +< 1.2.3 = [0.0.0, 1.2.2] +``` + ## Precompiling a project diff --git a/codex/stdlib/Random.md b/codex/stdlib/Random.md index 86afd63..f72488e 100644 --- a/codex/stdlib/Random.md +++ b/codex/stdlib/Random.md @@ -34,7 +34,6 @@ Random.randn Random.randn! Random.randexp Random.randexp! -Random.randjump Random.randstring Random.randsubseq Random.randsubseq! diff --git a/codex/stdlib/random.md b/codex/stdlib/random.md index 86afd63..f72488e 100644 --- a/codex/stdlib/random.md +++ b/codex/stdlib/random.md @@ -34,7 +34,6 @@ Random.randn Random.randn! Random.randexp Random.randexp! -Random.randjump Random.randstring Random.randsubseq Random.randsubseq! diff --git a/src/NEWS.md b/src/NEWS.md index 880f76f..534a621 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -1216,6 +1216,9 @@ Deprecated or removed * `rand(t::Tuple{Vararg{Int}})` is deprecated in favor of `rand(Float64, t)` or `rand(t...)`; `rand(::Tuple)` will have another meaning in the future ([#25429](https://github.com/JuliaLang/julia/issues/25429), [#25278](https://github.com/JuliaLang/julia/issues/25278)). + * `randjump`, which produced an array, is deprecated in favor of the + scalar version `Future.randjump` used with `accumulate` ([#27746](https://github.com/JuliaLang/julia/issues/27746)). + * The `assert` function (and `@assert` macro) have been documented that they are not guaranteed to run under various optimization levels and should therefore not be used to e.g. verify passwords. * `ObjectIdDict` has been deprecated in favor of `IdDict{Any,Any}` ([#25210](https://github.com/JuliaLang/julia/issues/25210)). @@ -1288,6 +1291,8 @@ Deprecated or removed (along with other utilities mostly used at the interactive prompt, such as `edit` and `less`) ([#27635](https://github.com/JuliaLang/julia/issues/27635)). + * `ndigits(n, b, [pad])` is deprecated in favor of `ndigits(n, base=b, pad=pad)` ([#27908](https://github.com/JuliaLang/julia/issues/27908)). + Command-line option changes --------------------------- diff --git a/src/manual/parallel-computing.md b/src/manual/parallel-computing.md index 640a3e3..a88dd04 100644 --- a/src/manual/parallel-computing.md +++ b/src/manual/parallel-computing.md @@ -1576,11 +1576,11 @@ creates separate instances of `Regex` object for each entry of `rx` vector. The case of `rand` is a bit more complex as we have to ensure that each thread uses non-overlapping pseudorandom number sequences. This can be simply ensured -by using [`randjump`](@ref) function: +by using the `Future.randjump` function: ```julia-repl -julia> using Random +julia> using Random; import Future julia> function g_fix(r) a = zeros(1000) @@ -1591,7 +1591,10 @@ julia> function g_fix(r) end g_fix (generic function with 1 method) -julia> r = randjump(MersenneTwister(1), big(10)^20, nthreads()); +julia> r = let m = MersenneTwister(1) + [m; accumulate(Future.randjump, m, fill(big(10)^20, nthreads()-1))] + end; + julia> g_fix(r) 1000 ``` diff --git a/src/stdlib/Pkg.md b/src/stdlib/Pkg.md index 6b88225..6e9c8f4 100644 --- a/src/stdlib/Pkg.md +++ b/src/stdlib/Pkg.md @@ -84,8 +84,9 @@ identify the package in projects that depend on it. **Application:** a project which provides standalone functionality not intended to be reused by other Julia projects. For example a web application or a -commmand-line utility. An application may have a UUID but does not need one. An -application may also provide global configuration options for packages it +commmand-line utility, or simulation/analytics code accompanying a scientific paper. +An application may have a UUID but does not need one. +An application may also provide global configuration options for packages it depends on. Packages, on the other hand, may not provide global configuration since that could conflict with the configuration of the main application. @@ -707,6 +708,7 @@ Similar to other package managers, the Julia package manager respects [semantic As an example, a version specifier is given as e.g. `1.2.3` is therefore assumed to be compatible with the versions `[1.2.3 - 2.0.0)` where `)` is a non-inclusive upper bound. More specifically, a version specifier is either given as a **caret specifier**, e.g. `^1.2.3` or a **tilde specifier** `~1.2.3`. Caret specifiers are the default and hence `1.2.3 == ^1.2.3`. The difference between a caret and tilde is described in the next section. +The intersection of multiple version specifiers can be formed by comma separating indiviual version specifiers. ##### Caret specifiers @@ -739,6 +741,17 @@ This gives the following example. ~1 = [1.0.0, 2.0.0) ``` +#### Inequality specifiers + +Inequalities can also be used to specify version ranges: + +``` +>= 1.2.3 = [1.2.3, ∞) +≥ 1.2.3 = [1.2.3, ∞) += 1.2.3 = [1.2.3, 1.2.3] +< 1.2.3 = [0.0.0, 1.2.2] +``` + ## Precompiling a project diff --git a/src/stdlib/Random.md b/src/stdlib/Random.md index 86afd63..f72488e 100644 --- a/src/stdlib/Random.md +++ b/src/stdlib/Random.md @@ -34,7 +34,6 @@ Random.randn Random.randn! Random.randexp Random.randexp! -Random.randjump Random.randstring Random.randsubseq Random.randsubseq! diff --git a/src/stdlib/random.md b/src/stdlib/random.md index 86afd63..f72488e 100644 --- a/src/stdlib/random.md +++ b/src/stdlib/random.md @@ -34,7 +34,6 @@ Random.randn Random.randn! Random.randexp Random.randexp! -Random.randjump Random.randstring Random.randsubseq Random.randsubseq! From 914e5ec06d68044e8b2906e6af778188ce3780dc Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Mon, 9 Jul 2018 08:56:37 +0900 Subject: [PATCH 041/153] update Julia Commit b6f9244d6b --- codex/NEWS.md | 6 +++--- codex/devdocs/backtraces.md | 2 +- codex/devdocs/callconv.md | 2 +- codex/devdocs/llvm.md | 2 +- codex/devdocs/ssair.md | 4 ++-- codex/manual/calling-c-and-fortran-code.md | 6 +++--- codex/manual/documentation.md | 2 +- codex/manual/faq.md | 2 +- codex/manual/noteworthy-differences.md | 2 +- codex/manual/parallel-computing.md | 2 +- codex/manual/performance-tips.md | 4 ++-- codex/stdlib/Dates.md | 2 +- codex/stdlib/LinearAlgebra.md | 2 +- codex/stdlib/REPL.md | 2 +- codex/stdlib/Random.md | 2 +- codex/stdlib/dates.md | 2 +- codex/stdlib/linearalgebra.md | 2 +- codex/stdlib/random.md | 2 +- src/NEWS.md | 6 +++--- src/devdocs/backtraces.md | 2 +- src/devdocs/callconv.md | 2 +- src/devdocs/llvm.md | 2 +- src/devdocs/ssair.md | 4 ++-- src/manual/calling-c-and-fortran-code.md | 6 +++--- src/manual/documentation.md | 2 +- src/manual/faq.md | 2 +- src/manual/noteworthy-differences.md | 2 +- src/manual/parallel-computing.md | 2 +- src/manual/performance-tips.md | 4 ++-- src/stdlib/Dates.md | 2 +- src/stdlib/LinearAlgebra.md | 2 +- src/stdlib/REPL.md | 2 +- src/stdlib/Random.md | 2 +- src/stdlib/dates.md | 2 +- src/stdlib/linearalgebra.md | 2 +- src/stdlib/random.md | 2 +- 36 files changed, 48 insertions(+), 48 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index e5ea9c0..847d70e 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -652,7 +652,7 @@ Library improvements Therefore custom string types may want to define direct `ncodeunits` methods. * `reverseind(s::AbstractString, i::Integer)` now has an efficient generic fallback, so - custom string types do not need to provide their own efficient defintions. The generic + custom string types do not need to provide their own efficient definitions. The generic definition relies on `ncodeunits` however, so for optimal performance you may need to define a custom method for that function. @@ -693,7 +693,7 @@ Library improvements Use `unique` to get the old behavior. * The `linearindices` function has been deprecated in favor of the new - `LinearIndices` type, which additionnally provides conversion from + `LinearIndices` type, which additionally provides conversion from cartesian indices to linear indices using the normal indexing operation. ([#24715](https://github.com/JuliaLang/julia/issues/24715), [#26775](https://github.com/JuliaLang/julia/issues/26775)). @@ -733,7 +733,7 @@ Compiler/Runtime improvements call. ([#22210](https://github.com/JuliaLang/julia/issues/22210), [#22732](https://github.com/JuliaLang/julia/issues/22732)) * Inference recursion-detection heuristics are now more precise, - allowing them to be triggered less often, but being more agressive when they + allowing them to be triggered less often, but being more aggressive when they are triggered to drive the inference computation to a solution ([#23912](https://github.com/JuliaLang/julia/issues/23912)). * Inference now propagates constants inter-procedurally, and can compute diff --git a/codex/devdocs/backtraces.md b/codex/devdocs/backtraces.md index d6f053f..ca750b7 100644 --- a/codex/devdocs/backtraces.md +++ b/codex/devdocs/backtraces.md @@ -102,7 +102,7 @@ the disk activity of the `julia` process: $ dtruss -f julia ``` -Create a [gist](https://gist.github.com) with the `strace`/ `dtruss` ouput, the [version info](@ref dev-version-info), +Create a [gist](https://gist.github.com) with the `strace`/ `dtruss` output, the [version info](@ref dev-version-info), and any other pertinent information and open a new [issue](https://github.com/JuliaLang/julia/issues?q=is%3Aopen) on Github with a link to the gist. diff --git a/codex/devdocs/callconv.md b/codex/devdocs/callconv.md index 093933a..88158cb 100644 --- a/codex/devdocs/callconv.md +++ b/codex/devdocs/callconv.md @@ -21,7 +21,7 @@ signature. A small return values is returned as LLVM return values. A large return values is returned via the "structure return" (`sret`) convention, where the caller provides a pointer to a return slot. -An argument or return values thta is a homogeneous tuple is sometimes represented as an LLVM vector +An argument or return values that is a homogeneous tuple is sometimes represented as an LLVM vector instead of an LLVM array. ## JL Call Convention diff --git a/codex/devdocs/llvm.md b/codex/devdocs/llvm.md index 3c38533..7b4a731 100644 --- a/codex/devdocs/llvm.md +++ b/codex/devdocs/llvm.md @@ -45,7 +45,7 @@ a file called `Make.user` in the top-level directory and adding a line to it suc LLVM_VER = 3.5.0 ``` -Besides the LLVM release numerals, you can also use `LLVM_VER = svn` to bulid against the latest +Besides the LLVM release numerals, you can also use `LLVM_VER = svn` to build against the latest development version of LLVM. You can also specify to build a debug version of LLVM, by setting either `LLVM_DEBUG = 1` or diff --git a/codex/devdocs/ssair.md b/codex/devdocs/ssair.md index 75231ca..ea37b8b 100644 --- a/codex/devdocs/ssair.md +++ b/codex/devdocs/ssair.md @@ -19,7 +19,7 @@ nodes as well as PhiC nodes and Upsilon nodes (the latter two are only used for ### Phi nodes and Pi nodes -Phi nodes are part of generic SSA abstraction (see the link above if you're not familar with +Phi nodes are part of generic SSA abstraction (see the link above if you're not familiar with the concept). In the Julia IR, these nodes are represented as: ``` struct PhiNode @@ -184,5 +184,5 @@ and return the new index of the node, as well as the node itself. It is legal at as well as make any modifications or deletions to the IR (insertions are disallowed however). The idea behind this arrangement is that, since the optimization passes need to touch the corresponding memory anyway, -and incur the corresponding memory access penalty, performing the extra housekeeping should have comparitively little +and incur the corresponding memory access penalty, performing the extra housekeeping should have comparatively little overhead (and save the overhead of maintaining these data structures during IR modification). diff --git a/codex/manual/calling-c-and-fortran-code.md b/codex/manual/calling-c-and-fortran-code.md index 7eeac82..2077876 100644 --- a/codex/manual/calling-c-and-fortran-code.md +++ b/codex/manual/calling-c-and-fortran-code.md @@ -459,7 +459,7 @@ checks and is only meant to improve readability of the call. !!! warning Fortran compilers *may* also add other hidden arguments for pointers, assumed-shape (`:`) and assumed-size (`*`) arrays. Such behaviour can be avoided by using `ISO_C_BINDING` and - including `bind(c)` in the defintion of the subroutine, which is strongly recommended for + including `bind(c)` in the definition of the subroutine, which is strongly recommended for interoperable code. In this case there will be no hidden arguments, at the cost of some language features (e.g. only `character(len=1)` will be permitted to pass strings). @@ -778,7 +778,7 @@ The input `n` is passed by value, and so the function's input signature is simply declared as `(Csize_t,)` without any `Ref` or `Ptr` necessary. (If the wrapper was calling a Fortran function instead, the corresponding function input signature should instead be `(Ref{Csize_t},)`, since Fortran variables are -passed by pointers.) Furthermore, `n` can be any type that is convertable to a +passed by pointers.) Furthermore, `n` can be any type that is convertible to a `Csize_t` integer; the [`ccall`](@ref) implicitly calls [`Base.cconvert(Csize_t, n)`](@ref). @@ -799,7 +799,7 @@ end Here, the input `p` is declared to be of type `Ref{gsl_permutation}`, meaning that the memory that `p` points to may be managed by Julia or by C. A pointer to memory allocated by C should -be of type `Ptr{gsl_permutation}`, but it is convertable using [`Base.cconvert`](@ref) and therefore +be of type `Ptr{gsl_permutation}`, but it is convertible using [`Base.cconvert`](@ref) and therefore can be used in the same (covariant) context of the input argument to a [`ccall`](@ref). A pointer to memory allocated by Julia must be of type `Ref{gsl_permutation}`, to ensure that the memory address pointed to is valid and that Julia's garbage collector manages the chunk of memory pointed diff --git a/codex/manual/documentation.md b/codex/manual/documentation.md index 20983fd..0eae97d 100644 --- a/codex/manual/documentation.md +++ b/codex/manual/documentation.md @@ -725,7 +725,7 @@ end ```` !!! note - "Fenced" code blocks, as shown in the last example, should be prefered over indented code blocks + "Fenced" code blocks, as shown in the last example, should be preferred over indented code blocks since there is no way to specify what language an indented code block is written in. #### Block quotes diff --git a/codex/manual/faq.md b/codex/manual/faq.md index 25b69d8..6f9e0fe 100644 --- a/codex/manual/faq.md +++ b/codex/manual/faq.md @@ -97,7 +97,7 @@ julia> x Here we created a function `change_array!`, that assigns `5` to the first element of the passed array (bound to `x` at the call site, and bound to `A` within the function). Notice that, after the function call, `x` is still bound to the same array, but the content of that array changed: -the variables `A` and `x` were distinct bindings refering to the same mutable `Array` object. +the variables `A` and `x` were distinct bindings referring to the same mutable `Array` object. ### Can I use `using` or `import` inside a function? diff --git a/codex/manual/noteworthy-differences.md b/codex/manual/noteworthy-differences.md index da423bc..2c61066 100644 --- a/codex/manual/noteworthy-differences.md +++ b/codex/manual/noteworthy-differences.md @@ -293,7 +293,7 @@ For users coming to Julia from R, these are some noteworthy differences: * Julia macros operate on parsed expressions, rather than the text of the program, which allows them to perform sophisticated transformations of Julia code. Macro names start with the `@` character, and have both a function-like syntax, `@mymacro(arg1, arg2, arg3)`, and a statement-like syntax, - `@mymacro arg1 arg2 arg3`. The forms are interchangable; the function-like form is particularly + `@mymacro arg1 arg2 arg3`. The forms are interchangeable; the function-like form is particularly useful if the macro appears within another expression, and is often clearest. The statement-like form is often used to annotate blocks, as in the distributed `for` construct: `@distributed for i in 1:n; #= body =#; end`. Where the end of the macro construct may be unclear, use the function-like form. diff --git a/codex/manual/parallel-computing.md b/codex/manual/parallel-computing.md index a88dd04..320983c 100644 --- a/codex/manual/parallel-computing.md +++ b/codex/manual/parallel-computing.md @@ -646,7 +646,7 @@ julia> data = [i for i in c] Consider a simple example using channels for inter-task communication. We start 4 tasks to process data from a single `jobs` channel. Jobs, identified by an id (`job_id`), are written to the channel. -Each task in this simulation reads a `job_id`, waits for a random amout of time and writes back +Each task in this simulation reads a `job_id`, waits for a random amount of time and writes back a tuple of `job_id` and the simulated time to the results channel. Finally all the `results` are printed out. diff --git a/codex/manual/performance-tips.md b/codex/manual/performance-tips.md index 30dc9ec..c3fbc6f 100644 --- a/codex/manual/performance-tips.md +++ b/codex/manual/performance-tips.md @@ -1491,7 +1491,7 @@ outer scope (or another inner function) modifies `r`. The discussion in the preceding paragraph referred to the "parser", that is, the phase of compilation that takes place when the module containing `abmult` is first loaded, as opposed to the later phase when it is first invoked. The parser does not "know" that -`Int` is a fixed type, or that the statement `r = -r` tranforms an `Int` to another `Int`. +`Int` is a fixed type, or that the statement `r = -r` transforms an `Int` to another `Int`. The magic of type inference takes place in the later phase of compilation. Thus, the parser does not know that `r` has a fixed type (`Int`). @@ -1537,7 +1537,7 @@ The `let` block creates a new variable `r` whose scope is only the inner function. The second technique recovers full language performance in the presence of captured variables. Note that this is a rapidly evolving aspect of the compiler, and it is likely that future releases -will not require this degree of programmer annotation to attain peformance. +will not require this degree of programmer annotation to attain performance. In the mean time, some user-contributed packages like [FastClosures](https://github.com/c42f/FastClosures.jl) automate the insertion of `let` statements as in `abmult3`. diff --git a/codex/stdlib/Dates.md b/codex/stdlib/Dates.md index 0c76284..dc2e7bd 100644 --- a/codex/stdlib/Dates.md +++ b/codex/stdlib/Dates.md @@ -427,7 +427,7 @@ julia> collect(dr) ## Adjuster Functions -As convenient as date-period arithmetics are, often the kinds of calculations needed on dates +As convenient as date-period arithmetic is, often the kinds of calculations needed on dates take on a *calendrical* or *temporal* nature rather than a fixed number of periods. Holidays are a perfect example; most follow rules such as "Memorial Day = Last Monday of May", or "Thanksgiving = 4th Thursday of November". These kinds of temporal expressions deal with rules relative to the diff --git a/codex/stdlib/LinearAlgebra.md b/codex/stdlib/LinearAlgebra.md index 6e7d122..bc32753 100644 --- a/codex/stdlib/LinearAlgebra.md +++ b/codex/stdlib/LinearAlgebra.md @@ -449,7 +449,7 @@ Many BLAS functions accept arguments that determine whether to transpose an argu which triangle of a matrix to reference (`uplo` or `ul`), whether the diagonal of a triangular matrix can be assumed to be all ones (`dA`) or which side of a matrix multiplication -the input argument belongs on (`side`). The possiblities are: +the input argument belongs on (`side`). The possibilities are: #### [Multplication Order](@id stdlib-blas-side) | `side` | Meaning | diff --git a/codex/stdlib/REPL.md b/codex/stdlib/REPL.md index 59494a4..42348a1 100644 --- a/codex/stdlib/REPL.md +++ b/codex/stdlib/REPL.md @@ -461,7 +461,7 @@ You like the following fruits: - peach ``` -## Customization / Configuation +## Customization / Configuration All interface customization is done through the keyword only `TerminalMenus.config()` function. diff --git a/codex/stdlib/Random.md b/codex/stdlib/Random.md index f72488e..54abfc2 100644 --- a/codex/stdlib/Random.md +++ b/codex/stdlib/Random.md @@ -11,7 +11,7 @@ streams of random numbers. Besides `MersenneTwister`, Julia also provides the `R type, which is a wrapper over the OS provided entropy. Most functions related to random generation accept an optional `AbstractRNG` as the first argument, -`rng` , which defaults to the global one if not provided. Morever, some of them accept optionally +`rng` , which defaults to the global one if not provided. Moreover, some of them accept optionally dimension specifications `dims...` (which can be given as a tuple) to generate arrays of random values. diff --git a/codex/stdlib/dates.md b/codex/stdlib/dates.md index 0c76284..dc2e7bd 100644 --- a/codex/stdlib/dates.md +++ b/codex/stdlib/dates.md @@ -427,7 +427,7 @@ julia> collect(dr) ## Adjuster Functions -As convenient as date-period arithmetics are, often the kinds of calculations needed on dates +As convenient as date-period arithmetic is, often the kinds of calculations needed on dates take on a *calendrical* or *temporal* nature rather than a fixed number of periods. Holidays are a perfect example; most follow rules such as "Memorial Day = Last Monday of May", or "Thanksgiving = 4th Thursday of November". These kinds of temporal expressions deal with rules relative to the diff --git a/codex/stdlib/linearalgebra.md b/codex/stdlib/linearalgebra.md index 6e7d122..bc32753 100644 --- a/codex/stdlib/linearalgebra.md +++ b/codex/stdlib/linearalgebra.md @@ -449,7 +449,7 @@ Many BLAS functions accept arguments that determine whether to transpose an argu which triangle of a matrix to reference (`uplo` or `ul`), whether the diagonal of a triangular matrix can be assumed to be all ones (`dA`) or which side of a matrix multiplication -the input argument belongs on (`side`). The possiblities are: +the input argument belongs on (`side`). The possibilities are: #### [Multplication Order](@id stdlib-blas-side) | `side` | Meaning | diff --git a/codex/stdlib/random.md b/codex/stdlib/random.md index f72488e..54abfc2 100644 --- a/codex/stdlib/random.md +++ b/codex/stdlib/random.md @@ -11,7 +11,7 @@ streams of random numbers. Besides `MersenneTwister`, Julia also provides the `R type, which is a wrapper over the OS provided entropy. Most functions related to random generation accept an optional `AbstractRNG` as the first argument, -`rng` , which defaults to the global one if not provided. Morever, some of them accept optionally +`rng` , which defaults to the global one if not provided. Moreover, some of them accept optionally dimension specifications `dims...` (which can be given as a tuple) to generate arrays of random values. diff --git a/src/NEWS.md b/src/NEWS.md index 534a621..dc06803 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -640,7 +640,7 @@ Library improvements Therefore custom string types may want to define direct `ncodeunits` methods. * `reverseind(s::AbstractString, i::Integer)` now has an efficient generic fallback, so - custom string types do not need to provide their own efficient defintions. The generic + custom string types do not need to provide their own efficient definitions. The generic definition relies on `ncodeunits` however, so for optimal performance you may need to define a custom method for that function. @@ -681,7 +681,7 @@ Library improvements Use `unique` to get the old behavior. * The `linearindices` function has been deprecated in favor of the new - `LinearIndices` type, which additionnally provides conversion from + `LinearIndices` type, which additionally provides conversion from cartesian indices to linear indices using the normal indexing operation. ([#24715](https://github.com/JuliaLang/julia/issues/24715), [#26775](https://github.com/JuliaLang/julia/issues/26775)). @@ -721,7 +721,7 @@ Compiler/Runtime improvements call. ([#22210](https://github.com/JuliaLang/julia/issues/22210), [#22732](https://github.com/JuliaLang/julia/issues/22732)) * Inference recursion-detection heuristics are now more precise, - allowing them to be triggered less often, but being more agressive when they + allowing them to be triggered less often, but being more aggressive when they are triggered to drive the inference computation to a solution ([#23912](https://github.com/JuliaLang/julia/issues/23912)). * Inference now propagates constants inter-procedurally, and can compute diff --git a/src/devdocs/backtraces.md b/src/devdocs/backtraces.md index d6f053f..ca750b7 100644 --- a/src/devdocs/backtraces.md +++ b/src/devdocs/backtraces.md @@ -102,7 +102,7 @@ the disk activity of the `julia` process: $ dtruss -f julia ``` -Create a [gist](https://gist.github.com) with the `strace`/ `dtruss` ouput, the [version info](@ref dev-version-info), +Create a [gist](https://gist.github.com) with the `strace`/ `dtruss` output, the [version info](@ref dev-version-info), and any other pertinent information and open a new [issue](https://github.com/JuliaLang/julia/issues?q=is%3Aopen) on Github with a link to the gist. diff --git a/src/devdocs/callconv.md b/src/devdocs/callconv.md index 093933a..88158cb 100644 --- a/src/devdocs/callconv.md +++ b/src/devdocs/callconv.md @@ -21,7 +21,7 @@ signature. A small return values is returned as LLVM return values. A large return values is returned via the "structure return" (`sret`) convention, where the caller provides a pointer to a return slot. -An argument or return values thta is a homogeneous tuple is sometimes represented as an LLVM vector +An argument or return values that is a homogeneous tuple is sometimes represented as an LLVM vector instead of an LLVM array. ## JL Call Convention diff --git a/src/devdocs/llvm.md b/src/devdocs/llvm.md index 3c38533..7b4a731 100644 --- a/src/devdocs/llvm.md +++ b/src/devdocs/llvm.md @@ -45,7 +45,7 @@ a file called `Make.user` in the top-level directory and adding a line to it suc LLVM_VER = 3.5.0 ``` -Besides the LLVM release numerals, you can also use `LLVM_VER = svn` to bulid against the latest +Besides the LLVM release numerals, you can also use `LLVM_VER = svn` to build against the latest development version of LLVM. You can also specify to build a debug version of LLVM, by setting either `LLVM_DEBUG = 1` or diff --git a/src/devdocs/ssair.md b/src/devdocs/ssair.md index 11828ea..253d5ce 100644 --- a/src/devdocs/ssair.md +++ b/src/devdocs/ssair.md @@ -19,7 +19,7 @@ nodes as well as PhiC nodes and Upsilon nodes (the latter two are only used for ### Phi nodes and Pi nodes -Phi nodes are part of generic SSA abstraction (see the link above if you're not familar with +Phi nodes are part of generic SSA abstraction (see the link above if you're not familiar with the concept). In the Julia IR, these nodes are represented as: ``` struct PhiNode @@ -184,5 +184,5 @@ and return the new index of the node, as well as the node itself. It is legal at as well as make any modifications or deletions to the IR (insertions are disallowed however). The idea behind this arrangement is that, since the optimization passes need to touch the corresponding memory anyway, -and incur the corresponding memory access penalty, performing the extra housekeeping should have comparitively little +and incur the corresponding memory access penalty, performing the extra housekeeping should have comparatively little overhead (and save the overhead of maintaining these data structures during IR modification). diff --git a/src/manual/calling-c-and-fortran-code.md b/src/manual/calling-c-and-fortran-code.md index 7eeac82..2077876 100644 --- a/src/manual/calling-c-and-fortran-code.md +++ b/src/manual/calling-c-and-fortran-code.md @@ -459,7 +459,7 @@ checks and is only meant to improve readability of the call. !!! warning Fortran compilers *may* also add other hidden arguments for pointers, assumed-shape (`:`) and assumed-size (`*`) arrays. Such behaviour can be avoided by using `ISO_C_BINDING` and - including `bind(c)` in the defintion of the subroutine, which is strongly recommended for + including `bind(c)` in the definition of the subroutine, which is strongly recommended for interoperable code. In this case there will be no hidden arguments, at the cost of some language features (e.g. only `character(len=1)` will be permitted to pass strings). @@ -778,7 +778,7 @@ The input `n` is passed by value, and so the function's input signature is simply declared as `(Csize_t,)` without any `Ref` or `Ptr` necessary. (If the wrapper was calling a Fortran function instead, the corresponding function input signature should instead be `(Ref{Csize_t},)`, since Fortran variables are -passed by pointers.) Furthermore, `n` can be any type that is convertable to a +passed by pointers.) Furthermore, `n` can be any type that is convertible to a `Csize_t` integer; the [`ccall`](@ref) implicitly calls [`Base.cconvert(Csize_t, n)`](@ref). @@ -799,7 +799,7 @@ end Here, the input `p` is declared to be of type `Ref{gsl_permutation}`, meaning that the memory that `p` points to may be managed by Julia or by C. A pointer to memory allocated by C should -be of type `Ptr{gsl_permutation}`, but it is convertable using [`Base.cconvert`](@ref) and therefore +be of type `Ptr{gsl_permutation}`, but it is convertible using [`Base.cconvert`](@ref) and therefore can be used in the same (covariant) context of the input argument to a [`ccall`](@ref). A pointer to memory allocated by Julia must be of type `Ref{gsl_permutation}`, to ensure that the memory address pointed to is valid and that Julia's garbage collector manages the chunk of memory pointed diff --git a/src/manual/documentation.md b/src/manual/documentation.md index 20983fd..0eae97d 100644 --- a/src/manual/documentation.md +++ b/src/manual/documentation.md @@ -725,7 +725,7 @@ end ```` !!! note - "Fenced" code blocks, as shown in the last example, should be prefered over indented code blocks + "Fenced" code blocks, as shown in the last example, should be preferred over indented code blocks since there is no way to specify what language an indented code block is written in. #### Block quotes diff --git a/src/manual/faq.md b/src/manual/faq.md index 25b69d8..6f9e0fe 100644 --- a/src/manual/faq.md +++ b/src/manual/faq.md @@ -97,7 +97,7 @@ julia> x Here we created a function `change_array!`, that assigns `5` to the first element of the passed array (bound to `x` at the call site, and bound to `A` within the function). Notice that, after the function call, `x` is still bound to the same array, but the content of that array changed: -the variables `A` and `x` were distinct bindings refering to the same mutable `Array` object. +the variables `A` and `x` were distinct bindings referring to the same mutable `Array` object. ### Can I use `using` or `import` inside a function? diff --git a/src/manual/noteworthy-differences.md b/src/manual/noteworthy-differences.md index da423bc..2c61066 100644 --- a/src/manual/noteworthy-differences.md +++ b/src/manual/noteworthy-differences.md @@ -293,7 +293,7 @@ For users coming to Julia from R, these are some noteworthy differences: * Julia macros operate on parsed expressions, rather than the text of the program, which allows them to perform sophisticated transformations of Julia code. Macro names start with the `@` character, and have both a function-like syntax, `@mymacro(arg1, arg2, arg3)`, and a statement-like syntax, - `@mymacro arg1 arg2 arg3`. The forms are interchangable; the function-like form is particularly + `@mymacro arg1 arg2 arg3`. The forms are interchangeable; the function-like form is particularly useful if the macro appears within another expression, and is often clearest. The statement-like form is often used to annotate blocks, as in the distributed `for` construct: `@distributed for i in 1:n; #= body =#; end`. Where the end of the macro construct may be unclear, use the function-like form. diff --git a/src/manual/parallel-computing.md b/src/manual/parallel-computing.md index a88dd04..320983c 100644 --- a/src/manual/parallel-computing.md +++ b/src/manual/parallel-computing.md @@ -646,7 +646,7 @@ julia> data = [i for i in c] Consider a simple example using channels for inter-task communication. We start 4 tasks to process data from a single `jobs` channel. Jobs, identified by an id (`job_id`), are written to the channel. -Each task in this simulation reads a `job_id`, waits for a random amout of time and writes back +Each task in this simulation reads a `job_id`, waits for a random amount of time and writes back a tuple of `job_id` and the simulated time to the results channel. Finally all the `results` are printed out. diff --git a/src/manual/performance-tips.md b/src/manual/performance-tips.md index 30dc9ec..c3fbc6f 100644 --- a/src/manual/performance-tips.md +++ b/src/manual/performance-tips.md @@ -1491,7 +1491,7 @@ outer scope (or another inner function) modifies `r`. The discussion in the preceding paragraph referred to the "parser", that is, the phase of compilation that takes place when the module containing `abmult` is first loaded, as opposed to the later phase when it is first invoked. The parser does not "know" that -`Int` is a fixed type, or that the statement `r = -r` tranforms an `Int` to another `Int`. +`Int` is a fixed type, or that the statement `r = -r` transforms an `Int` to another `Int`. The magic of type inference takes place in the later phase of compilation. Thus, the parser does not know that `r` has a fixed type (`Int`). @@ -1537,7 +1537,7 @@ The `let` block creates a new variable `r` whose scope is only the inner function. The second technique recovers full language performance in the presence of captured variables. Note that this is a rapidly evolving aspect of the compiler, and it is likely that future releases -will not require this degree of programmer annotation to attain peformance. +will not require this degree of programmer annotation to attain performance. In the mean time, some user-contributed packages like [FastClosures](https://github.com/c42f/FastClosures.jl) automate the insertion of `let` statements as in `abmult3`. diff --git a/src/stdlib/Dates.md b/src/stdlib/Dates.md index 0c76284..dc2e7bd 100644 --- a/src/stdlib/Dates.md +++ b/src/stdlib/Dates.md @@ -427,7 +427,7 @@ julia> collect(dr) ## Adjuster Functions -As convenient as date-period arithmetics are, often the kinds of calculations needed on dates +As convenient as date-period arithmetic is, often the kinds of calculations needed on dates take on a *calendrical* or *temporal* nature rather than a fixed number of periods. Holidays are a perfect example; most follow rules such as "Memorial Day = Last Monday of May", or "Thanksgiving = 4th Thursday of November". These kinds of temporal expressions deal with rules relative to the diff --git a/src/stdlib/LinearAlgebra.md b/src/stdlib/LinearAlgebra.md index 6e7d122..bc32753 100644 --- a/src/stdlib/LinearAlgebra.md +++ b/src/stdlib/LinearAlgebra.md @@ -449,7 +449,7 @@ Many BLAS functions accept arguments that determine whether to transpose an argu which triangle of a matrix to reference (`uplo` or `ul`), whether the diagonal of a triangular matrix can be assumed to be all ones (`dA`) or which side of a matrix multiplication -the input argument belongs on (`side`). The possiblities are: +the input argument belongs on (`side`). The possibilities are: #### [Multplication Order](@id stdlib-blas-side) | `side` | Meaning | diff --git a/src/stdlib/REPL.md b/src/stdlib/REPL.md index 59494a4..42348a1 100644 --- a/src/stdlib/REPL.md +++ b/src/stdlib/REPL.md @@ -461,7 +461,7 @@ You like the following fruits: - peach ``` -## Customization / Configuation +## Customization / Configuration All interface customization is done through the keyword only `TerminalMenus.config()` function. diff --git a/src/stdlib/Random.md b/src/stdlib/Random.md index f72488e..54abfc2 100644 --- a/src/stdlib/Random.md +++ b/src/stdlib/Random.md @@ -11,7 +11,7 @@ streams of random numbers. Besides `MersenneTwister`, Julia also provides the `R type, which is a wrapper over the OS provided entropy. Most functions related to random generation accept an optional `AbstractRNG` as the first argument, -`rng` , which defaults to the global one if not provided. Morever, some of them accept optionally +`rng` , which defaults to the global one if not provided. Moreover, some of them accept optionally dimension specifications `dims...` (which can be given as a tuple) to generate arrays of random values. diff --git a/src/stdlib/dates.md b/src/stdlib/dates.md index 0c76284..dc2e7bd 100644 --- a/src/stdlib/dates.md +++ b/src/stdlib/dates.md @@ -427,7 +427,7 @@ julia> collect(dr) ## Adjuster Functions -As convenient as date-period arithmetics are, often the kinds of calculations needed on dates +As convenient as date-period arithmetic is, often the kinds of calculations needed on dates take on a *calendrical* or *temporal* nature rather than a fixed number of periods. Holidays are a perfect example; most follow rules such as "Memorial Day = Last Monday of May", or "Thanksgiving = 4th Thursday of November". These kinds of temporal expressions deal with rules relative to the diff --git a/src/stdlib/linearalgebra.md b/src/stdlib/linearalgebra.md index 6e7d122..bc32753 100644 --- a/src/stdlib/linearalgebra.md +++ b/src/stdlib/linearalgebra.md @@ -449,7 +449,7 @@ Many BLAS functions accept arguments that determine whether to transpose an argu which triangle of a matrix to reference (`uplo` or `ul`), whether the diagonal of a triangular matrix can be assumed to be all ones (`dA`) or which side of a matrix multiplication -the input argument belongs on (`side`). The possiblities are: +the input argument belongs on (`side`). The possibilities are: #### [Multplication Order](@id stdlib-blas-side) | `side` | Meaning | diff --git a/src/stdlib/random.md b/src/stdlib/random.md index f72488e..54abfc2 100644 --- a/src/stdlib/random.md +++ b/src/stdlib/random.md @@ -11,7 +11,7 @@ streams of random numbers. Besides `MersenneTwister`, Julia also provides the `R type, which is a wrapper over the OS provided entropy. Most functions related to random generation accept an optional `AbstractRNG` as the first argument, -`rng` , which defaults to the global one if not provided. Morever, some of them accept optionally +`rng` , which defaults to the global one if not provided. Moreover, some of them accept optionally dimension specifications `dims...` (which can be given as a tuple) to generate arrays of random values. From 59d732ce7739318d81ef40184d2e92e46baee4ae Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Mon, 9 Jul 2018 12:54:01 +0900 Subject: [PATCH 042/153] delete stdlib lowercased files --- codex/stdlib/base64.md | 17 - codex/stdlib/crc32c.md | 6 - codex/stdlib/dates.md | 820 --------------------------------- codex/stdlib/delimitedfiles.md | 19 - codex/stdlib/distributed.md | 77 ---- codex/stdlib/filewatching.md | 9 - codex/stdlib/libdl.md | 13 - codex/stdlib/linearalgebra.md | 625 ------------------------- codex/stdlib/mmap.md | 15 - codex/stdlib/printf.md | 14 - codex/stdlib/profile.md | 17 - codex/stdlib/random.md | 50 -- codex/stdlib/serialization.md | 7 - codex/stdlib/sharedarrays.md | 9 - codex/stdlib/sparsearrays.md | 228 --------- codex/stdlib/test.md | 269 ----------- codex/stdlib/unicode.md | 15 - src/devdocs/object.md | 2 +- src/stdlib/base64.md | 17 - src/stdlib/crc32c.md | 6 - src/stdlib/dates.md | 820 --------------------------------- src/stdlib/delimitedfiles.md | 19 - src/stdlib/distributed.md | 77 ---- src/stdlib/filewatching.md | 9 - src/stdlib/libdl.md | 13 - src/stdlib/linearalgebra.md | 625 ------------------------- src/stdlib/mmap.md | 15 - src/stdlib/printf.md | 14 - src/stdlib/profile.md | 17 - src/stdlib/random.md | 50 -- src/stdlib/serialization.md | 7 - src/stdlib/sharedarrays.md | 9 - src/stdlib/sparsearrays.md | 228 --------- src/stdlib/test.md | 269 ----------- src/stdlib/unicode.md | 15 - 35 files changed, 1 insertion(+), 4421 deletions(-) delete mode 100644 codex/stdlib/base64.md delete mode 100644 codex/stdlib/crc32c.md delete mode 100644 codex/stdlib/dates.md delete mode 100644 codex/stdlib/delimitedfiles.md delete mode 100644 codex/stdlib/distributed.md delete mode 100644 codex/stdlib/filewatching.md delete mode 100644 codex/stdlib/libdl.md delete mode 100644 codex/stdlib/linearalgebra.md delete mode 100644 codex/stdlib/mmap.md delete mode 100644 codex/stdlib/printf.md delete mode 100644 codex/stdlib/profile.md delete mode 100644 codex/stdlib/random.md delete mode 100644 codex/stdlib/serialization.md delete mode 100644 codex/stdlib/sharedarrays.md delete mode 100644 codex/stdlib/sparsearrays.md delete mode 100644 codex/stdlib/test.md delete mode 100644 codex/stdlib/unicode.md delete mode 100644 src/stdlib/base64.md delete mode 100644 src/stdlib/crc32c.md delete mode 100644 src/stdlib/dates.md delete mode 100644 src/stdlib/delimitedfiles.md delete mode 100644 src/stdlib/distributed.md delete mode 100644 src/stdlib/filewatching.md delete mode 100644 src/stdlib/libdl.md delete mode 100644 src/stdlib/linearalgebra.md delete mode 100644 src/stdlib/mmap.md delete mode 100644 src/stdlib/printf.md delete mode 100644 src/stdlib/profile.md delete mode 100644 src/stdlib/random.md delete mode 100644 src/stdlib/serialization.md delete mode 100644 src/stdlib/sharedarrays.md delete mode 100644 src/stdlib/sparsearrays.md delete mode 100644 src/stdlib/test.md delete mode 100644 src/stdlib/unicode.md diff --git a/codex/stdlib/base64.md b/codex/stdlib/base64.md deleted file mode 100644 index b179de0..0000000 --- a/codex/stdlib/base64.md +++ /dev/null @@ -1,17 +0,0 @@ -# Base64 - -```@meta -DocTestSetup = :(using Base64) -``` - -```@docs -Base64.Base64EncodePipe -Base64.base64encode -Base64.Base64DecodePipe -Base64.base64decode -Base64.stringmime -``` - -```@meta -DocTestSetup = nothing -``` diff --git a/codex/stdlib/crc32c.md b/codex/stdlib/crc32c.md deleted file mode 100644 index 1304709..0000000 --- a/codex/stdlib/crc32c.md +++ /dev/null @@ -1,6 +0,0 @@ -# CRC32c - -```@docs -CRC32c.crc32c -CRC32c.crc32c(::IO, ::Integer, ::UInt32) -``` diff --git a/codex/stdlib/dates.md b/codex/stdlib/dates.md deleted file mode 100644 index dc2e7bd..0000000 --- a/codex/stdlib/dates.md +++ /dev/null @@ -1,820 +0,0 @@ -# Dates - -```@meta -DocTestSetup = :(using Dates) -``` - -The `Dates` module provides two types for working with dates: [`Date`](@ref) and [`DateTime`](@ref), -representing day and millisecond precision, respectively; both are subtypes of the abstract [`TimeType`](@ref). -The motivation for distinct types is simple: some operations are much simpler, both in terms of -code and mental reasoning, when the complexities of greater precision don't have to be dealt with. -For example, since the [`Date`](@ref) type only resolves to the precision of a single date (i.e. -no hours, minutes, or seconds), normal considerations for time zones, daylight savings/summer -time, and leap seconds are unnecessary and avoided. - -Both [`Date`](@ref) and [`DateTime`](@ref) are basically immutable [`Int64`](@ref) wrappers. -The single `instant` field of either type is actually a `UTInstant{P}` type, which -represents a continuously increasing machine timeline based on the UT second [^1]. The -[`DateTime`](@ref) type is not aware of time zones (*naive*, in Python parlance), -analogous to a *LocalDateTime* in Java 8. Additional time zone functionality -can be added through the [TimeZones.jl package](https://github.com/JuliaTime/TimeZones.jl/), which -compiles the [IANA time zone database](http://www.iana.org/time-zones). Both [`Date`](@ref) and -[`DateTime`](@ref) are based on the [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) standard, which follows the proleptic Gregorian calendar. -One note is that the ISO 8601 standard is particular about BC/BCE dates. In general, the last -day of the BC/BCE era, 1-12-31 BC/BCE, was followed by 1-1-1 AD/CE, thus no year zero exists. -The ISO standard, however, states that 1 BC/BCE is year zero, so `0000-12-31` is the day before -`0001-01-01`, and year `-0001` (yes, negative one for the year) is 2 BC/BCE, year `-0002` is 3 -BC/BCE, etc. - -[^1]: - The notion of the UT second is actually quite fundamental. There are basically two different notions - of time generally accepted, one based on the physical rotation of the earth (one full rotation - = 1 day), the other based on the SI second (a fixed, constant value). These are radically different! - Think about it, a "UT second", as defined relative to the rotation of the earth, may have a different - absolute length depending on the day! Anyway, the fact that [`Date`](@ref) and [`DateTime`](@ref) - are based on UT seconds is a simplifying, yet honest assumption so that things like leap seconds - and all their complexity can be avoided. This basis of time is formally called [UT](https://en.wikipedia.org/wiki/Universal_Time) - or UT1. Basing types on the UT second basically means that every minute has 60 seconds and every - day has 24 hours and leads to more natural calculations when working with calendar dates. - -## Constructors - -[`Date`](@ref) and [`DateTime`](@ref) types can be constructed by integer or [`Period`](@ref) -types, by parsing, or through adjusters (more on those later): - -```jldoctest -julia> DateTime(2013) -2013-01-01T00:00:00 - -julia> DateTime(2013,7) -2013-07-01T00:00:00 - -julia> DateTime(2013,7,1) -2013-07-01T00:00:00 - -julia> DateTime(2013,7,1,12) -2013-07-01T12:00:00 - -julia> DateTime(2013,7,1,12,30) -2013-07-01T12:30:00 - -julia> DateTime(2013,7,1,12,30,59) -2013-07-01T12:30:59 - -julia> DateTime(2013,7,1,12,30,59,1) -2013-07-01T12:30:59.001 - -julia> Date(2013) -2013-01-01 - -julia> Date(2013,7) -2013-07-01 - -julia> Date(2013,7,1) -2013-07-01 - -julia> Date(Dates.Year(2013),Dates.Month(7),Dates.Day(1)) -2013-07-01 - -julia> Date(Dates.Month(7),Dates.Year(2013)) -2013-07-01 -``` - -[`Date`](@ref) or [`DateTime`](@ref) parsing is accomplished by the use of format strings. Format -strings work by the notion of defining *delimited* or *fixed-width* "slots" that contain a period -to parse and passing the text to parse and format string to a [`Date`](@ref) or [`DateTime`](@ref) -constructor, of the form `Date("2015-01-01","y-m-d")` or `DateTime("20150101","yyyymmdd")`. - -Delimited slots are marked by specifying the delimiter the parser should expect between two subsequent -periods; so `"y-m-d"` lets the parser know that between the first and second slots in a date string -like `"2014-07-16"`, it should find the `-` character. The `y`, `m`, and `d` characters let the -parser know which periods to parse in each slot. - -Fixed-width slots are specified by repeating the period character the number of times corresponding -to the width with no delimiter between characters. So `"yyyymmdd"` would correspond to a date -string like `"20140716"`. The parser distinguishes a fixed-width slot by the absence of a delimiter, -noting the transition `"yyyymm"` from one period character to the next. - -Support for text-form month parsing is also supported through the `u` and `U` characters, for -abbreviated and full-length month names, respectively. By default, only English month names are -supported, so `u` corresponds to "Jan", "Feb", "Mar", etc. And `U` corresponds to "January", "February", -"March", etc. Similar to other name=>value mapping functions [`dayname`](@ref) and [`monthname`](@ref), -custom locales can be loaded by passing in the `locale=>Dict{String,Int}` mapping to the `MONTHTOVALUEABBR` -and `MONTHTOVALUE` dicts for abbreviated and full-name month names, respectively. - -One note on parsing performance: using the `Date(date_string,format_string)` function is fine -if only called a few times. If there are many similarly formatted date strings to parse however, -it is much more efficient to first create a [`Dates.DateFormat`](@ref), and pass it instead of -a raw format string. - -```jldoctest -julia> df = DateFormat("y-m-d"); - -julia> dt = Date("2015-01-01",df) -2015-01-01 - -julia> dt2 = Date("2015-01-02",df) -2015-01-02 -``` - -You can also use the `dateformat""` string macro. This macro creates the `DateFormat` object once when the macro is expanded and uses the same `DateFormat` object even if a code snippet is run multiple times. - -```jldoctest -julia> for i = 1:10^5 - Date("2015-01-01", dateformat"y-m-d") - end -``` - -A full suite of parsing and formatting tests and examples is available in [`stdlib/Dates/test/io.jl`](https://github.com/JuliaLang/julia/blob/master/stdlib/Dates/test/io.jl). - -## Durations/Comparisons - -Finding the length of time between two [`Date`](@ref) or [`DateTime`](@ref) is straightforward -given their underlying representation as `UTInstant{Day}` and `UTInstant{Millisecond}`, respectively. -The difference between [`Date`](@ref) is returned in the number of [`Day`](@ref), and [`DateTime`](@ref) -in the number of [`Millisecond`](@ref). Similarly, comparing [`TimeType`](@ref) is a simple matter -of comparing the underlying machine instants (which in turn compares the internal [`Int64`](@ref) values). - -```jldoctest -julia> dt = Date(2012,2,29) -2012-02-29 - -julia> dt2 = Date(2000,2,1) -2000-02-01 - -julia> dump(dt) -Date - instant: Dates.UTInstant{Day} - periods: Day - value: Int64 734562 - -julia> dump(dt2) -Date - instant: Dates.UTInstant{Day} - periods: Day - value: Int64 730151 - -julia> dt > dt2 -true - -julia> dt != dt2 -true - -julia> dt + dt2 -ERROR: MethodError: no method matching +(::Date, ::Date) -[...] - -julia> dt * dt2 -ERROR: MethodError: no method matching *(::Date, ::Date) -[...] - -julia> dt / dt2 -ERROR: MethodError: no method matching /(::Date, ::Date) - -julia> dt - dt2 -4411 days - -julia> dt2 - dt --4411 days - -julia> dt = DateTime(2012,2,29) -2012-02-29T00:00:00 - -julia> dt2 = DateTime(2000,2,1) -2000-02-01T00:00:00 - -julia> dt - dt2 -381110400000 milliseconds -``` - -## Accessor Functions - -Because the [`Date`](@ref) and [`DateTime`](@ref) types are stored as single [`Int64`](@ref) values, date -parts or fields can be retrieved through accessor functions. The lowercase accessors return the -field as an integer: - -```jldoctest tdate -julia> t = Date(2014, 1, 31) -2014-01-31 - -julia> Dates.year(t) -2014 - -julia> Dates.month(t) -1 - -julia> Dates.week(t) -5 - -julia> Dates.day(t) -31 -``` - -While propercase return the same value in the corresponding [`Period`](@ref) type: - -```jldoctest tdate -julia> Dates.Year(t) -2014 years - -julia> Dates.Day(t) -31 days -``` - -Compound methods are provided, as they provide a measure of efficiency if multiple fields are -needed at the same time: - -```jldoctest tdate -julia> Dates.yearmonth(t) -(2014, 1) - -julia> Dates.monthday(t) -(1, 31) - -julia> Dates.yearmonthday(t) -(2014, 1, 31) -``` - -One may also access the underlying `UTInstant` or integer value: - -```jldoctest tdate -julia> dump(t) -Date - instant: Dates.UTInstant{Day} - periods: Day - value: Int64 735264 - -julia> t.instant -Dates.UTInstant{Day}(735264 days) - -julia> Dates.value(t) -735264 -``` - -## Query Functions - -Query functions provide calendrical information about a [`TimeType`](@ref). They include information -about the day of the week: - -```jldoctest tdate2 -julia> t = Date(2014, 1, 31) -2014-01-31 - -julia> Dates.dayofweek(t) -5 - -julia> Dates.dayname(t) -"Friday" - -julia> Dates.dayofweekofmonth(t) # 5th Friday of January -5 -``` - -Month of the year: - -```jldoctest tdate2 -julia> Dates.monthname(t) -"January" - -julia> Dates.daysinmonth(t) -31 -``` - -As well as information about the [`TimeType`](@ref)'s year and quarter: - -```jldoctest tdate2 -julia> Dates.isleapyear(t) -false - -julia> Dates.dayofyear(t) -31 - -julia> Dates.quarterofyear(t) -1 - -julia> Dates.dayofquarter(t) -31 -``` - -The [`dayname`](@ref) and [`monthname`](@ref) methods can also take an optional `locale` keyword -that can be used to return the name of the day or month of the year for other languages/locales. -There are also versions of these functions returning the abbreviated names, namely -[`dayabbr`](@ref) and [`monthabbr`](@ref). -First the mapping is loaded into the `LOCALES` variable: - -```jldoctest tdate2 -julia> french_months = ["janvier", "février", "mars", "avril", "mai", "juin", - "juillet", "août", "septembre", "octobre", "novembre", "décembre"]; - -julia> french_monts_abbrev = ["janv","févr","mars","avril","mai","juin", - "juil","août","sept","oct","nov","déc"]; - -julia> french_days = ["lundi","mardi","mercredi","jeudi","vendredi","samedi","dimanche"]; - -julia> Dates.LOCALES["french"] = Dates.DateLocale(french_months, french_monts_abbrev, french_days, [""]); -``` - - The above mentioned functions can then be used to perform the queries: - -```jldoctest tdate2 -julia> Dates.dayname(t;locale="french") -"vendredi" - -julia> Dates.monthname(t;locale="french") -"janvier" - -julia> Dates.monthabbr(t;locale="french") -"janv" -``` - -Since the abbreviated versions of the days are not loaded, trying to use the -function `dayabbr` will error. - -```jldoctest tdate2 -julia> Dates.dayabbr(t;locale="french") -ERROR: BoundsError: attempt to access 1-element Array{String,1} at index [5] -Stacktrace: -[...] -``` - - -## TimeType-Period Arithmetic - -It's good practice when using any language/date framework to be familiar with how date-period -arithmetic is handled as there are some [tricky issues](https://codeblog.jonskeet.uk/2010/12/01/the-joys-of-date-time-arithmetic/) -to deal with (though much less so for day-precision types). - -The `Dates` module approach tries to follow the simple principle of trying to change as -little as possible when doing [`Period`](@ref) arithmetic. This approach is also often known as -*calendrical* arithmetic or what you would probably guess if someone were to ask you the same -calculation in a conversation. Why all the fuss about this? Let's take a classic example: add -1 month to January 31st, 2014. What's the answer? Javascript will say [March 3](http://www.markhneedham.com/blog/2009/01/07/javascript-add-a-month-to-a-date/) -(assumes 31 days). PHP says [March 2](https://stackoverflow.com/questions/5760262/php-adding-months-to-a-date-while-not-exceeding-the-last-day-of-the-month) -(assumes 30 days). The fact is, there is no right answer. In the `Dates` module, it gives -the result of February 28th. How does it figure that out? I like to think of the classic 7-7-7 -gambling game in casinos. - -Now just imagine that instead of 7-7-7, the slots are Year-Month-Day, or in our example, 2014-01-31. -When you ask to add 1 month to this date, the month slot is incremented, so now we have 2014-02-31. -Then the day number is checked if it is greater than the last valid day of the new month; if it -is (as in the case above), the day number is adjusted down to the last valid day (28). What are -the ramifications with this approach? Go ahead and add another month to our date, `2014-02-28 + Month(1) == 2014-03-28`. -What? Were you expecting the last day of March? Nope, sorry, remember the 7-7-7 slots. As few -slots as possible are going to change, so we first increment the month slot by 1, 2014-03-28, -and boom, we're done because that's a valid date. On the other hand, if we were to add 2 months -to our original date, 2014-01-31, then we end up with 2014-03-31, as expected. The other ramification -of this approach is a loss in associativity when a specific ordering is forced (i.e. adding things -in different orders results in different outcomes). For example: - -```jldoctest -julia> (Date(2014,1,29)+Dates.Day(1)) + Dates.Month(1) -2014-02-28 - -julia> (Date(2014,1,29)+Dates.Month(1)) + Dates.Day(1) -2014-03-01 -``` - -What's going on there? In the first line, we're adding 1 day to January 29th, which results in -2014-01-30; then we add 1 month, so we get 2014-02-30, which then adjusts down to 2014-02-28. -In the second example, we add 1 month *first*, where we get 2014-02-29, which adjusts down to -2014-02-28, and *then* add 1 day, which results in 2014-03-01. One design principle that helps -in this case is that, in the presence of multiple Periods, the operations will be ordered by the -Periods' *types*, not their value or positional order; this means `Year` will always be added -first, then `Month`, then `Week`, etc. Hence the following *does* result in associativity and -Just Works: - -```jldoctest -julia> Date(2014,1,29) + Dates.Day(1) + Dates.Month(1) -2014-03-01 - -julia> Date(2014,1,29) + Dates.Month(1) + Dates.Day(1) -2014-03-01 -``` - -Tricky? Perhaps. What is an innocent `Dates` user to do? The bottom line is to be aware -that explicitly forcing a certain associativity, when dealing with months, may lead to some unexpected -results, but otherwise, everything should work as expected. Thankfully, that's pretty much the -extent of the odd cases in date-period arithmetic when dealing with time in UT (avoiding the "joys" -of dealing with daylight savings, leap seconds, etc.). - -As a bonus, all period arithmetic objects work directly with ranges: - -```jldoctest -julia> dr = Date(2014,1,29):Day(1):Date(2014,2,3) -2014-01-29:1 day:2014-02-03 - -julia> collect(dr) -6-element Array{Date,1}: - 2014-01-29 - 2014-01-30 - 2014-01-31 - 2014-02-01 - 2014-02-02 - 2014-02-03 - -julia> dr = Date(2014,1,29):Dates.Month(1):Date(2014,07,29) -2014-01-29:1 month:2014-07-29 - -julia> collect(dr) -7-element Array{Date,1}: - 2014-01-29 - 2014-02-28 - 2014-03-29 - 2014-04-29 - 2014-05-29 - 2014-06-29 - 2014-07-29 -``` - -## Adjuster Functions - -As convenient as date-period arithmetic is, often the kinds of calculations needed on dates -take on a *calendrical* or *temporal* nature rather than a fixed number of periods. Holidays are -a perfect example; most follow rules such as "Memorial Day = Last Monday of May", or "Thanksgiving -= 4th Thursday of November". These kinds of temporal expressions deal with rules relative to the -calendar, like first or last of the month, next Tuesday, or the first and third Wednesdays, etc. - -The `Dates` module provides the *adjuster* API through several convenient methods that -aid in simply and succinctly expressing temporal rules. The first group of adjuster methods deal -with the first and last of weeks, months, quarters, and years. They each take a single [`TimeType`](@ref) -as input and return or *adjust to* the first or last of the desired period relative to the input. - -```jldoctest -julia> Dates.firstdayofweek(Date(2014,7,16)) # Adjusts the input to the Monday of the input's week -2014-07-14 - -julia> Dates.lastdayofmonth(Date(2014,7,16)) # Adjusts to the last day of the input's month -2014-07-31 - -julia> Dates.lastdayofquarter(Date(2014,7,16)) # Adjusts to the last day of the input's quarter -2014-09-30 -``` - -The next two higher-order methods, [`tonext`](@ref), and [`toprev`](@ref), generalize working -with temporal expressions by taking a `DateFunction` as first argument, along with a starting -[`TimeType`](@ref). A `DateFunction` is just a function, usually anonymous, that takes a single -[`TimeType`](@ref) as input and returns a [`Bool`](@ref), `true` indicating a satisfied -adjustment criterion. -For example: - -```jldoctest -julia> istuesday = x->Dates.dayofweek(x) == Dates.Tuesday; # Returns true if the day of the week of x is Tuesday - -julia> Dates.tonext(istuesday, Date(2014,7,13)) # 2014-07-13 is a Sunday -2014-07-15 - -julia> Dates.tonext(Date(2014,7,13), Dates.Tuesday) # Convenience method provided for day of the week adjustments -2014-07-15 -``` - -This is useful with the do-block syntax for more complex temporal expressions: - -```jldoctest -julia> Dates.tonext(Date(2014,7,13)) do x - # Return true on the 4th Thursday of November (Thanksgiving) - Dates.dayofweek(x) == Dates.Thursday && - Dates.dayofweekofmonth(x) == 4 && - Dates.month(x) == Dates.November - end -2014-11-27 -``` - -The [`Base.filter`](@ref) method can be used to obtain all valid dates/moments in a specified -range: - -```jldoctest -# Pittsburgh street cleaning; Every 2nd Tuesday from April to November -# Date range from January 1st, 2014 to January 1st, 2015 -julia> dr = Dates.Date(2014):Day(1):Dates.Date(2015); - -julia> filter(dr) do x - Dates.dayofweek(x) == Dates.Tue && - Dates.April <= Dates.month(x) <= Dates.Nov && - Dates.dayofweekofmonth(x) == 2 - end -8-element Array{Date,1}: - 2014-04-08 - 2014-05-13 - 2014-06-10 - 2014-07-08 - 2014-08-12 - 2014-09-09 - 2014-10-14 - 2014-11-11 -``` - -Additional examples and tests are available in [`stdlib/Dates/test/adjusters.jl`](https://github.com/JuliaLang/julia/blob/master/stdlib/Dates/test/adjusters.jl). - -## Period Types - -Periods are a human view of discrete, sometimes irregular durations of time. Consider 1 month; -it could represent, in days, a value of 28, 29, 30, or 31 depending on the year and month context. -Or a year could represent 365 or 366 days in the case of a leap year. [`Period`](@ref) types are -simple [`Int64`](@ref) wrappers and are constructed by wrapping any `Int64` convertible type, i.e. `Year(1)` -or `Month(3.0)`. Arithmetic between [`Period`](@ref) of the same type behave like integers, and -limited `Period-Real` arithmetic is available. - -```jldoctest -julia> y1 = Dates.Year(1) -1 year - -julia> y2 = Dates.Year(2) -2 years - -julia> y3 = Dates.Year(10) -10 years - -julia> y1 + y2 -3 years - -julia> div(y3,y2) -5 - -julia> y3 - y2 -8 years - -julia> y3 % y2 -0 years - -julia> div(y3,3) # mirrors integer division -3 years -``` - -## Rounding - -[`Date`](@ref) and [`DateTime`](@ref) values can be rounded to a specified resolution (e.g., 1 -month or 15 minutes) with [`floor`](@ref), [`ceil`](@ref), or [`round`](@ref): - -```jldoctest -julia> floor(Date(1985, 8, 16), Dates.Month) -1985-08-01 - -julia> ceil(DateTime(2013, 2, 13, 0, 31, 20), Dates.Minute(15)) -2013-02-13T00:45:00 - -julia> round(DateTime(2016, 8, 6, 20, 15), Dates.Day) -2016-08-07T00:00:00 -``` - -Unlike the numeric [`round`](@ref) method, which breaks ties toward the even number by default, -the [`TimeType`](@ref)[`round`](@ref) method uses the `RoundNearestTiesUp` rounding mode. (It's -difficult to guess what breaking ties to nearest "even" [`TimeType`](@ref) would entail.) Further -details on the available `RoundingMode` s can be found in the [API reference](@ref stdlib-dates-api). - -Rounding should generally behave as expected, but there are a few cases in which the expected -behaviour is not obvious. - -### Rounding Epoch - -In many cases, the resolution specified for rounding (e.g., `Dates.Second(30)`) divides evenly -into the next largest period (in this case, `Dates.Minute(1)`). But rounding behaviour in cases -in which this is not true may lead to confusion. What is the expected result of rounding a [`DateTime`](@ref) -to the nearest 10 hours? - -```jldoctest -julia> round(DateTime(2016, 7, 17, 11, 55), Dates.Hour(10)) -2016-07-17T12:00:00 -``` - -That may seem confusing, given that the hour (12) is not divisible by 10. The reason that `2016-07-17T12:00:00` -was chosen is that it is 17,676,660 hours after `0000-01-01T00:00:00`, and 17,676,660 is divisible -by 10. - -As Julia [`Date`](@ref) and [`DateTime`](@ref) values are represented according to the ISO 8601 -standard, `0000-01-01T00:00:00` was chosen as base (or "rounding epoch") from which to begin the -count of days (and milliseconds) used in rounding calculations. (Note that this differs slightly -from Julia's internal representation of [`Date`](@ref) s using Rata Die notation; but since the -ISO 8601 standard is most visible to the end user, `0000-01-01T00:00:00` was chosen as the rounding -epoch instead of the `0000-12-31T00:00:00` used internally to minimize confusion.) - -The only exception to the use of `0000-01-01T00:00:00` as the rounding epoch is when rounding -to weeks. Rounding to the nearest week will always return a Monday (the first day of the week -as specified by ISO 8601). For this reason, we use `0000-01-03T00:00:00` (the first day of the -first week of year 0000, as defined by ISO 8601) as the base when rounding to a number of weeks. - -Here is a related case in which the expected behaviour is not necessarily obvious: What happens -when we round to the nearest `P(2)`, where `P` is a [`Period`](@ref) type? In some cases (specifically, -when `P <: Dates.TimePeriod`) the answer is clear: - -```jldoctest -julia> round(DateTime(2016, 7, 17, 8, 55, 30), Dates.Hour(2)) -2016-07-17T08:00:00 - -julia> round(DateTime(2016, 7, 17, 8, 55, 30), Dates.Minute(2)) -2016-07-17T08:56:00 -``` - -This seems obvious, because two of each of these periods still divides evenly into the next larger -order period. But in the case of two months (which still divides evenly into one year), the answer -may be surprising: - -```jldoctest -julia> round(DateTime(2016, 7, 17, 8, 55, 30), Dates.Month(2)) -2016-07-01T00:00:00 -``` - -Why round to the first day in July, even though it is month 7 (an odd number)? The key is that -months are 1-indexed (the first month is assigned 1), unlike hours, minutes, seconds, and milliseconds -(the first of which are assigned 0). - -This means that rounding a [`DateTime`](@ref) to an even multiple of seconds, minutes, hours, -or years (because the ISO 8601 specification includes a year zero) will result in a [`DateTime`](@ref) -with an even value in that field, while rounding a [`DateTime`](@ref) to an even multiple of months -will result in the months field having an odd value. Because both months and years may contain -an irregular number of days, whether rounding to an even number of days will result in an even -value in the days field is uncertain. - -See the [API reference](@ref stdlib-dates-api) for additional information -on methods exported from the `Dates` module. - -# [API reference](@id stdlib-dates-api) - -## Dates and Time Types - -```@docs -Dates.Period -Dates.CompoundPeriod -Dates.Instant -Dates.UTInstant -Dates.TimeType -Dates.DateTime -Dates.Date -Dates.Time -``` - -## Dates Functions - -```@docs -Dates.DateTime(::Int64, ::Int64, ::Int64, ::Int64, ::Int64, ::Int64, ::Int64) -Dates.DateTime(::Dates.Period) -Dates.DateTime(::Function, ::Any...) -Dates.DateTime(::Dates.TimeType) -Dates.DateTime(::AbstractString, ::AbstractString) -Dates.format -Dates.DateFormat -Dates.@dateformat_str -Dates.DateTime(::AbstractString, ::Dates.DateFormat) -Dates.Date(::Int64, ::Int64, ::Int64) -Dates.Date(::Dates.Period) -Dates.Date(::Function, ::Any, ::Any, ::Any) -Dates.Date(::Dates.TimeType) -Dates.Date(::AbstractString, ::AbstractString) -Dates.Date(::AbstractString, ::Dates.DateFormat) -Dates.Time(::Int64::Int64, ::Int64, ::Int64, ::Int64, ::Int64) -Dates.Time(::Dates.TimePeriod) -Dates.Time(::Function, ::Any...) -Dates.Time(::Dates.DateTime) -Dates.now() -Dates.now(::Type{Dates.UTC}) -Base.eps -``` - -### Accessor Functions - -```@docs -Dates.year -Dates.month -Dates.week -Dates.day -Dates.hour -Dates.minute -Dates.second -Dates.millisecond -Dates.microsecond -Dates.nanosecond -Dates.Year(::Dates.TimeType) -Dates.Month(::Dates.TimeType) -Dates.Week(::Dates.TimeType) -Dates.Day(::Dates.TimeType) -Dates.Hour(::DateTime) -Dates.Minute(::DateTime) -Dates.Second(::DateTime) -Dates.Millisecond(::DateTime) -Dates.Microsecond(::Dates.Time) -Dates.Nanosecond(::Dates.Time) -Dates.yearmonth -Dates.monthday -Dates.yearmonthday -``` - -### Query Functions - -```@docs -Dates.dayname -Dates.dayabbr -Dates.dayofweek -Dates.dayofmonth -Dates.dayofweekofmonth -Dates.daysofweekinmonth -Dates.monthname -Dates.monthabbr -Dates.daysinmonth -Dates.isleapyear -Dates.dayofyear -Dates.daysinyear -Dates.quarterofyear -Dates.dayofquarter -``` - -### Adjuster Functions - -```@docs -Base.trunc(::Dates.TimeType, ::Type{Dates.Period}) -Dates.firstdayofweek -Dates.lastdayofweek -Dates.firstdayofmonth -Dates.lastdayofmonth -Dates.firstdayofyear -Dates.lastdayofyear -Dates.firstdayofquarter -Dates.lastdayofquarter -Dates.tonext(::Dates.TimeType, ::Int) -Dates.toprev(::Dates.TimeType, ::Int) -Dates.tofirst -Dates.tolast -Dates.tonext(::Function, ::Dates.TimeType) -Dates.toprev(::Function, ::Dates.TimeType) -``` - -### Periods - -```@docs -Dates.Period(::Any) -Dates.CompoundPeriod(::Vector{<:Dates.Period}) -Dates.default -``` - -### Rounding Functions - -`Date` and `DateTime` values can be rounded to a specified resolution (e.g., 1 month or 15 minutes) -with `floor`, `ceil`, or `round`. - -```@docs -Base.floor(::Dates.TimeType, ::Dates.Period) -Base.ceil(::Dates.TimeType, ::Dates.Period) -Base.round(::Dates.TimeType, ::Dates.Period, ::RoundingMode{:NearestTiesUp}) -``` - -Most `Period` values can also be rounded to a specified resolution: - -```@docs -Base.floor(::Dates.ConvertiblePeriod, ::T) where T <: Dates.ConvertiblePeriod -Base.ceil(::Dates.ConvertiblePeriod, ::Dates.ConvertiblePeriod) -Base.round(::Dates.ConvertiblePeriod, ::Dates.ConvertiblePeriod, ::RoundingMode{:NearestTiesUp}) -``` - -The following functions are not exported: - -```@docs -Dates.floorceil -Dates.epochdays2date -Dates.epochms2datetime -Dates.date2epochdays -Dates.datetime2epochms -``` - -### Conversion Functions - -```@docs -Dates.today -Dates.unix2datetime -Dates.datetime2unix -Dates.julian2datetime -Dates.datetime2julian -Dates.rata2datetime -Dates.datetime2rata -``` - -### Constants - -Days of the Week: - -| Variable | Abbr. | Value (Int) | -|:----------- |:----- |:----------- | -| `Monday` | `Mon` | 1 | -| `Tuesday` | `Tue` | 2 | -| `Wednesday` | `Wed` | 3 | -| `Thursday` | `Thu` | 4 | -| `Friday` | `Fri` | 5 | -| `Saturday` | `Sat` | 6 | -| `Sunday` | `Sun` | 7 | - -Months of the Year: - -| Variable | Abbr. | Value (Int) | -|:----------- |:----- |:----------- | -| `January` | `Jan` | 1 | -| `February` | `Feb` | 2 | -| `March` | `Mar` | 3 | -| `April` | `Apr` | 4 | -| `May` | `May` | 5 | -| `June` | `Jun` | 6 | -| `July` | `Jul` | 7 | -| `August` | `Aug` | 8 | -| `September` | `Sep` | 9 | -| `October` | `Oct` | 10 | -| `November` | `Nov` | 11 | -| `December` | `Dec` | 12 | - -```@meta -DocTestSetup = nothing -``` diff --git a/codex/stdlib/delimitedfiles.md b/codex/stdlib/delimitedfiles.md deleted file mode 100644 index 839bdb8..0000000 --- a/codex/stdlib/delimitedfiles.md +++ /dev/null @@ -1,19 +0,0 @@ -# Delimited Files - -```@meta -DocTestSetup = :(using DelimitedFiles) -``` - -```@docs -DelimitedFiles.readdlm(::Any, ::AbstractChar, ::Type, ::AbstractChar) -DelimitedFiles.readdlm(::Any, ::AbstractChar, ::AbstractChar) -DelimitedFiles.readdlm(::Any, ::AbstractChar, ::Type) -DelimitedFiles.readdlm(::Any, ::AbstractChar) -DelimitedFiles.readdlm(::Any, ::Type) -DelimitedFiles.readdlm(::Any) -DelimitedFiles.writedlm -``` - -```@meta -DocTestSetup = nothing -``` diff --git a/codex/stdlib/distributed.md b/codex/stdlib/distributed.md deleted file mode 100644 index da0b822..0000000 --- a/codex/stdlib/distributed.md +++ /dev/null @@ -1,77 +0,0 @@ -# Distributed Computing - -```@meta -DocTestSetup = :(using Distributed) -``` - -```@docs -Distributed.addprocs -Distributed.nprocs -Distributed.nworkers -Distributed.procs() -Distributed.procs(::Integer) -Distributed.workers -Distributed.rmprocs -Distributed.interrupt -Distributed.myid -Distributed.pmap -Distributed.RemoteException -Distributed.Future -Distributed.RemoteChannel -Distributed.wait -Distributed.fetch(::Any) -Distributed.remotecall(::Any, ::Integer, ::Any...) -Distributed.remotecall_wait(::Any, ::Integer, ::Any...) -Distributed.remotecall_fetch(::Any, ::Integer, ::Any...) -Distributed.remote_do(::Any, ::Integer, ::Any...) -Distributed.put!(::RemoteChannel, ::Any...) -Distributed.put!(::Future, ::Any) -Distributed.take!(::RemoteChannel, ::Any...) -Distributed.isready(::RemoteChannel, ::Any...) -Distributed.isready(::Future) -Distributed.WorkerPool -Distributed.CachingPool -Distributed.default_worker_pool -Distributed.clear!(::CachingPool) -Distributed.remote -Distributed.remotecall(::Any, ::AbstractWorkerPool, ::Any...) -Distributed.remotecall_wait(::Any, ::AbstractWorkerPool, ::Any...) -Distributed.remotecall_fetch(::Any, ::AbstractWorkerPool, ::Any...) -Distributed.remote_do(::Any, ::AbstractWorkerPool, ::Any...) -Distributed.timedwait -Distributed.@spawn -Distributed.@spawnat -Distributed.@fetch -Distributed.@fetchfrom -Distributed.@async -Distributed.@sync -Distributed.@distributed -Distributed.@everywhere -Distributed.clear!(::Any, ::Any; ::Any) -Distributed.remoteref_id -Distributed.channel_from_id -Distributed.worker_id_from_socket -Distributed.cluster_cookie() -Distributed.cluster_cookie(::Any) -``` - -## Cluster Manager Interface - -This interface provides a mechanism to launch and manage Julia workers on different cluster environments. -There are two types of managers present in Base: `LocalManager`, for launching additional workers on the -same host, and `SSHManager`, for launching on remote hosts via `ssh`. TCP/IP sockets are used to connect -and transport messages between processes. It is possible for Cluster Managers to provide a different transport. - -```@docs -Distributed.launch -Distributed.manage -Distributed.kill(::ClusterManager, ::Int, ::WorkerConfig) -Distributed.connect(::ClusterManager, ::Int, ::WorkerConfig) -Distributed.init_worker -Distributed.start_worker -Distributed.process_messages -``` - -```@meta -DocTestSetup = nothing -``` diff --git a/codex/stdlib/filewatching.md b/codex/stdlib/filewatching.md deleted file mode 100644 index 3944f5d..0000000 --- a/codex/stdlib/filewatching.md +++ /dev/null @@ -1,9 +0,0 @@ -# [File Events](@id lib-filewatching) - -```@docs -FileWatching.poll_fd -FileWatching.poll_file -FileWatching.watch_file -FileWatching.watch_folder -FileWatching.unwatch_folder -``` diff --git a/codex/stdlib/libdl.md b/codex/stdlib/libdl.md deleted file mode 100644 index c25ad8c..0000000 --- a/codex/stdlib/libdl.md +++ /dev/null @@ -1,13 +0,0 @@ -# Dynamic Linker - -```@docs -Libdl.dlopen -Libdl.dlopen_e -Libdl.RTLD_NOW -Libdl.dlsym -Libdl.dlsym_e -Libdl.dlclose -Libdl.dlext -Libdl.find_library -Libdl.DL_LOAD_PATH -``` diff --git a/codex/stdlib/linearalgebra.md b/codex/stdlib/linearalgebra.md deleted file mode 100644 index bc32753..0000000 --- a/codex/stdlib/linearalgebra.md +++ /dev/null @@ -1,625 +0,0 @@ -# Linear Algebra - -```@meta -DocTestSetup = :(using LinearAlgebra) -``` - -In addition to (and as part of) its support for multi-dimensional arrays, Julia provides native implementations -of many common and useful linear algebra operations. Basic operations, such as [`tr`](@ref), [`det`](@ref), -and [`inv`](@ref) are all supported: - -```jldoctest -julia> A = [1 2 3; 4 1 6; 7 8 1] -3×3 Array{Int64,2}: - 1 2 3 - 4 1 6 - 7 8 1 - -julia> tr(A) -3 - -julia> det(A) -104.0 - -julia> inv(A) -3×3 Array{Float64,2}: - -0.451923 0.211538 0.0865385 - 0.365385 -0.192308 0.0576923 - 0.240385 0.0576923 -0.0673077 -``` - -As well as other useful operations, such as finding eigenvalues or eigenvectors: - -```jldoctest -julia> A = [-4. -17.; 2. 2.] -2×2 Array{Float64,2}: - -4.0 -17.0 - 2.0 2.0 - -julia> eigvals(A) -2-element Array{Complex{Float64},1}: - -1.0 + 5.0im - -1.0 - 5.0im - -julia> eigvecs(A) -2×2 Array{Complex{Float64},2}: - 0.945905+0.0im 0.945905-0.0im - -0.166924-0.278207im -0.166924+0.278207im -``` - -In addition, Julia provides many [factorizations](@ref man-linalg-factorizations) which can be used to -speed up problems such as linear solve or matrix exponentiation by pre-factorizing a matrix into a form -more amenable (for performance or memory reasons) to the problem. See the documentation on [`factorize`](@ref) -for more information. As an example: - -```jldoctest -julia> A = [1.5 2 -4; 3 -1 -6; -10 2.3 4] -3×3 Array{Float64,2}: - 1.5 2.0 -4.0 - 3.0 -1.0 -6.0 - -10.0 2.3 4.0 - -julia> factorize(A) -LU{Float64,Array{Float64,2}} -L factor: -3×3 Array{Float64,2}: - 1.0 0.0 0.0 - -0.15 1.0 0.0 - -0.3 -0.132196 1.0 -U factor: -3×3 Array{Float64,2}: - -10.0 2.3 4.0 - 0.0 2.345 -3.4 - 0.0 0.0 -5.24947 -``` - -Since `A` is not Hermitian, symmetric, triangular, tridiagonal, or bidiagonal, an LU factorization may be the -best we can do. Compare with: - -```jldoctest -julia> B = [1.5 2 -4; 2 -1 -3; -4 -3 5] -3×3 Array{Float64,2}: - 1.5 2.0 -4.0 - 2.0 -1.0 -3.0 - -4.0 -3.0 5.0 - -julia> factorize(B) -BunchKaufman{Float64,Array{Float64,2}} -D factor: -3×3 Tridiagonal{Float64,Array{Float64,1}}: - -1.64286 0.0 ⋅ - 0.0 -2.8 0.0 - ⋅ 0.0 5.0 -U factor: -3×3 UnitUpperTriangular{Float64,Array{Float64,2}}: - 1.0 0.142857 -0.8 - ⋅ 1.0 -0.6 - ⋅ ⋅ 1.0 -permutation: -3-element Array{Int64,1}: - 1 - 2 - 3 -``` - -Here, Julia was able to detect that `B` is in fact symmetric, and used a more appropriate factorization. -Often it's possible to write more efficient code for a matrix that is known to have certain properties e.g. -it is symmetric, or tridiagonal. Julia provides some special types so that you can "tag" matrices as having -these properties. For instance: - -```jldoctest -julia> B = [1.5 2 -4; 2 -1 -3; -4 -3 5] -3×3 Array{Float64,2}: - 1.5 2.0 -4.0 - 2.0 -1.0 -3.0 - -4.0 -3.0 5.0 - -julia> sB = Symmetric(B) -3×3 Symmetric{Float64,Array{Float64,2}}: - 1.5 2.0 -4.0 - 2.0 -1.0 -3.0 - -4.0 -3.0 5.0 -``` - -`sB` has been tagged as a matrix that's (real) symmetric, so for later operations we might perform on it, -such as eigenfactorization or computing matrix-vector products, efficiencies can be found by only referencing -half of it. For example: - -```jldoctest -julia> B = [1.5 2 -4; 2 -1 -3; -4 -3 5] -3×3 Array{Float64,2}: - 1.5 2.0 -4.0 - 2.0 -1.0 -3.0 - -4.0 -3.0 5.0 - -julia> sB = Symmetric(B) -3×3 Symmetric{Float64,Array{Float64,2}}: - 1.5 2.0 -4.0 - 2.0 -1.0 -3.0 - -4.0 -3.0 5.0 - -julia> x = [1; 2; 3] -3-element Array{Int64,1}: - 1 - 2 - 3 - -julia> sB\x -3-element Array{Float64,1}: - -1.7391304347826084 - -1.1086956521739126 - -1.4565217391304346 -``` -The `\` operation here performs the linear solution. The left-division operator is pretty powerful and it's easy to write compact, readable code that is flexible enough to solve all sorts of systems of linear equations. - -## Special matrices - -[Matrices with special symmetries and structures](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=3274) -arise often in linear algebra and are frequently associated with various matrix factorizations. -Julia features a rich collection of special matrix types, which allow for fast computation with -specialized routines that are specially developed for particular matrix types. - -The following tables summarize the types of special matrices that have been implemented in Julia, -as well as whether hooks to various optimized methods for them in LAPACK are available. - -| Type | Description | -|:------------------------- |:-------------------------------------------------------------------------------- | -| [`Symmetric`](@ref) | [Symmetric matrix](https://en.wikipedia.org/wiki/Symmetric_matrix) | -| [`Hermitian`](@ref) | [Hermitian matrix](https://en.wikipedia.org/wiki/Hermitian_matrix) | -| [`UpperTriangular`](@ref) | Upper [triangular matrix](https://en.wikipedia.org/wiki/Triangular_matrix) | -| [`LowerTriangular`](@ref) | Lower [triangular matrix](https://en.wikipedia.org/wiki/Triangular_matrix) | -| [`Tridiagonal`](@ref) | [Tridiagonal matrix](https://en.wikipedia.org/wiki/Tridiagonal_matrix) | -| [`SymTridiagonal`](@ref) | Symmetric tridiagonal matrix | -| [`Bidiagonal`](@ref) | Upper/lower [bidiagonal matrix](https://en.wikipedia.org/wiki/Bidiagonal_matrix) | -| [`Diagonal`](@ref) | [Diagonal matrix](https://en.wikipedia.org/wiki/Diagonal_matrix) | -| [`UniformScaling`](@ref) | [Uniform scaling operator](https://en.wikipedia.org/wiki/Uniform_scaling) | - -### Elementary operations - -| Matrix type | `+` | `-` | `*` | `\` | Other functions with optimized methods | -|:------------------------- |:--- |:--- |:--- |:--- |:----------------------------------------------------------- | -| [`Symmetric`](@ref) | | | | MV | [`inv`](@ref), [`sqrt`](@ref), [`exp`](@ref) | -| [`Hermitian`](@ref) | | | | MV | [`inv`](@ref), [`sqrt`](@ref), [`exp`](@ref) | -| [`UpperTriangular`](@ref) | | | MV | MV | [`inv`](@ref), [`det`](@ref) | -| [`LowerTriangular`](@ref) | | | MV | MV | [`inv`](@ref), [`det`](@ref) | -| [`SymTridiagonal`](@ref) | M | M | MS | MV | [`eigmax`](@ref), [`eigmin`](@ref) | -| [`Tridiagonal`](@ref) | M | M | MS | MV | | -| [`Bidiagonal`](@ref) | M | M | MS | MV | | -| [`Diagonal`](@ref) | M | M | MV | MV | [`inv`](@ref), [`det`](@ref), [`logdet`](@ref), [`/`](@ref) | -| [`UniformScaling`](@ref) | M | M | MVS | MVS | [`/`](@ref) | - -Legend: - -| Key | Description | -|:---------- |:------------------------------------------------------------- | -| M (matrix) | An optimized method for matrix-matrix operations is available | -| V (vector) | An optimized method for matrix-vector operations is available | -| S (scalar) | An optimized method for matrix-scalar operations is available | - -### Matrix factorizations - -| Matrix type | LAPACK | [`eigen`](@ref) | [`eigvals`](@ref) | [`eigvecs`](@ref) | [`svd`](@ref) | [`svdvals`](@ref) | -|:------------------------- |:------ |:------------- |:----------------- |:----------------- |:------------- |:----------------- | -| [`Symmetric`](@ref) | SY | | ARI | | | | -| [`Hermitian`](@ref) | HE | | ARI | | | | -| [`UpperTriangular`](@ref) | TR | A | A | A | | | -| [`LowerTriangular`](@ref) | TR | A | A | A | | | -| [`SymTridiagonal`](@ref) | ST | A | ARI | AV | | | -| [`Tridiagonal`](@ref) | GT | | | | | | -| [`Bidiagonal`](@ref) | BD | | | | A | A | -| [`Diagonal`](@ref) | DI | | A | | | | - -Legend: - -| Key | Description | Example | -|:------------ |:------------------------------------------------------------------------------------------------------------------------------- |:-------------------- | -| A (all) | An optimized method to find all the characteristic values and/or vectors is available | e.g. `eigvals(M)` | -| R (range) | An optimized method to find the `il`th through the `ih`th characteristic values are available | `eigvals(M, il, ih)` | -| I (interval) | An optimized method to find the characteristic values in the interval [`vl`, `vh`] is available | `eigvals(M, vl, vh)` | -| V (vectors) | An optimized method to find the characteristic vectors corresponding to the characteristic values `x=[x1, x2,...]` is available | `eigvecs(M, x)` | - -### The uniform scaling operator - -A [`UniformScaling`](@ref) operator represents a scalar times the identity operator, `λ*I`. The identity -operator `I` is defined as a constant and is an instance of `UniformScaling`. The size of these -operators are generic and match the other matrix in the binary operations [`+`](@ref), [`-`](@ref), -[`*`](@ref) and [`\`](@ref). For `A+I` and `A-I` this means that `A` must be square. Multiplication -with the identity operator `I` is a noop (except for checking that the scaling factor is one) -and therefore almost without overhead. - -To see the `UniformScaling` operator in action: - -```jldoctest -julia> U = UniformScaling(2); - -julia> a = [1 2; 3 4] -2×2 Array{Int64,2}: - 1 2 - 3 4 - -julia> a + U -2×2 Array{Int64,2}: - 3 2 - 3 6 - -julia> a * U -2×2 Array{Int64,2}: - 2 4 - 6 8 - -julia> [a U] -2×4 Array{Int64,2}: - 1 2 2 0 - 3 4 0 2 - -julia> b = [1 2 3; 4 5 6] -2×3 Array{Int64,2}: - 1 2 3 - 4 5 6 - -julia> b - U -ERROR: DimensionMismatch("matrix is not square: dimensions are (2, 3)") -Stacktrace: -[...] -``` - -## [Matrix factorizations](@id man-linalg-factorizations) - -[Matrix factorizations (a.k.a. matrix decompositions)](https://en.wikipedia.org/wiki/Matrix_decomposition) -compute the factorization of a matrix into a product of matrices, and are one of the central concepts -in linear algebra. - -The following table summarizes the types of matrix factorizations that have been implemented in -Julia. Details of their associated methods can be found in the [Standard Functions](@ref) section -of the Linear Algebra documentation. - -| Type | Description | -|:----------------- |:-------------------------------------------------------------------------------------------------------------- | -| `Cholesky` | [Cholesky factorization](https://en.wikipedia.org/wiki/Cholesky_decomposition) | -| `CholeskyPivoted` | [Pivoted](https://en.wikipedia.org/wiki/Pivot_element) Cholesky factorization | -| `LU` | [LU factorization](https://en.wikipedia.org/wiki/LU_decomposition) | -| `LUTridiagonal` | LU factorization for [`Tridiagonal`](@ref) matrices | -| `QR` | [QR factorization](https://en.wikipedia.org/wiki/QR_decomposition) | -| `QRCompactWY` | Compact WY form of the QR factorization | -| `QRPivoted` | Pivoted [QR factorization](https://en.wikipedia.org/wiki/QR_decomposition) | -| `Hessenberg` | [Hessenberg decomposition](http://mathworld.wolfram.com/HessenbergDecomposition.html) | -| `Eigen` | [Spectral decomposition](https://en.wikipedia.org/wiki/Eigendecomposition_(matrix)) | -| `SVD` | [Singular value decomposition](https://en.wikipedia.org/wiki/Singular_value_decomposition) | -| `GeneralizedSVD` | [Generalized SVD](https://en.wikipedia.org/wiki/Generalized_singular_value_decomposition#Higher_order_version) | - - - - -## Standard Functions - -Linear algebra functions in Julia are largely implemented by calling functions from [LAPACK](http://www.netlib.org/lapack/). - Sparse factorizations call functions from [SuiteSparse](http://faculty.cse.tamu.edu/davis/suitesparse.html). - -```@docs -Base.:*(::AbstractMatrix, ::AbstractMatrix) -Base.:\(::AbstractMatrix, ::AbstractVecOrMat) -LinearAlgebra.dot -LinearAlgebra.cross -LinearAlgebra.factorize -LinearAlgebra.Diagonal -LinearAlgebra.Bidiagonal -LinearAlgebra.SymTridiagonal -LinearAlgebra.Tridiagonal -LinearAlgebra.Symmetric -LinearAlgebra.Hermitian -LinearAlgebra.LowerTriangular -LinearAlgebra.UpperTriangular -LinearAlgebra.UniformScaling -LinearAlgebra.lu -LinearAlgebra.lu! -LinearAlgebra.cholesky -LinearAlgebra.cholesky! -LinearAlgebra.lowrankupdate -LinearAlgebra.lowrankdowndate -LinearAlgebra.lowrankupdate! -LinearAlgebra.lowrankdowndate! -LinearAlgebra.ldlt -LinearAlgebra.ldlt! -LinearAlgebra.qr -LinearAlgebra.qr! -LinearAlgebra.QR -LinearAlgebra.QRCompactWY -LinearAlgebra.QRPivoted -LinearAlgebra.lq! -LinearAlgebra.lq -LinearAlgebra.bunchkaufman -LinearAlgebra.bunchkaufman! -LinearAlgebra.eigvals -LinearAlgebra.eigvals! -LinearAlgebra.eigmax -LinearAlgebra.eigmin -LinearAlgebra.eigvecs -LinearAlgebra.eigen -LinearAlgebra.eigen! -LinearAlgebra.hessenberg -LinearAlgebra.hessenberg! -LinearAlgebra.schur! -LinearAlgebra.schur -LinearAlgebra.ordschur -LinearAlgebra.ordschur! -LinearAlgebra.svd -LinearAlgebra.svd! -LinearAlgebra.svdvals -LinearAlgebra.svdvals! -LinearAlgebra.Givens -LinearAlgebra.givens -LinearAlgebra.triu -LinearAlgebra.triu! -LinearAlgebra.tril -LinearAlgebra.tril! -LinearAlgebra.diagind -LinearAlgebra.diag -LinearAlgebra.diagm -LinearAlgebra.rank -LinearAlgebra.norm -LinearAlgebra.opnorm -LinearAlgebra.normalize! -LinearAlgebra.normalize -LinearAlgebra.cond -LinearAlgebra.condskeel -LinearAlgebra.tr -LinearAlgebra.det -LinearAlgebra.logdet -LinearAlgebra.logabsdet -Base.inv(::AbstractMatrix) -LinearAlgebra.pinv -LinearAlgebra.nullspace -Base.kron -LinearAlgebra.exp(::StridedMatrix{<:LinearAlgebra.BlasFloat}) -LinearAlgebra.log(::StridedMatrix) -LinearAlgebra.sqrt(::StridedMatrix{<:Real}) -LinearAlgebra.cos(::StridedMatrix{<:Real}) -LinearAlgebra.sin(::StridedMatrix{<:Real}) -LinearAlgebra.sincos(::StridedMatrix{<:Real}) -LinearAlgebra.tan(::StridedMatrix{<:Real}) -LinearAlgebra.sec(::StridedMatrix) -LinearAlgebra.csc(::StridedMatrix) -LinearAlgebra.cot(::StridedMatrix) -LinearAlgebra.cosh(::StridedMatrix) -LinearAlgebra.sinh(::StridedMatrix) -LinearAlgebra.tanh(::StridedMatrix) -LinearAlgebra.sech(::StridedMatrix) -LinearAlgebra.csch(::StridedMatrix) -LinearAlgebra.coth(::StridedMatrix) -LinearAlgebra.acos(::StridedMatrix) -LinearAlgebra.asin(::StridedMatrix) -LinearAlgebra.atan(::StridedMatrix) -LinearAlgebra.asec(::StridedMatrix) -LinearAlgebra.acsc(::StridedMatrix) -LinearAlgebra.acot(::StridedMatrix) -LinearAlgebra.acosh(::StridedMatrix) -LinearAlgebra.asinh(::StridedMatrix) -LinearAlgebra.atanh(::StridedMatrix) -LinearAlgebra.asech(::StridedMatrix) -LinearAlgebra.acsch(::StridedMatrix) -LinearAlgebra.acoth(::StridedMatrix) -LinearAlgebra.lyap -LinearAlgebra.sylvester -LinearAlgebra.issuccess -LinearAlgebra.issymmetric -LinearAlgebra.isposdef -LinearAlgebra.isposdef! -LinearAlgebra.istril -LinearAlgebra.istriu -LinearAlgebra.isdiag -LinearAlgebra.ishermitian -Base.transpose -LinearAlgebra.transpose! -Base.adjoint -LinearAlgebra.adjoint! -Base.copy(::Union{Transpose,Adjoint}) -LinearAlgebra.stride1 -LinearAlgebra.checksquare -``` - -## Low-level matrix operations - -In many cases there are in-place versions of matrix operations that allow you to supply -a pre-allocated output vector or matrix. This is useful when optimizing critical code in order -to avoid the overhead of repeated allocations. These in-place operations are suffixed with `!` -below (e.g. `mul!`) according to the usual Julia convention. - -```@docs -LinearAlgebra.mul! -LinearAlgebra.lmul! -LinearAlgebra.rmul! -LinearAlgebra.ldiv! -LinearAlgebra.rdiv! -``` - -## BLAS Functions - -In Julia (as in much of scientific computation), dense linear-algebra operations are based on -the [LAPACK library](http://www.netlib.org/lapack/), which in turn is built on top of basic linear-algebra -building-blocks known as the [BLAS](http://www.netlib.org/blas/). There are highly optimized -implementations of BLAS available for every computer architecture, and sometimes in high-performance -linear algebra routines it is useful to call the BLAS functions directly. - -`LinearAlgebra.BLAS` provides wrappers for some of the BLAS functions. Those BLAS functions -that overwrite one of the input arrays have names ending in `'!'`. Usually, a BLAS function has -four methods defined, for [`Float64`](@ref), [`Float32`](@ref), `ComplexF64`, and `ComplexF32` arrays. - -### [BLAS Character Arguments](@id stdlib-blas-chars) -Many BLAS functions accept arguments that determine whether to transpose an argument (`trans`), -which triangle of a matrix to reference (`uplo` or `ul`), -whether the diagonal of a triangular matrix can be assumed to -be all ones (`dA`) or which side of a matrix multiplication -the input argument belongs on (`side`). The possibilities are: - -#### [Multplication Order](@id stdlib-blas-side) -| `side` | Meaning | -|:-------|:--------------------------------------------------------------------| -| `'L'` | The argument goes on the *left* side of a matrix-matrix operation. | -| `'R'` | The argument goes on the *right* side of a matrix-matrix operation. | - -#### [Triangle Referencing](@id stdlib-blas-uplo) -| `uplo`/`ul` | Meaning | -|:------------|:------------------------------------------------------| -| `'U'` | Only the *upper* triangle of the matrix will be used. | -| `'L'` | Only the *lower* triangle of the matrix will be used. | - -#### [Transposition Operation](@id stdlib-blas-trans) -| `trans`/`tX` | Meaning | -|:-------------|:--------------------------------------------------------| -| `'N'` | The input matrix `X` is not transposed or conjugated. | -| `'T'` | The input matrix `X` will be transposed. | -| `'C'` | The input matrix `X` will be conjugated and transposed. | - -#### [Unit Diagonal](@id stdlib-blas-diag) -| `diag`/`dX` | Meaning | -|:------------|:----------------------------------------------------------| -| `'N'` | The diagonal values of the matrix `X` will be read. | -| `'U'` | The diagonal of the matrix `X` is assumed to be all ones. | - -```@docs -LinearAlgebra.BLAS -LinearAlgebra.BLAS.dotu -LinearAlgebra.BLAS.dotc -LinearAlgebra.BLAS.blascopy! -LinearAlgebra.BLAS.nrm2 -LinearAlgebra.BLAS.asum -LinearAlgebra.axpy! -LinearAlgebra.BLAS.scal! -LinearAlgebra.BLAS.scal -LinearAlgebra.BLAS.ger! -LinearAlgebra.BLAS.syr! -LinearAlgebra.BLAS.syrk! -LinearAlgebra.BLAS.syrk -LinearAlgebra.BLAS.her! -LinearAlgebra.BLAS.herk! -LinearAlgebra.BLAS.herk -LinearAlgebra.BLAS.gbmv! -LinearAlgebra.BLAS.gbmv -LinearAlgebra.BLAS.sbmv! -LinearAlgebra.BLAS.sbmv(::Any, ::Any, ::Any, ::Any, ::Any) -LinearAlgebra.BLAS.sbmv(::Any, ::Any, ::Any, ::Any) -LinearAlgebra.BLAS.gemm! -LinearAlgebra.BLAS.gemm(::Any, ::Any, ::Any, ::Any, ::Any) -LinearAlgebra.BLAS.gemm(::Any, ::Any, ::Any, ::Any) -LinearAlgebra.BLAS.gemv! -LinearAlgebra.BLAS.gemv(::Any, ::Any, ::Any, ::Any) -LinearAlgebra.BLAS.gemv(::Any, ::Any, ::Any) -LinearAlgebra.BLAS.symm! -LinearAlgebra.BLAS.symm(::Any, ::Any, ::Any, ::Any, ::Any) -LinearAlgebra.BLAS.symm(::Any, ::Any, ::Any, ::Any) -LinearAlgebra.BLAS.symv! -LinearAlgebra.BLAS.symv(::Any, ::Any, ::Any, ::Any) -LinearAlgebra.BLAS.symv(::Any, ::Any, ::Any) -LinearAlgebra.BLAS.trmm! -LinearAlgebra.BLAS.trmm -LinearAlgebra.BLAS.trsm! -LinearAlgebra.BLAS.trsm -LinearAlgebra.BLAS.trmv! -LinearAlgebra.BLAS.trmv -LinearAlgebra.BLAS.trsv! -LinearAlgebra.BLAS.trsv -LinearAlgebra.BLAS.set_num_threads -LinearAlgebra.I -``` - -## LAPACK Functions - -`LinearAlgebra.LAPACK` provides wrappers for some of the LAPACK functions for linear algebra. - Those functions that overwrite one of the input arrays have names ending in `'!'`. - -Usually a function has 4 methods defined, one each for [`Float64`](@ref), [`Float32`](@ref), -`ComplexF64` and `ComplexF32` arrays. - -Note that the LAPACK API provided by Julia can and will change in the future. Since this API is -not user-facing, there is no commitment to support/deprecate this specific set of functions in -future releases. - -```@docs -LinearAlgebra.LAPACK -LinearAlgebra.LAPACK.gbtrf! -LinearAlgebra.LAPACK.gbtrs! -LinearAlgebra.LAPACK.gebal! -LinearAlgebra.LAPACK.gebak! -LinearAlgebra.LAPACK.gebrd! -LinearAlgebra.LAPACK.gelqf! -LinearAlgebra.LAPACK.geqlf! -LinearAlgebra.LAPACK.geqrf! -LinearAlgebra.LAPACK.geqp3! -LinearAlgebra.LAPACK.gerqf! -LinearAlgebra.LAPACK.geqrt! -LinearAlgebra.LAPACK.geqrt3! -LinearAlgebra.LAPACK.getrf! -LinearAlgebra.LAPACK.tzrzf! -LinearAlgebra.LAPACK.ormrz! -LinearAlgebra.LAPACK.gels! -LinearAlgebra.LAPACK.gesv! -LinearAlgebra.LAPACK.getrs! -LinearAlgebra.LAPACK.getri! -LinearAlgebra.LAPACK.gesvx! -LinearAlgebra.LAPACK.gelsd! -LinearAlgebra.LAPACK.gelsy! -LinearAlgebra.LAPACK.gglse! -LinearAlgebra.LAPACK.geev! -LinearAlgebra.LAPACK.gesdd! -LinearAlgebra.LAPACK.gesvd! -LinearAlgebra.LAPACK.ggsvd! -LinearAlgebra.LAPACK.ggsvd3! -LinearAlgebra.LAPACK.geevx! -LinearAlgebra.LAPACK.ggev! -LinearAlgebra.LAPACK.gtsv! -LinearAlgebra.LAPACK.gttrf! -LinearAlgebra.LAPACK.gttrs! -LinearAlgebra.LAPACK.orglq! -LinearAlgebra.LAPACK.orgqr! -LinearAlgebra.LAPACK.orgql! -LinearAlgebra.LAPACK.orgrq! -LinearAlgebra.LAPACK.ormlq! -LinearAlgebra.LAPACK.ormqr! -LinearAlgebra.LAPACK.ormql! -LinearAlgebra.LAPACK.ormrq! -LinearAlgebra.LAPACK.gemqrt! -LinearAlgebra.LAPACK.posv! -LinearAlgebra.LAPACK.potrf! -LinearAlgebra.LAPACK.potri! -LinearAlgebra.LAPACK.potrs! -LinearAlgebra.LAPACK.pstrf! -LinearAlgebra.LAPACK.ptsv! -LinearAlgebra.LAPACK.pttrf! -LinearAlgebra.LAPACK.pttrs! -LinearAlgebra.LAPACK.trtri! -LinearAlgebra.LAPACK.trtrs! -LinearAlgebra.LAPACK.trcon! -LinearAlgebra.LAPACK.trevc! -LinearAlgebra.LAPACK.trrfs! -LinearAlgebra.LAPACK.stev! -LinearAlgebra.LAPACK.stebz! -LinearAlgebra.LAPACK.stegr! -LinearAlgebra.LAPACK.stein! -LinearAlgebra.LAPACK.syconv! -LinearAlgebra.LAPACK.sysv! -LinearAlgebra.LAPACK.sytrf! -LinearAlgebra.LAPACK.sytri! -LinearAlgebra.LAPACK.sytrs! -LinearAlgebra.LAPACK.hesv! -LinearAlgebra.LAPACK.hetrf! -LinearAlgebra.LAPACK.hetri! -LinearAlgebra.LAPACK.hetrs! -LinearAlgebra.LAPACK.syev! -LinearAlgebra.LAPACK.syevr! -LinearAlgebra.LAPACK.sygvd! -LinearAlgebra.LAPACK.bdsqr! -LinearAlgebra.LAPACK.bdsdc! -LinearAlgebra.LAPACK.gecon! -LinearAlgebra.LAPACK.gehrd! -LinearAlgebra.LAPACK.orghr! -LinearAlgebra.LAPACK.gees! -LinearAlgebra.LAPACK.gges! -LinearAlgebra.LAPACK.trexc! -LinearAlgebra.LAPACK.trsen! -LinearAlgebra.LAPACK.tgsen! -LinearAlgebra.LAPACK.trsyl! -``` - -```@meta -DocTestSetup = nothing -``` diff --git a/codex/stdlib/mmap.md b/codex/stdlib/mmap.md deleted file mode 100644 index 9bd623d..0000000 --- a/codex/stdlib/mmap.md +++ /dev/null @@ -1,15 +0,0 @@ -# Memory-mapped I/O - -```@meta -DocTestSetup = :(using Mmap) -``` - -```@docs -Mmap.Anonymous -Mmap.mmap -Mmap.sync! -``` - -```@meta -DocTestSetup = nothing -``` diff --git a/codex/stdlib/printf.md b/codex/stdlib/printf.md deleted file mode 100644 index de79d5c..0000000 --- a/codex/stdlib/printf.md +++ /dev/null @@ -1,14 +0,0 @@ -# Printf - -```@meta -DocTestSetup = :(using Printf) -``` - -```@docs -Printf.@printf -Printf.@sprintf -``` - -```@meta -DocTestSetup = nothing -``` diff --git a/codex/stdlib/profile.md b/codex/stdlib/profile.md deleted file mode 100644 index ac60bb9..0000000 --- a/codex/stdlib/profile.md +++ /dev/null @@ -1,17 +0,0 @@ -# [Profiling](@id lib-profiling) - -```@docs -Profile.@profile -``` - -The methods in `Profile` are not exported and need to be called e.g. as `Profile.print()`. - -```@docs -Profile.clear -Profile.print -Profile.init -Profile.fetch -Profile.retrieve -Profile.callers -Profile.clear_malloc_data -``` diff --git a/codex/stdlib/random.md b/codex/stdlib/random.md deleted file mode 100644 index 54abfc2..0000000 --- a/codex/stdlib/random.md +++ /dev/null @@ -1,50 +0,0 @@ -# Random Numbers - -```@meta -DocTestSetup = :(using Random) -``` - -Random number generation in Julia uses the [Mersenne Twister library](http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/#dSFMT) -via `MersenneTwister` objects. Julia has a global RNG, which is used by default. Other RNG types -can be plugged in by inheriting the `AbstractRNG` type; they can then be used to have multiple -streams of random numbers. Besides `MersenneTwister`, Julia also provides the `RandomDevice` RNG -type, which is a wrapper over the OS provided entropy. - -Most functions related to random generation accept an optional `AbstractRNG` as the first argument, -`rng` , which defaults to the global one if not provided. Moreover, some of them accept optionally -dimension specifications `dims...` (which can be given as a tuple) to generate arrays of random -values. - -A `MersenneTwister` or `RandomDevice` RNG can generate random numbers of the following types: -[`Float16`](@ref), [`Float32`](@ref), [`Float64`](@ref), [`BigFloat`](@ref), [`Bool`](@ref), -[`Int8`](@ref), [`UInt8`](@ref), [`Int16`](@ref), [`UInt16`](@ref), [`Int32`](@ref), -[`UInt32`](@ref), [`Int64`](@ref), [`UInt64`](@ref), [`Int128`](@ref), [`UInt128`](@ref), -[`BigInt`](@ref) (or complex numbers of those types). -Random floating point numbers are generated uniformly in ``[0, 1)``. As `BigInt` represents -unbounded integers, the interval must be specified (e.g. `rand(big.(1:6))`). - -```@docs -Random.srand -Random.MersenneTwister -Random.RandomDevice -Random.rand -Random.rand! -Random.bitrand -Random.randn -Random.randn! -Random.randexp -Random.randexp! -Random.randstring -Random.randsubseq -Random.randsubseq! -Random.randperm -Random.randperm! -Random.randcycle -Random.randcycle! -Random.shuffle -Random.shuffle! -``` - -```@meta -DocTestSetup = nothing -``` diff --git a/codex/stdlib/serialization.md b/codex/stdlib/serialization.md deleted file mode 100644 index c01ead7..0000000 --- a/codex/stdlib/serialization.md +++ /dev/null @@ -1,7 +0,0 @@ -# Serialization - -```@docs -Serialization.serialize -Serialization.deserialize -Serialization.writeheader -``` diff --git a/codex/stdlib/sharedarrays.md b/codex/stdlib/sharedarrays.md deleted file mode 100644 index bac1cd0..0000000 --- a/codex/stdlib/sharedarrays.md +++ /dev/null @@ -1,9 +0,0 @@ -# Shared Arrays - -```@docs -SharedArrays.SharedArray -SharedArrays.procs(::SharedArray) -SharedArrays.sdata -SharedArrays.indexpids -SharedArrays.localindices -``` diff --git a/codex/stdlib/sparsearrays.md b/codex/stdlib/sparsearrays.md deleted file mode 100644 index af1be79..0000000 --- a/codex/stdlib/sparsearrays.md +++ /dev/null @@ -1,228 +0,0 @@ -# Sparse Arrays - -```@meta -DocTestSetup = :(using SparseArrays, LinearAlgebra) -``` - -Julia has support for sparse vectors and [sparse matrices](https://en.wikipedia.org/wiki/Sparse_matrix) -in the `SparseArrays` stdlib module. Sparse arrays are arrays that contain enough zeros -that storing them in a special data structure leads to savings in space and execution time, -compared to dense arrays. - -## [Compressed Sparse Column (CSC) Sparse Matrix Storage](@id man-csc) - -In Julia, sparse matrices are stored in the [Compressed Sparse Column (CSC) format](https://en.wikipedia.org/wiki/Sparse_matrix#Compressed_sparse_column_.28CSC_or_CCS.29). -Julia sparse matrices have the type [`SparseMatrixCSC{Tv,Ti}`](@ref), where `Tv` is the -type of the stored values, and `Ti` is the integer type for storing column pointers and -row indices. The internal representation of `SparseMatrixCSC` is as follows: - -```julia -struct SparseMatrixCSC{Tv,Ti<:Integer} <: AbstractSparseMatrix{Tv,Ti} - m::Int # Number of rows - n::Int # Number of columns - colptr::Vector{Ti} # Column i is in colptr[i]:(colptr[i+1]-1) - rowval::Vector{Ti} # Row indices of stored values - nzval::Vector{Tv} # Stored values, typically nonzeros -end -``` - -The compressed sparse column storage makes it easy and quick to access the elements in the column -of a sparse matrix, whereas accessing the sparse matrix by rows is considerably slower. Operations -such as insertion of previously unstored entries one at a time in the CSC structure tend to be slow. This is -because all elements of the sparse matrix that are beyond the point of insertion have to be moved -one place over. - -All operations on sparse matrices are carefully implemented to exploit the CSC data structure -for performance, and to avoid expensive operations. - -If you have data in CSC format from a different application or library, and wish to import it -in Julia, make sure that you use 1-based indexing. The row indices in every column need to be -sorted. If your `SparseMatrixCSC` object contains unsorted row indices, one quick way to sort -them is by doing a double transpose. - -In some applications, it is convenient to store explicit zero values in a `SparseMatrixCSC`. These -*are* accepted by functions in `Base` (but there is no guarantee that they will be preserved in -mutating operations). Such explicitly stored zeros are treated as structural nonzeros by many -routines. The [`nnz`](@ref) function returns the number of elements explicitly stored in the -sparse data structure, including structural nonzeros. In order to count the exact number of -numerical nonzeros, use [`count(!iszero, x)`](@ref), which inspects every stored element of a sparse -matrix. [`dropzeros`](@ref), and the in-place [`dropzeros!`](@ref), can be used to -remove stored zeros from the sparse matrix. - -```jldoctest -julia> A = sparse([1, 2, 3], [1, 2, 3], [0, 2, 0]) -3×3 SparseMatrixCSC{Int64,Int64} with 3 stored entries: - [1, 1] = 0 - [2, 2] = 2 - [3, 3] = 0 - -julia> dropzeros(A) -3×3 SparseMatrixCSC{Int64,Int64} with 1 stored entry: - [2, 2] = 2 -``` - -## Sparse Vector Storage - -Sparse vectors are stored in a close analog to compressed sparse column format for sparse -matrices. In Julia, sparse vectors have the type [`SparseVector{Tv,Ti}`](@ref) where `Tv` -is the type of the stored values and `Ti` the integer type for the indices. The internal -representation is as follows: - -```julia -struct SparseVector{Tv,Ti<:Integer} <: AbstractSparseVector{Tv,Ti} - n::Int # Length of the sparse vector - nzind::Vector{Ti} # Indices of stored values - nzval::Vector{Tv} # Stored values, typically nonzeros -end -``` - -As for [`SparseMatrixCSC`](@ref), the `SparseVector` type can also contain explicitly -stored zeros. (See [Sparse Matrix Storage](@ref man-csc).). - -## Sparse Vector and Matrix Constructors - -The simplest way to create a sparse array is to use a function equivalent to the [`zeros`](@ref) -function that Julia provides for working with dense arrays. To produce a -sparse array instead, you can use the same name with an `sp` prefix: - -```jldoctest -julia> spzeros(3) -3-element SparseVector{Float64,Int64} with 0 stored entries -``` - -The [`sparse`](@ref) function is often a handy way to construct sparse arrays. For -example, to construct a sparse matrix we can input a vector `I` of row indices, a vector -`J` of column indices, and a vector `V` of stored values (this is also known as the -[COO (coordinate) format](https://en.wikipedia.org/wiki/Sparse_matrix#Coordinate_list_.28COO.29)). -`sparse(I,J,V)` then constructs a sparse matrix such that `S[I[k], J[k]] = V[k]`. The -equivalent sparse vector constructor is [`sparsevec`](@ref), which takes the (row) index -vector `I` and the vector `V` with the stored values and constructs a sparse vector `R` -such that `R[I[k]] = V[k]`. - -```jldoctest sparse_function -julia> I = [1, 4, 3, 5]; J = [4, 7, 18, 9]; V = [1, 2, -5, 3]; - -julia> S = sparse(I,J,V) -5×18 SparseMatrixCSC{Int64,Int64} with 4 stored entries: - [1 , 4] = 1 - [4 , 7] = 2 - [5 , 9] = 3 - [3 , 18] = -5 - -julia> R = sparsevec(I,V) -5-element SparseVector{Int64,Int64} with 4 stored entries: - [1] = 1 - [3] = -5 - [4] = 2 - [5] = 3 -``` - -The inverse of the [`sparse`](@ref) and [`sparsevec`](@ref) functions is -[`findnz`](@ref), which retrieves the inputs used to create the sparse array. -[`findall(!iszero, x)`](@ref) returns the cartesian indices of non-zero entries in `x` -(including stored entries equal to zero). - -```jldoctest sparse_function -julia> findnz(S) -([1, 4, 5, 3], [4, 7, 9, 18], [1, 2, 3, -5]) - -julia> findall(!iszero, S) -4-element Array{CartesianIndex{2},1}: - CartesianIndex(1, 4) - CartesianIndex(4, 7) - CartesianIndex(5, 9) - CartesianIndex(3, 18) - -julia> findnz(R) -([1, 3, 4, 5], [1, -5, 2, 3]) - -julia> findall(!iszero, R) -4-element Array{Int64,1}: - 1 - 3 - 4 - 5 -``` - -Another way to create a sparse array is to convert a dense array into a sparse array using -the [`sparse`](@ref) function: - -```jldoctest -julia> sparse(Matrix(1.0I, 5, 5)) -5×5 SparseMatrixCSC{Float64,Int64} with 5 stored entries: - [1, 1] = 1.0 - [2, 2] = 1.0 - [3, 3] = 1.0 - [4, 4] = 1.0 - [5, 5] = 1.0 - -julia> sparse([1.0, 0.0, 1.0]) -3-element SparseVector{Float64,Int64} with 2 stored entries: - [1] = 1.0 - [3] = 1.0 -``` - -You can go in the other direction using the [`Array`](@ref) constructor. The [`issparse`](@ref) -function can be used to query if a matrix is sparse. - -```jldoctest -julia> issparse(spzeros(5)) -true -``` - -## Sparse matrix operations - -Arithmetic operations on sparse matrices also work as they do on dense matrices. Indexing of, -assignment into, and concatenation of sparse matrices work in the same way as dense matrices. -Indexing operations, especially assignment, are expensive, when carried out one element at a time. -In many cases it may be better to convert the sparse matrix into `(I,J,V)` format using [`findnz`](@ref), -manipulate the values or the structure in the dense vectors `(I,J,V)`, and then reconstruct -the sparse matrix. - -## Correspondence of dense and sparse methods - -The following table gives a correspondence between built-in methods on sparse matrices and their -corresponding methods on dense matrix types. In general, methods that generate sparse matrices -differ from their dense counterparts in that the resulting matrix follows the same sparsity pattern -as a given sparse matrix `S`, or that the resulting sparse matrix has density `d`, i.e. each matrix -element has a probability `d` of being non-zero. - -Details can be found in the [Sparse Vectors and Matrices](@ref stdlib-sparse-arrays) -section of the standard library reference. - -| Sparse | Dense | Description | -|:-------------------------- |:---------------------- |:--------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [`spzeros(m,n)`](@ref) | [`zeros(m,n)`](@ref) | Creates a *m*-by-*n* matrix of zeros. ([`spzeros(m,n)`](@ref) is empty.) | -| [`sparse(I, n, n)`](@ref) | [`Matrix(I,n,n)`](@ref)| Creates a *n*-by-*n* identity matrix. | -| [`Array(S)`](@ref) | [`sparse(A)`](@ref) | Interconverts between dense and sparse formats. | -| [`sprand(m,n,d)`](@ref) | [`rand(m,n)`](@ref) | Creates a *m*-by-*n* random matrix (of density *d*) with iid non-zero elements distributed uniformly on the half-open interval ``[0, 1)``. | -| [`sprandn(m,n,d)`](@ref) | [`randn(m,n)`](@ref) | Creates a *m*-by-*n* random matrix (of density *d*) with iid non-zero elements distributed according to the standard normal (Gaussian) distribution. | -| [`sprandn(m,n,d,X)`](@ref) | [`randn(m,n,X)`](@ref) | Creates a *m*-by-*n* random matrix (of density *d*) with iid non-zero elements distributed according to the *X* distribution. (Requires the `Distributions` package.) | - -# [Sparse Arrays](@id stdlib-sparse-arrays) - -```@docs -SparseArrays.SparseVector -SparseArrays.SparseMatrixCSC -SparseArrays.sparse -SparseArrays.sparsevec -SparseArrays.issparse -SparseArrays.nnz -SparseArrays.findnz -SparseArrays.spzeros -SparseArrays.spdiagm -SparseArrays.blockdiag -SparseArrays.sprand -SparseArrays.sprandn -SparseArrays.nonzeros -SparseArrays.rowvals -SparseArrays.nzrange -SparseArrays.dropzeros! -SparseArrays.dropzeros -SparseArrays.permute -permute!{Tv, Ti, Tp <: Integer, Tq <: Integer}(::SparseMatrixCSC{Tv,Ti}, ::SparseMatrixCSC{Tv,Ti}, ::AbstractArray{Tp,1}, ::AbstractArray{Tq,1}) -``` - -```@meta -DocTestSetup = nothing -``` diff --git a/codex/stdlib/test.md b/codex/stdlib/test.md deleted file mode 100644 index 4211071..0000000 --- a/codex/stdlib/test.md +++ /dev/null @@ -1,269 +0,0 @@ -# Unit Testing - -```@meta -DocTestSetup = :(using Test) -``` - -## Testing Base Julia - -Julia is under rapid development and has an extensive test suite to verify functionality across -multiple platforms. If you build Julia from source, you can run this test suite with `make test`. -In a binary install, you can run the test suite using `Base.runtests()`. - -```@docs -Base.runtests -``` - -## Basic Unit Tests - -The `Test` module provides simple *unit testing* functionality. Unit testing is a way to -see if your code is correct by checking that the results are what you expect. It can be helpful -to ensure your code still works after you make changes, and can be used when developing as a way -of specifying the behaviors your code should have when complete. - -Simple unit testing can be performed with the `@test` and `@test_throws` macros: - -```@docs -Test.@test -Test.@test_throws -``` - -For example, suppose we want to check our new function `foo(x)` works as expected: - -```jldoctest testfoo -julia> using Test - -julia> foo(x) = length(x)^2 -foo (generic function with 1 method) -``` - -If the condition is true, a `Pass` is returned: - -```jldoctest testfoo -julia> @test foo("bar") == 9 -Test Passed - -julia> @test foo("fizz") >= 10 -Test Passed -``` - -If the condition is false, then a `Fail` is returned and an exception is thrown: - -```jldoctest testfoo -julia> @test foo("f") == 20 -Test Failed at none:1 - Expression: foo("f") == 20 - Evaluated: 1 == 20 -ERROR: There was an error during testing -``` - -If the condition could not be evaluated because an exception was thrown, which occurs in this -case because `length` is not defined for symbols, an `Error` object is returned and an exception -is thrown: - -```julia-repl -julia> @test foo(:cat) == 1 -Error During Test - Test threw an exception of type MethodError - Expression: foo(:cat) == 1 - MethodError: no method matching length(::Symbol) - Closest candidates are: - length(::SimpleVector) at essentials.jl:256 - length(::Base.MethodList) at reflection.jl:521 - length(::MethodTable) at reflection.jl:597 - ... - Stacktrace: - [...] -ERROR: There was an error during testing -``` - -If we expect that evaluating an expression *should* throw an exception, then we can use `@test_throws` -to check that this occurs: - -```jldoctest testfoo -julia> @test_throws MethodError foo(:cat) -Test Passed - Thrown: MethodError -``` - -## Working with Test Sets - -Typically a large number of tests are used to make sure functions work correctly over a range -of inputs. In the event a test fails, the default behavior is to throw an exception immediately. -However, it is normally preferable to run the rest of the tests first to get a better picture -of how many errors there are in the code being tested. - -The `@testset` macro can be used to group tests into *sets*. All the tests in a test set will -be run, and at the end of the test set a summary will be printed. If any of the tests failed, -or could not be evaluated due to an error, the test set will then throw a `TestSetException`. - -```@docs -Test.@testset -``` - -We can put our tests for the `foo(x)` function in a test set: - -```jldoctest testfoo -julia> @testset "Foo Tests" begin - @test foo("a") == 1 - @test foo("ab") == 4 - @test foo("abc") == 9 - end; -Test Summary: | Pass Total -Foo Tests | 3 3 -``` - -Test sets can also be nested: - -```jldoctest testfoo -julia> @testset "Foo Tests" begin - @testset "Animals" begin - @test foo("cat") == 9 - @test foo("dog") == foo("cat") - end - @testset "Arrays $i" for i in 1:3 - @test foo(zeros(i)) == i^2 - @test foo(fill(1.0, i)) == i^2 - end - end; -Test Summary: | Pass Total -Foo Tests | 8 8 -``` - -In the event that a nested test set has no failures, as happened here, it will be hidden in the -summary. If we do have a test failure, only the details for the failed test sets will be shown: - -```julia-repl -julia> @testset "Foo Tests" begin - @testset "Animals" begin - @testset "Felines" begin - @test foo("cat") == 9 - end - @testset "Canines" begin - @test foo("dog") == 9 - end - end - @testset "Arrays" begin - @test foo(zeros(2)) == 4 - @test foo(fill(1.0, 4)) == 15 - end - end - -Arrays: Test Failed - Expression: foo(fill(1.0, 4)) == 15 - Evaluated: 16 == 15 -[...] -Test Summary: | Pass Fail Total -Foo Tests | 3 1 4 - Animals | 2 2 - Arrays | 1 1 2 -ERROR: Some tests did not pass: 3 passed, 1 failed, 0 errored, 0 broken. -``` - -## Other Test Macros - -As calculations on floating-point values can be imprecise, you can perform approximate equality -checks using either `@test a ≈ b` (where `≈`, typed via tab completion of `\approx`, is the -[`isapprox`](@ref) function) or use [`isapprox`](@ref) directly. - -```jldoctest -julia> @test 1 ≈ 0.999999999 -Test Passed - -julia> @test 1 ≈ 0.999999 -Test Failed at none:1 - Expression: 1 ≈ 0.999999 - Evaluated: 1 ≈ 0.999999 -ERROR: There was an error during testing -``` - -```@docs -Test.@inferred -Test.@test_logs -Test.@test_deprecated -Test.@test_warn -Test.@test_nowarn -``` - -## Broken Tests - -If a test fails consistently it can be changed to use the `@test_broken` macro. This will denote -the test as `Broken` if the test continues to fail and alerts the user via an `Error` if the test -succeeds. - -```@docs -Test.@test_broken -``` - -`@test_skip` is also available to skip a test without evaluation, but counting the skipped test -in the test set reporting. The test will not run but gives a `Broken` `Result`. - -```@docs -Test.@test_skip -``` - -## Creating Custom `AbstractTestSet` Types - -Packages can create their own `AbstractTestSet` subtypes by implementing the `record` and `finish` -methods. The subtype should have a one-argument constructor taking a description string, with -any options passed in as keyword arguments. - -```@docs -Test.record -Test.finish -``` - -`Test` takes responsibility for maintaining a stack of nested testsets as they are executed, -but any result accumulation is the responsibility of the `AbstractTestSet` subtype. You can access -this stack with the `get_testset` and `get_testset_depth` methods. Note that these functions are -not exported. - -```@docs -Test.get_testset -Test.get_testset_depth -``` - -`Test` also makes sure that nested `@testset` invocations use the same `AbstractTestSet` -subtype as their parent unless it is set explicitly. It does not propagate any properties of the -testset. Option inheritance behavior can be implemented by packages using the stack infrastructure -that `Test` provides. - -Defining a basic `AbstractTestSet` subtype might look like: - -```julia -import Test: record, finish -using Test: AbstractTestSet, Result, Pass, Fail, Error -using Test: get_testset_depth, get_testset -struct CustomTestSet <: Test.AbstractTestSet - description::AbstractString - foo::Int - results::Vector - # constructor takes a description string and options keyword arguments - CustomTestSet(desc; foo=1) = new(desc, foo, []) -end - -record(ts::CustomTestSet, child::AbstractTestSet) = push!(ts.results, child) -record(ts::CustomTestSet, res::Result) = push!(ts.results, res) -function finish(ts::CustomTestSet) - # just record if we're not the top-level parent - if get_testset_depth() > 0 - record(get_testset(), ts) - end - ts -end -``` - -And using that testset looks like: - -```julia -@testset CustomTestSet foo=4 "custom testset inner 2" begin - # this testset should inherit the type, but not the argument. - @testset "custom testset inner" begin - @test true - end -end -``` - -```@meta -DocTestSetup = nothing -``` diff --git a/codex/stdlib/unicode.md b/codex/stdlib/unicode.md deleted file mode 100644 index 474629d..0000000 --- a/codex/stdlib/unicode.md +++ /dev/null @@ -1,15 +0,0 @@ -# Unicode - -```@meta -DocTestSetup = :(using Unicode) -``` - -```@docs -Unicode.isassigned -Unicode.normalize -Unicode.graphemes -``` - -```@meta -DocTestSetup = nothing -``` diff --git a/src/devdocs/object.md b/src/devdocs/object.md index 49d1e46..cf9223f 100644 --- a/src/devdocs/object.md +++ b/src/devdocs/object.md @@ -1,6 +1,6 @@ # Memory layout of Julia Objects -## Object layout (`jl_value_t`) +## Object layout (jl_value_t) The `jl_value_t` struct is the name for a block of memory owned by the Julia Garbage Collector, representing the data associated with a Julia object in memory. Absent any type information, it diff --git a/src/stdlib/base64.md b/src/stdlib/base64.md deleted file mode 100644 index b179de0..0000000 --- a/src/stdlib/base64.md +++ /dev/null @@ -1,17 +0,0 @@ -# Base64 - -```@meta -DocTestSetup = :(using Base64) -``` - -```@docs -Base64.Base64EncodePipe -Base64.base64encode -Base64.Base64DecodePipe -Base64.base64decode -Base64.stringmime -``` - -```@meta -DocTestSetup = nothing -``` diff --git a/src/stdlib/crc32c.md b/src/stdlib/crc32c.md deleted file mode 100644 index 1304709..0000000 --- a/src/stdlib/crc32c.md +++ /dev/null @@ -1,6 +0,0 @@ -# CRC32c - -```@docs -CRC32c.crc32c -CRC32c.crc32c(::IO, ::Integer, ::UInt32) -``` diff --git a/src/stdlib/dates.md b/src/stdlib/dates.md deleted file mode 100644 index dc2e7bd..0000000 --- a/src/stdlib/dates.md +++ /dev/null @@ -1,820 +0,0 @@ -# Dates - -```@meta -DocTestSetup = :(using Dates) -``` - -The `Dates` module provides two types for working with dates: [`Date`](@ref) and [`DateTime`](@ref), -representing day and millisecond precision, respectively; both are subtypes of the abstract [`TimeType`](@ref). -The motivation for distinct types is simple: some operations are much simpler, both in terms of -code and mental reasoning, when the complexities of greater precision don't have to be dealt with. -For example, since the [`Date`](@ref) type only resolves to the precision of a single date (i.e. -no hours, minutes, or seconds), normal considerations for time zones, daylight savings/summer -time, and leap seconds are unnecessary and avoided. - -Both [`Date`](@ref) and [`DateTime`](@ref) are basically immutable [`Int64`](@ref) wrappers. -The single `instant` field of either type is actually a `UTInstant{P}` type, which -represents a continuously increasing machine timeline based on the UT second [^1]. The -[`DateTime`](@ref) type is not aware of time zones (*naive*, in Python parlance), -analogous to a *LocalDateTime* in Java 8. Additional time zone functionality -can be added through the [TimeZones.jl package](https://github.com/JuliaTime/TimeZones.jl/), which -compiles the [IANA time zone database](http://www.iana.org/time-zones). Both [`Date`](@ref) and -[`DateTime`](@ref) are based on the [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) standard, which follows the proleptic Gregorian calendar. -One note is that the ISO 8601 standard is particular about BC/BCE dates. In general, the last -day of the BC/BCE era, 1-12-31 BC/BCE, was followed by 1-1-1 AD/CE, thus no year zero exists. -The ISO standard, however, states that 1 BC/BCE is year zero, so `0000-12-31` is the day before -`0001-01-01`, and year `-0001` (yes, negative one for the year) is 2 BC/BCE, year `-0002` is 3 -BC/BCE, etc. - -[^1]: - The notion of the UT second is actually quite fundamental. There are basically two different notions - of time generally accepted, one based on the physical rotation of the earth (one full rotation - = 1 day), the other based on the SI second (a fixed, constant value). These are radically different! - Think about it, a "UT second", as defined relative to the rotation of the earth, may have a different - absolute length depending on the day! Anyway, the fact that [`Date`](@ref) and [`DateTime`](@ref) - are based on UT seconds is a simplifying, yet honest assumption so that things like leap seconds - and all their complexity can be avoided. This basis of time is formally called [UT](https://en.wikipedia.org/wiki/Universal_Time) - or UT1. Basing types on the UT second basically means that every minute has 60 seconds and every - day has 24 hours and leads to more natural calculations when working with calendar dates. - -## Constructors - -[`Date`](@ref) and [`DateTime`](@ref) types can be constructed by integer or [`Period`](@ref) -types, by parsing, or through adjusters (more on those later): - -```jldoctest -julia> DateTime(2013) -2013-01-01T00:00:00 - -julia> DateTime(2013,7) -2013-07-01T00:00:00 - -julia> DateTime(2013,7,1) -2013-07-01T00:00:00 - -julia> DateTime(2013,7,1,12) -2013-07-01T12:00:00 - -julia> DateTime(2013,7,1,12,30) -2013-07-01T12:30:00 - -julia> DateTime(2013,7,1,12,30,59) -2013-07-01T12:30:59 - -julia> DateTime(2013,7,1,12,30,59,1) -2013-07-01T12:30:59.001 - -julia> Date(2013) -2013-01-01 - -julia> Date(2013,7) -2013-07-01 - -julia> Date(2013,7,1) -2013-07-01 - -julia> Date(Dates.Year(2013),Dates.Month(7),Dates.Day(1)) -2013-07-01 - -julia> Date(Dates.Month(7),Dates.Year(2013)) -2013-07-01 -``` - -[`Date`](@ref) or [`DateTime`](@ref) parsing is accomplished by the use of format strings. Format -strings work by the notion of defining *delimited* or *fixed-width* "slots" that contain a period -to parse and passing the text to parse and format string to a [`Date`](@ref) or [`DateTime`](@ref) -constructor, of the form `Date("2015-01-01","y-m-d")` or `DateTime("20150101","yyyymmdd")`. - -Delimited slots are marked by specifying the delimiter the parser should expect between two subsequent -periods; so `"y-m-d"` lets the parser know that between the first and second slots in a date string -like `"2014-07-16"`, it should find the `-` character. The `y`, `m`, and `d` characters let the -parser know which periods to parse in each slot. - -Fixed-width slots are specified by repeating the period character the number of times corresponding -to the width with no delimiter between characters. So `"yyyymmdd"` would correspond to a date -string like `"20140716"`. The parser distinguishes a fixed-width slot by the absence of a delimiter, -noting the transition `"yyyymm"` from one period character to the next. - -Support for text-form month parsing is also supported through the `u` and `U` characters, for -abbreviated and full-length month names, respectively. By default, only English month names are -supported, so `u` corresponds to "Jan", "Feb", "Mar", etc. And `U` corresponds to "January", "February", -"March", etc. Similar to other name=>value mapping functions [`dayname`](@ref) and [`monthname`](@ref), -custom locales can be loaded by passing in the `locale=>Dict{String,Int}` mapping to the `MONTHTOVALUEABBR` -and `MONTHTOVALUE` dicts for abbreviated and full-name month names, respectively. - -One note on parsing performance: using the `Date(date_string,format_string)` function is fine -if only called a few times. If there are many similarly formatted date strings to parse however, -it is much more efficient to first create a [`Dates.DateFormat`](@ref), and pass it instead of -a raw format string. - -```jldoctest -julia> df = DateFormat("y-m-d"); - -julia> dt = Date("2015-01-01",df) -2015-01-01 - -julia> dt2 = Date("2015-01-02",df) -2015-01-02 -``` - -You can also use the `dateformat""` string macro. This macro creates the `DateFormat` object once when the macro is expanded and uses the same `DateFormat` object even if a code snippet is run multiple times. - -```jldoctest -julia> for i = 1:10^5 - Date("2015-01-01", dateformat"y-m-d") - end -``` - -A full suite of parsing and formatting tests and examples is available in [`stdlib/Dates/test/io.jl`](https://github.com/JuliaLang/julia/blob/master/stdlib/Dates/test/io.jl). - -## Durations/Comparisons - -Finding the length of time between two [`Date`](@ref) or [`DateTime`](@ref) is straightforward -given their underlying representation as `UTInstant{Day}` and `UTInstant{Millisecond}`, respectively. -The difference between [`Date`](@ref) is returned in the number of [`Day`](@ref), and [`DateTime`](@ref) -in the number of [`Millisecond`](@ref). Similarly, comparing [`TimeType`](@ref) is a simple matter -of comparing the underlying machine instants (which in turn compares the internal [`Int64`](@ref) values). - -```jldoctest -julia> dt = Date(2012,2,29) -2012-02-29 - -julia> dt2 = Date(2000,2,1) -2000-02-01 - -julia> dump(dt) -Date - instant: Dates.UTInstant{Day} - periods: Day - value: Int64 734562 - -julia> dump(dt2) -Date - instant: Dates.UTInstant{Day} - periods: Day - value: Int64 730151 - -julia> dt > dt2 -true - -julia> dt != dt2 -true - -julia> dt + dt2 -ERROR: MethodError: no method matching +(::Date, ::Date) -[...] - -julia> dt * dt2 -ERROR: MethodError: no method matching *(::Date, ::Date) -[...] - -julia> dt / dt2 -ERROR: MethodError: no method matching /(::Date, ::Date) - -julia> dt - dt2 -4411 days - -julia> dt2 - dt --4411 days - -julia> dt = DateTime(2012,2,29) -2012-02-29T00:00:00 - -julia> dt2 = DateTime(2000,2,1) -2000-02-01T00:00:00 - -julia> dt - dt2 -381110400000 milliseconds -``` - -## Accessor Functions - -Because the [`Date`](@ref) and [`DateTime`](@ref) types are stored as single [`Int64`](@ref) values, date -parts or fields can be retrieved through accessor functions. The lowercase accessors return the -field as an integer: - -```jldoctest tdate -julia> t = Date(2014, 1, 31) -2014-01-31 - -julia> Dates.year(t) -2014 - -julia> Dates.month(t) -1 - -julia> Dates.week(t) -5 - -julia> Dates.day(t) -31 -``` - -While propercase return the same value in the corresponding [`Period`](@ref) type: - -```jldoctest tdate -julia> Dates.Year(t) -2014 years - -julia> Dates.Day(t) -31 days -``` - -Compound methods are provided, as they provide a measure of efficiency if multiple fields are -needed at the same time: - -```jldoctest tdate -julia> Dates.yearmonth(t) -(2014, 1) - -julia> Dates.monthday(t) -(1, 31) - -julia> Dates.yearmonthday(t) -(2014, 1, 31) -``` - -One may also access the underlying `UTInstant` or integer value: - -```jldoctest tdate -julia> dump(t) -Date - instant: Dates.UTInstant{Day} - periods: Day - value: Int64 735264 - -julia> t.instant -Dates.UTInstant{Day}(735264 days) - -julia> Dates.value(t) -735264 -``` - -## Query Functions - -Query functions provide calendrical information about a [`TimeType`](@ref). They include information -about the day of the week: - -```jldoctest tdate2 -julia> t = Date(2014, 1, 31) -2014-01-31 - -julia> Dates.dayofweek(t) -5 - -julia> Dates.dayname(t) -"Friday" - -julia> Dates.dayofweekofmonth(t) # 5th Friday of January -5 -``` - -Month of the year: - -```jldoctest tdate2 -julia> Dates.monthname(t) -"January" - -julia> Dates.daysinmonth(t) -31 -``` - -As well as information about the [`TimeType`](@ref)'s year and quarter: - -```jldoctest tdate2 -julia> Dates.isleapyear(t) -false - -julia> Dates.dayofyear(t) -31 - -julia> Dates.quarterofyear(t) -1 - -julia> Dates.dayofquarter(t) -31 -``` - -The [`dayname`](@ref) and [`monthname`](@ref) methods can also take an optional `locale` keyword -that can be used to return the name of the day or month of the year for other languages/locales. -There are also versions of these functions returning the abbreviated names, namely -[`dayabbr`](@ref) and [`monthabbr`](@ref). -First the mapping is loaded into the `LOCALES` variable: - -```jldoctest tdate2 -julia> french_months = ["janvier", "février", "mars", "avril", "mai", "juin", - "juillet", "août", "septembre", "octobre", "novembre", "décembre"]; - -julia> french_monts_abbrev = ["janv","févr","mars","avril","mai","juin", - "juil","août","sept","oct","nov","déc"]; - -julia> french_days = ["lundi","mardi","mercredi","jeudi","vendredi","samedi","dimanche"]; - -julia> Dates.LOCALES["french"] = Dates.DateLocale(french_months, french_monts_abbrev, french_days, [""]); -``` - - The above mentioned functions can then be used to perform the queries: - -```jldoctest tdate2 -julia> Dates.dayname(t;locale="french") -"vendredi" - -julia> Dates.monthname(t;locale="french") -"janvier" - -julia> Dates.monthabbr(t;locale="french") -"janv" -``` - -Since the abbreviated versions of the days are not loaded, trying to use the -function `dayabbr` will error. - -```jldoctest tdate2 -julia> Dates.dayabbr(t;locale="french") -ERROR: BoundsError: attempt to access 1-element Array{String,1} at index [5] -Stacktrace: -[...] -``` - - -## TimeType-Period Arithmetic - -It's good practice when using any language/date framework to be familiar with how date-period -arithmetic is handled as there are some [tricky issues](https://codeblog.jonskeet.uk/2010/12/01/the-joys-of-date-time-arithmetic/) -to deal with (though much less so for day-precision types). - -The `Dates` module approach tries to follow the simple principle of trying to change as -little as possible when doing [`Period`](@ref) arithmetic. This approach is also often known as -*calendrical* arithmetic or what you would probably guess if someone were to ask you the same -calculation in a conversation. Why all the fuss about this? Let's take a classic example: add -1 month to January 31st, 2014. What's the answer? Javascript will say [March 3](http://www.markhneedham.com/blog/2009/01/07/javascript-add-a-month-to-a-date/) -(assumes 31 days). PHP says [March 2](https://stackoverflow.com/questions/5760262/php-adding-months-to-a-date-while-not-exceeding-the-last-day-of-the-month) -(assumes 30 days). The fact is, there is no right answer. In the `Dates` module, it gives -the result of February 28th. How does it figure that out? I like to think of the classic 7-7-7 -gambling game in casinos. - -Now just imagine that instead of 7-7-7, the slots are Year-Month-Day, or in our example, 2014-01-31. -When you ask to add 1 month to this date, the month slot is incremented, so now we have 2014-02-31. -Then the day number is checked if it is greater than the last valid day of the new month; if it -is (as in the case above), the day number is adjusted down to the last valid day (28). What are -the ramifications with this approach? Go ahead and add another month to our date, `2014-02-28 + Month(1) == 2014-03-28`. -What? Were you expecting the last day of March? Nope, sorry, remember the 7-7-7 slots. As few -slots as possible are going to change, so we first increment the month slot by 1, 2014-03-28, -and boom, we're done because that's a valid date. On the other hand, if we were to add 2 months -to our original date, 2014-01-31, then we end up with 2014-03-31, as expected. The other ramification -of this approach is a loss in associativity when a specific ordering is forced (i.e. adding things -in different orders results in different outcomes). For example: - -```jldoctest -julia> (Date(2014,1,29)+Dates.Day(1)) + Dates.Month(1) -2014-02-28 - -julia> (Date(2014,1,29)+Dates.Month(1)) + Dates.Day(1) -2014-03-01 -``` - -What's going on there? In the first line, we're adding 1 day to January 29th, which results in -2014-01-30; then we add 1 month, so we get 2014-02-30, which then adjusts down to 2014-02-28. -In the second example, we add 1 month *first*, where we get 2014-02-29, which adjusts down to -2014-02-28, and *then* add 1 day, which results in 2014-03-01. One design principle that helps -in this case is that, in the presence of multiple Periods, the operations will be ordered by the -Periods' *types*, not their value or positional order; this means `Year` will always be added -first, then `Month`, then `Week`, etc. Hence the following *does* result in associativity and -Just Works: - -```jldoctest -julia> Date(2014,1,29) + Dates.Day(1) + Dates.Month(1) -2014-03-01 - -julia> Date(2014,1,29) + Dates.Month(1) + Dates.Day(1) -2014-03-01 -``` - -Tricky? Perhaps. What is an innocent `Dates` user to do? The bottom line is to be aware -that explicitly forcing a certain associativity, when dealing with months, may lead to some unexpected -results, but otherwise, everything should work as expected. Thankfully, that's pretty much the -extent of the odd cases in date-period arithmetic when dealing with time in UT (avoiding the "joys" -of dealing with daylight savings, leap seconds, etc.). - -As a bonus, all period arithmetic objects work directly with ranges: - -```jldoctest -julia> dr = Date(2014,1,29):Day(1):Date(2014,2,3) -2014-01-29:1 day:2014-02-03 - -julia> collect(dr) -6-element Array{Date,1}: - 2014-01-29 - 2014-01-30 - 2014-01-31 - 2014-02-01 - 2014-02-02 - 2014-02-03 - -julia> dr = Date(2014,1,29):Dates.Month(1):Date(2014,07,29) -2014-01-29:1 month:2014-07-29 - -julia> collect(dr) -7-element Array{Date,1}: - 2014-01-29 - 2014-02-28 - 2014-03-29 - 2014-04-29 - 2014-05-29 - 2014-06-29 - 2014-07-29 -``` - -## Adjuster Functions - -As convenient as date-period arithmetic is, often the kinds of calculations needed on dates -take on a *calendrical* or *temporal* nature rather than a fixed number of periods. Holidays are -a perfect example; most follow rules such as "Memorial Day = Last Monday of May", or "Thanksgiving -= 4th Thursday of November". These kinds of temporal expressions deal with rules relative to the -calendar, like first or last of the month, next Tuesday, or the first and third Wednesdays, etc. - -The `Dates` module provides the *adjuster* API through several convenient methods that -aid in simply and succinctly expressing temporal rules. The first group of adjuster methods deal -with the first and last of weeks, months, quarters, and years. They each take a single [`TimeType`](@ref) -as input and return or *adjust to* the first or last of the desired period relative to the input. - -```jldoctest -julia> Dates.firstdayofweek(Date(2014,7,16)) # Adjusts the input to the Monday of the input's week -2014-07-14 - -julia> Dates.lastdayofmonth(Date(2014,7,16)) # Adjusts to the last day of the input's month -2014-07-31 - -julia> Dates.lastdayofquarter(Date(2014,7,16)) # Adjusts to the last day of the input's quarter -2014-09-30 -``` - -The next two higher-order methods, [`tonext`](@ref), and [`toprev`](@ref), generalize working -with temporal expressions by taking a `DateFunction` as first argument, along with a starting -[`TimeType`](@ref). A `DateFunction` is just a function, usually anonymous, that takes a single -[`TimeType`](@ref) as input and returns a [`Bool`](@ref), `true` indicating a satisfied -adjustment criterion. -For example: - -```jldoctest -julia> istuesday = x->Dates.dayofweek(x) == Dates.Tuesday; # Returns true if the day of the week of x is Tuesday - -julia> Dates.tonext(istuesday, Date(2014,7,13)) # 2014-07-13 is a Sunday -2014-07-15 - -julia> Dates.tonext(Date(2014,7,13), Dates.Tuesday) # Convenience method provided for day of the week adjustments -2014-07-15 -``` - -This is useful with the do-block syntax for more complex temporal expressions: - -```jldoctest -julia> Dates.tonext(Date(2014,7,13)) do x - # Return true on the 4th Thursday of November (Thanksgiving) - Dates.dayofweek(x) == Dates.Thursday && - Dates.dayofweekofmonth(x) == 4 && - Dates.month(x) == Dates.November - end -2014-11-27 -``` - -The [`Base.filter`](@ref) method can be used to obtain all valid dates/moments in a specified -range: - -```jldoctest -# Pittsburgh street cleaning; Every 2nd Tuesday from April to November -# Date range from January 1st, 2014 to January 1st, 2015 -julia> dr = Dates.Date(2014):Day(1):Dates.Date(2015); - -julia> filter(dr) do x - Dates.dayofweek(x) == Dates.Tue && - Dates.April <= Dates.month(x) <= Dates.Nov && - Dates.dayofweekofmonth(x) == 2 - end -8-element Array{Date,1}: - 2014-04-08 - 2014-05-13 - 2014-06-10 - 2014-07-08 - 2014-08-12 - 2014-09-09 - 2014-10-14 - 2014-11-11 -``` - -Additional examples and tests are available in [`stdlib/Dates/test/adjusters.jl`](https://github.com/JuliaLang/julia/blob/master/stdlib/Dates/test/adjusters.jl). - -## Period Types - -Periods are a human view of discrete, sometimes irregular durations of time. Consider 1 month; -it could represent, in days, a value of 28, 29, 30, or 31 depending on the year and month context. -Or a year could represent 365 or 366 days in the case of a leap year. [`Period`](@ref) types are -simple [`Int64`](@ref) wrappers and are constructed by wrapping any `Int64` convertible type, i.e. `Year(1)` -or `Month(3.0)`. Arithmetic between [`Period`](@ref) of the same type behave like integers, and -limited `Period-Real` arithmetic is available. - -```jldoctest -julia> y1 = Dates.Year(1) -1 year - -julia> y2 = Dates.Year(2) -2 years - -julia> y3 = Dates.Year(10) -10 years - -julia> y1 + y2 -3 years - -julia> div(y3,y2) -5 - -julia> y3 - y2 -8 years - -julia> y3 % y2 -0 years - -julia> div(y3,3) # mirrors integer division -3 years -``` - -## Rounding - -[`Date`](@ref) and [`DateTime`](@ref) values can be rounded to a specified resolution (e.g., 1 -month or 15 minutes) with [`floor`](@ref), [`ceil`](@ref), or [`round`](@ref): - -```jldoctest -julia> floor(Date(1985, 8, 16), Dates.Month) -1985-08-01 - -julia> ceil(DateTime(2013, 2, 13, 0, 31, 20), Dates.Minute(15)) -2013-02-13T00:45:00 - -julia> round(DateTime(2016, 8, 6, 20, 15), Dates.Day) -2016-08-07T00:00:00 -``` - -Unlike the numeric [`round`](@ref) method, which breaks ties toward the even number by default, -the [`TimeType`](@ref)[`round`](@ref) method uses the `RoundNearestTiesUp` rounding mode. (It's -difficult to guess what breaking ties to nearest "even" [`TimeType`](@ref) would entail.) Further -details on the available `RoundingMode` s can be found in the [API reference](@ref stdlib-dates-api). - -Rounding should generally behave as expected, but there are a few cases in which the expected -behaviour is not obvious. - -### Rounding Epoch - -In many cases, the resolution specified for rounding (e.g., `Dates.Second(30)`) divides evenly -into the next largest period (in this case, `Dates.Minute(1)`). But rounding behaviour in cases -in which this is not true may lead to confusion. What is the expected result of rounding a [`DateTime`](@ref) -to the nearest 10 hours? - -```jldoctest -julia> round(DateTime(2016, 7, 17, 11, 55), Dates.Hour(10)) -2016-07-17T12:00:00 -``` - -That may seem confusing, given that the hour (12) is not divisible by 10. The reason that `2016-07-17T12:00:00` -was chosen is that it is 17,676,660 hours after `0000-01-01T00:00:00`, and 17,676,660 is divisible -by 10. - -As Julia [`Date`](@ref) and [`DateTime`](@ref) values are represented according to the ISO 8601 -standard, `0000-01-01T00:00:00` was chosen as base (or "rounding epoch") from which to begin the -count of days (and milliseconds) used in rounding calculations. (Note that this differs slightly -from Julia's internal representation of [`Date`](@ref) s using Rata Die notation; but since the -ISO 8601 standard is most visible to the end user, `0000-01-01T00:00:00` was chosen as the rounding -epoch instead of the `0000-12-31T00:00:00` used internally to minimize confusion.) - -The only exception to the use of `0000-01-01T00:00:00` as the rounding epoch is when rounding -to weeks. Rounding to the nearest week will always return a Monday (the first day of the week -as specified by ISO 8601). For this reason, we use `0000-01-03T00:00:00` (the first day of the -first week of year 0000, as defined by ISO 8601) as the base when rounding to a number of weeks. - -Here is a related case in which the expected behaviour is not necessarily obvious: What happens -when we round to the nearest `P(2)`, where `P` is a [`Period`](@ref) type? In some cases (specifically, -when `P <: Dates.TimePeriod`) the answer is clear: - -```jldoctest -julia> round(DateTime(2016, 7, 17, 8, 55, 30), Dates.Hour(2)) -2016-07-17T08:00:00 - -julia> round(DateTime(2016, 7, 17, 8, 55, 30), Dates.Minute(2)) -2016-07-17T08:56:00 -``` - -This seems obvious, because two of each of these periods still divides evenly into the next larger -order period. But in the case of two months (which still divides evenly into one year), the answer -may be surprising: - -```jldoctest -julia> round(DateTime(2016, 7, 17, 8, 55, 30), Dates.Month(2)) -2016-07-01T00:00:00 -``` - -Why round to the first day in July, even though it is month 7 (an odd number)? The key is that -months are 1-indexed (the first month is assigned 1), unlike hours, minutes, seconds, and milliseconds -(the first of which are assigned 0). - -This means that rounding a [`DateTime`](@ref) to an even multiple of seconds, minutes, hours, -or years (because the ISO 8601 specification includes a year zero) will result in a [`DateTime`](@ref) -with an even value in that field, while rounding a [`DateTime`](@ref) to an even multiple of months -will result in the months field having an odd value. Because both months and years may contain -an irregular number of days, whether rounding to an even number of days will result in an even -value in the days field is uncertain. - -See the [API reference](@ref stdlib-dates-api) for additional information -on methods exported from the `Dates` module. - -# [API reference](@id stdlib-dates-api) - -## Dates and Time Types - -```@docs -Dates.Period -Dates.CompoundPeriod -Dates.Instant -Dates.UTInstant -Dates.TimeType -Dates.DateTime -Dates.Date -Dates.Time -``` - -## Dates Functions - -```@docs -Dates.DateTime(::Int64, ::Int64, ::Int64, ::Int64, ::Int64, ::Int64, ::Int64) -Dates.DateTime(::Dates.Period) -Dates.DateTime(::Function, ::Any...) -Dates.DateTime(::Dates.TimeType) -Dates.DateTime(::AbstractString, ::AbstractString) -Dates.format -Dates.DateFormat -Dates.@dateformat_str -Dates.DateTime(::AbstractString, ::Dates.DateFormat) -Dates.Date(::Int64, ::Int64, ::Int64) -Dates.Date(::Dates.Period) -Dates.Date(::Function, ::Any, ::Any, ::Any) -Dates.Date(::Dates.TimeType) -Dates.Date(::AbstractString, ::AbstractString) -Dates.Date(::AbstractString, ::Dates.DateFormat) -Dates.Time(::Int64::Int64, ::Int64, ::Int64, ::Int64, ::Int64) -Dates.Time(::Dates.TimePeriod) -Dates.Time(::Function, ::Any...) -Dates.Time(::Dates.DateTime) -Dates.now() -Dates.now(::Type{Dates.UTC}) -Base.eps -``` - -### Accessor Functions - -```@docs -Dates.year -Dates.month -Dates.week -Dates.day -Dates.hour -Dates.minute -Dates.second -Dates.millisecond -Dates.microsecond -Dates.nanosecond -Dates.Year(::Dates.TimeType) -Dates.Month(::Dates.TimeType) -Dates.Week(::Dates.TimeType) -Dates.Day(::Dates.TimeType) -Dates.Hour(::DateTime) -Dates.Minute(::DateTime) -Dates.Second(::DateTime) -Dates.Millisecond(::DateTime) -Dates.Microsecond(::Dates.Time) -Dates.Nanosecond(::Dates.Time) -Dates.yearmonth -Dates.monthday -Dates.yearmonthday -``` - -### Query Functions - -```@docs -Dates.dayname -Dates.dayabbr -Dates.dayofweek -Dates.dayofmonth -Dates.dayofweekofmonth -Dates.daysofweekinmonth -Dates.monthname -Dates.monthabbr -Dates.daysinmonth -Dates.isleapyear -Dates.dayofyear -Dates.daysinyear -Dates.quarterofyear -Dates.dayofquarter -``` - -### Adjuster Functions - -```@docs -Base.trunc(::Dates.TimeType, ::Type{Dates.Period}) -Dates.firstdayofweek -Dates.lastdayofweek -Dates.firstdayofmonth -Dates.lastdayofmonth -Dates.firstdayofyear -Dates.lastdayofyear -Dates.firstdayofquarter -Dates.lastdayofquarter -Dates.tonext(::Dates.TimeType, ::Int) -Dates.toprev(::Dates.TimeType, ::Int) -Dates.tofirst -Dates.tolast -Dates.tonext(::Function, ::Dates.TimeType) -Dates.toprev(::Function, ::Dates.TimeType) -``` - -### Periods - -```@docs -Dates.Period(::Any) -Dates.CompoundPeriod(::Vector{<:Dates.Period}) -Dates.default -``` - -### Rounding Functions - -`Date` and `DateTime` values can be rounded to a specified resolution (e.g., 1 month or 15 minutes) -with `floor`, `ceil`, or `round`. - -```@docs -Base.floor(::Dates.TimeType, ::Dates.Period) -Base.ceil(::Dates.TimeType, ::Dates.Period) -Base.round(::Dates.TimeType, ::Dates.Period, ::RoundingMode{:NearestTiesUp}) -``` - -Most `Period` values can also be rounded to a specified resolution: - -```@docs -Base.floor(::Dates.ConvertiblePeriod, ::T) where T <: Dates.ConvertiblePeriod -Base.ceil(::Dates.ConvertiblePeriod, ::Dates.ConvertiblePeriod) -Base.round(::Dates.ConvertiblePeriod, ::Dates.ConvertiblePeriod, ::RoundingMode{:NearestTiesUp}) -``` - -The following functions are not exported: - -```@docs -Dates.floorceil -Dates.epochdays2date -Dates.epochms2datetime -Dates.date2epochdays -Dates.datetime2epochms -``` - -### Conversion Functions - -```@docs -Dates.today -Dates.unix2datetime -Dates.datetime2unix -Dates.julian2datetime -Dates.datetime2julian -Dates.rata2datetime -Dates.datetime2rata -``` - -### Constants - -Days of the Week: - -| Variable | Abbr. | Value (Int) | -|:----------- |:----- |:----------- | -| `Monday` | `Mon` | 1 | -| `Tuesday` | `Tue` | 2 | -| `Wednesday` | `Wed` | 3 | -| `Thursday` | `Thu` | 4 | -| `Friday` | `Fri` | 5 | -| `Saturday` | `Sat` | 6 | -| `Sunday` | `Sun` | 7 | - -Months of the Year: - -| Variable | Abbr. | Value (Int) | -|:----------- |:----- |:----------- | -| `January` | `Jan` | 1 | -| `February` | `Feb` | 2 | -| `March` | `Mar` | 3 | -| `April` | `Apr` | 4 | -| `May` | `May` | 5 | -| `June` | `Jun` | 6 | -| `July` | `Jul` | 7 | -| `August` | `Aug` | 8 | -| `September` | `Sep` | 9 | -| `October` | `Oct` | 10 | -| `November` | `Nov` | 11 | -| `December` | `Dec` | 12 | - -```@meta -DocTestSetup = nothing -``` diff --git a/src/stdlib/delimitedfiles.md b/src/stdlib/delimitedfiles.md deleted file mode 100644 index 839bdb8..0000000 --- a/src/stdlib/delimitedfiles.md +++ /dev/null @@ -1,19 +0,0 @@ -# Delimited Files - -```@meta -DocTestSetup = :(using DelimitedFiles) -``` - -```@docs -DelimitedFiles.readdlm(::Any, ::AbstractChar, ::Type, ::AbstractChar) -DelimitedFiles.readdlm(::Any, ::AbstractChar, ::AbstractChar) -DelimitedFiles.readdlm(::Any, ::AbstractChar, ::Type) -DelimitedFiles.readdlm(::Any, ::AbstractChar) -DelimitedFiles.readdlm(::Any, ::Type) -DelimitedFiles.readdlm(::Any) -DelimitedFiles.writedlm -``` - -```@meta -DocTestSetup = nothing -``` diff --git a/src/stdlib/distributed.md b/src/stdlib/distributed.md deleted file mode 100644 index da0b822..0000000 --- a/src/stdlib/distributed.md +++ /dev/null @@ -1,77 +0,0 @@ -# Distributed Computing - -```@meta -DocTestSetup = :(using Distributed) -``` - -```@docs -Distributed.addprocs -Distributed.nprocs -Distributed.nworkers -Distributed.procs() -Distributed.procs(::Integer) -Distributed.workers -Distributed.rmprocs -Distributed.interrupt -Distributed.myid -Distributed.pmap -Distributed.RemoteException -Distributed.Future -Distributed.RemoteChannel -Distributed.wait -Distributed.fetch(::Any) -Distributed.remotecall(::Any, ::Integer, ::Any...) -Distributed.remotecall_wait(::Any, ::Integer, ::Any...) -Distributed.remotecall_fetch(::Any, ::Integer, ::Any...) -Distributed.remote_do(::Any, ::Integer, ::Any...) -Distributed.put!(::RemoteChannel, ::Any...) -Distributed.put!(::Future, ::Any) -Distributed.take!(::RemoteChannel, ::Any...) -Distributed.isready(::RemoteChannel, ::Any...) -Distributed.isready(::Future) -Distributed.WorkerPool -Distributed.CachingPool -Distributed.default_worker_pool -Distributed.clear!(::CachingPool) -Distributed.remote -Distributed.remotecall(::Any, ::AbstractWorkerPool, ::Any...) -Distributed.remotecall_wait(::Any, ::AbstractWorkerPool, ::Any...) -Distributed.remotecall_fetch(::Any, ::AbstractWorkerPool, ::Any...) -Distributed.remote_do(::Any, ::AbstractWorkerPool, ::Any...) -Distributed.timedwait -Distributed.@spawn -Distributed.@spawnat -Distributed.@fetch -Distributed.@fetchfrom -Distributed.@async -Distributed.@sync -Distributed.@distributed -Distributed.@everywhere -Distributed.clear!(::Any, ::Any; ::Any) -Distributed.remoteref_id -Distributed.channel_from_id -Distributed.worker_id_from_socket -Distributed.cluster_cookie() -Distributed.cluster_cookie(::Any) -``` - -## Cluster Manager Interface - -This interface provides a mechanism to launch and manage Julia workers on different cluster environments. -There are two types of managers present in Base: `LocalManager`, for launching additional workers on the -same host, and `SSHManager`, for launching on remote hosts via `ssh`. TCP/IP sockets are used to connect -and transport messages between processes. It is possible for Cluster Managers to provide a different transport. - -```@docs -Distributed.launch -Distributed.manage -Distributed.kill(::ClusterManager, ::Int, ::WorkerConfig) -Distributed.connect(::ClusterManager, ::Int, ::WorkerConfig) -Distributed.init_worker -Distributed.start_worker -Distributed.process_messages -``` - -```@meta -DocTestSetup = nothing -``` diff --git a/src/stdlib/filewatching.md b/src/stdlib/filewatching.md deleted file mode 100644 index 3944f5d..0000000 --- a/src/stdlib/filewatching.md +++ /dev/null @@ -1,9 +0,0 @@ -# [File Events](@id lib-filewatching) - -```@docs -FileWatching.poll_fd -FileWatching.poll_file -FileWatching.watch_file -FileWatching.watch_folder -FileWatching.unwatch_folder -``` diff --git a/src/stdlib/libdl.md b/src/stdlib/libdl.md deleted file mode 100644 index c25ad8c..0000000 --- a/src/stdlib/libdl.md +++ /dev/null @@ -1,13 +0,0 @@ -# Dynamic Linker - -```@docs -Libdl.dlopen -Libdl.dlopen_e -Libdl.RTLD_NOW -Libdl.dlsym -Libdl.dlsym_e -Libdl.dlclose -Libdl.dlext -Libdl.find_library -Libdl.DL_LOAD_PATH -``` diff --git a/src/stdlib/linearalgebra.md b/src/stdlib/linearalgebra.md deleted file mode 100644 index bc32753..0000000 --- a/src/stdlib/linearalgebra.md +++ /dev/null @@ -1,625 +0,0 @@ -# Linear Algebra - -```@meta -DocTestSetup = :(using LinearAlgebra) -``` - -In addition to (and as part of) its support for multi-dimensional arrays, Julia provides native implementations -of many common and useful linear algebra operations. Basic operations, such as [`tr`](@ref), [`det`](@ref), -and [`inv`](@ref) are all supported: - -```jldoctest -julia> A = [1 2 3; 4 1 6; 7 8 1] -3×3 Array{Int64,2}: - 1 2 3 - 4 1 6 - 7 8 1 - -julia> tr(A) -3 - -julia> det(A) -104.0 - -julia> inv(A) -3×3 Array{Float64,2}: - -0.451923 0.211538 0.0865385 - 0.365385 -0.192308 0.0576923 - 0.240385 0.0576923 -0.0673077 -``` - -As well as other useful operations, such as finding eigenvalues or eigenvectors: - -```jldoctest -julia> A = [-4. -17.; 2. 2.] -2×2 Array{Float64,2}: - -4.0 -17.0 - 2.0 2.0 - -julia> eigvals(A) -2-element Array{Complex{Float64},1}: - -1.0 + 5.0im - -1.0 - 5.0im - -julia> eigvecs(A) -2×2 Array{Complex{Float64},2}: - 0.945905+0.0im 0.945905-0.0im - -0.166924-0.278207im -0.166924+0.278207im -``` - -In addition, Julia provides many [factorizations](@ref man-linalg-factorizations) which can be used to -speed up problems such as linear solve or matrix exponentiation by pre-factorizing a matrix into a form -more amenable (for performance or memory reasons) to the problem. See the documentation on [`factorize`](@ref) -for more information. As an example: - -```jldoctest -julia> A = [1.5 2 -4; 3 -1 -6; -10 2.3 4] -3×3 Array{Float64,2}: - 1.5 2.0 -4.0 - 3.0 -1.0 -6.0 - -10.0 2.3 4.0 - -julia> factorize(A) -LU{Float64,Array{Float64,2}} -L factor: -3×3 Array{Float64,2}: - 1.0 0.0 0.0 - -0.15 1.0 0.0 - -0.3 -0.132196 1.0 -U factor: -3×3 Array{Float64,2}: - -10.0 2.3 4.0 - 0.0 2.345 -3.4 - 0.0 0.0 -5.24947 -``` - -Since `A` is not Hermitian, symmetric, triangular, tridiagonal, or bidiagonal, an LU factorization may be the -best we can do. Compare with: - -```jldoctest -julia> B = [1.5 2 -4; 2 -1 -3; -4 -3 5] -3×3 Array{Float64,2}: - 1.5 2.0 -4.0 - 2.0 -1.0 -3.0 - -4.0 -3.0 5.0 - -julia> factorize(B) -BunchKaufman{Float64,Array{Float64,2}} -D factor: -3×3 Tridiagonal{Float64,Array{Float64,1}}: - -1.64286 0.0 ⋅ - 0.0 -2.8 0.0 - ⋅ 0.0 5.0 -U factor: -3×3 UnitUpperTriangular{Float64,Array{Float64,2}}: - 1.0 0.142857 -0.8 - ⋅ 1.0 -0.6 - ⋅ ⋅ 1.0 -permutation: -3-element Array{Int64,1}: - 1 - 2 - 3 -``` - -Here, Julia was able to detect that `B` is in fact symmetric, and used a more appropriate factorization. -Often it's possible to write more efficient code for a matrix that is known to have certain properties e.g. -it is symmetric, or tridiagonal. Julia provides some special types so that you can "tag" matrices as having -these properties. For instance: - -```jldoctest -julia> B = [1.5 2 -4; 2 -1 -3; -4 -3 5] -3×3 Array{Float64,2}: - 1.5 2.0 -4.0 - 2.0 -1.0 -3.0 - -4.0 -3.0 5.0 - -julia> sB = Symmetric(B) -3×3 Symmetric{Float64,Array{Float64,2}}: - 1.5 2.0 -4.0 - 2.0 -1.0 -3.0 - -4.0 -3.0 5.0 -``` - -`sB` has been tagged as a matrix that's (real) symmetric, so for later operations we might perform on it, -such as eigenfactorization or computing matrix-vector products, efficiencies can be found by only referencing -half of it. For example: - -```jldoctest -julia> B = [1.5 2 -4; 2 -1 -3; -4 -3 5] -3×3 Array{Float64,2}: - 1.5 2.0 -4.0 - 2.0 -1.0 -3.0 - -4.0 -3.0 5.0 - -julia> sB = Symmetric(B) -3×3 Symmetric{Float64,Array{Float64,2}}: - 1.5 2.0 -4.0 - 2.0 -1.0 -3.0 - -4.0 -3.0 5.0 - -julia> x = [1; 2; 3] -3-element Array{Int64,1}: - 1 - 2 - 3 - -julia> sB\x -3-element Array{Float64,1}: - -1.7391304347826084 - -1.1086956521739126 - -1.4565217391304346 -``` -The `\` operation here performs the linear solution. The left-division operator is pretty powerful and it's easy to write compact, readable code that is flexible enough to solve all sorts of systems of linear equations. - -## Special matrices - -[Matrices with special symmetries and structures](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=3274) -arise often in linear algebra and are frequently associated with various matrix factorizations. -Julia features a rich collection of special matrix types, which allow for fast computation with -specialized routines that are specially developed for particular matrix types. - -The following tables summarize the types of special matrices that have been implemented in Julia, -as well as whether hooks to various optimized methods for them in LAPACK are available. - -| Type | Description | -|:------------------------- |:-------------------------------------------------------------------------------- | -| [`Symmetric`](@ref) | [Symmetric matrix](https://en.wikipedia.org/wiki/Symmetric_matrix) | -| [`Hermitian`](@ref) | [Hermitian matrix](https://en.wikipedia.org/wiki/Hermitian_matrix) | -| [`UpperTriangular`](@ref) | Upper [triangular matrix](https://en.wikipedia.org/wiki/Triangular_matrix) | -| [`LowerTriangular`](@ref) | Lower [triangular matrix](https://en.wikipedia.org/wiki/Triangular_matrix) | -| [`Tridiagonal`](@ref) | [Tridiagonal matrix](https://en.wikipedia.org/wiki/Tridiagonal_matrix) | -| [`SymTridiagonal`](@ref) | Symmetric tridiagonal matrix | -| [`Bidiagonal`](@ref) | Upper/lower [bidiagonal matrix](https://en.wikipedia.org/wiki/Bidiagonal_matrix) | -| [`Diagonal`](@ref) | [Diagonal matrix](https://en.wikipedia.org/wiki/Diagonal_matrix) | -| [`UniformScaling`](@ref) | [Uniform scaling operator](https://en.wikipedia.org/wiki/Uniform_scaling) | - -### Elementary operations - -| Matrix type | `+` | `-` | `*` | `\` | Other functions with optimized methods | -|:------------------------- |:--- |:--- |:--- |:--- |:----------------------------------------------------------- | -| [`Symmetric`](@ref) | | | | MV | [`inv`](@ref), [`sqrt`](@ref), [`exp`](@ref) | -| [`Hermitian`](@ref) | | | | MV | [`inv`](@ref), [`sqrt`](@ref), [`exp`](@ref) | -| [`UpperTriangular`](@ref) | | | MV | MV | [`inv`](@ref), [`det`](@ref) | -| [`LowerTriangular`](@ref) | | | MV | MV | [`inv`](@ref), [`det`](@ref) | -| [`SymTridiagonal`](@ref) | M | M | MS | MV | [`eigmax`](@ref), [`eigmin`](@ref) | -| [`Tridiagonal`](@ref) | M | M | MS | MV | | -| [`Bidiagonal`](@ref) | M | M | MS | MV | | -| [`Diagonal`](@ref) | M | M | MV | MV | [`inv`](@ref), [`det`](@ref), [`logdet`](@ref), [`/`](@ref) | -| [`UniformScaling`](@ref) | M | M | MVS | MVS | [`/`](@ref) | - -Legend: - -| Key | Description | -|:---------- |:------------------------------------------------------------- | -| M (matrix) | An optimized method for matrix-matrix operations is available | -| V (vector) | An optimized method for matrix-vector operations is available | -| S (scalar) | An optimized method for matrix-scalar operations is available | - -### Matrix factorizations - -| Matrix type | LAPACK | [`eigen`](@ref) | [`eigvals`](@ref) | [`eigvecs`](@ref) | [`svd`](@ref) | [`svdvals`](@ref) | -|:------------------------- |:------ |:------------- |:----------------- |:----------------- |:------------- |:----------------- | -| [`Symmetric`](@ref) | SY | | ARI | | | | -| [`Hermitian`](@ref) | HE | | ARI | | | | -| [`UpperTriangular`](@ref) | TR | A | A | A | | | -| [`LowerTriangular`](@ref) | TR | A | A | A | | | -| [`SymTridiagonal`](@ref) | ST | A | ARI | AV | | | -| [`Tridiagonal`](@ref) | GT | | | | | | -| [`Bidiagonal`](@ref) | BD | | | | A | A | -| [`Diagonal`](@ref) | DI | | A | | | | - -Legend: - -| Key | Description | Example | -|:------------ |:------------------------------------------------------------------------------------------------------------------------------- |:-------------------- | -| A (all) | An optimized method to find all the characteristic values and/or vectors is available | e.g. `eigvals(M)` | -| R (range) | An optimized method to find the `il`th through the `ih`th characteristic values are available | `eigvals(M, il, ih)` | -| I (interval) | An optimized method to find the characteristic values in the interval [`vl`, `vh`] is available | `eigvals(M, vl, vh)` | -| V (vectors) | An optimized method to find the characteristic vectors corresponding to the characteristic values `x=[x1, x2,...]` is available | `eigvecs(M, x)` | - -### The uniform scaling operator - -A [`UniformScaling`](@ref) operator represents a scalar times the identity operator, `λ*I`. The identity -operator `I` is defined as a constant and is an instance of `UniformScaling`. The size of these -operators are generic and match the other matrix in the binary operations [`+`](@ref), [`-`](@ref), -[`*`](@ref) and [`\`](@ref). For `A+I` and `A-I` this means that `A` must be square. Multiplication -with the identity operator `I` is a noop (except for checking that the scaling factor is one) -and therefore almost without overhead. - -To see the `UniformScaling` operator in action: - -```jldoctest -julia> U = UniformScaling(2); - -julia> a = [1 2; 3 4] -2×2 Array{Int64,2}: - 1 2 - 3 4 - -julia> a + U -2×2 Array{Int64,2}: - 3 2 - 3 6 - -julia> a * U -2×2 Array{Int64,2}: - 2 4 - 6 8 - -julia> [a U] -2×4 Array{Int64,2}: - 1 2 2 0 - 3 4 0 2 - -julia> b = [1 2 3; 4 5 6] -2×3 Array{Int64,2}: - 1 2 3 - 4 5 6 - -julia> b - U -ERROR: DimensionMismatch("matrix is not square: dimensions are (2, 3)") -Stacktrace: -[...] -``` - -## [Matrix factorizations](@id man-linalg-factorizations) - -[Matrix factorizations (a.k.a. matrix decompositions)](https://en.wikipedia.org/wiki/Matrix_decomposition) -compute the factorization of a matrix into a product of matrices, and are one of the central concepts -in linear algebra. - -The following table summarizes the types of matrix factorizations that have been implemented in -Julia. Details of their associated methods can be found in the [Standard Functions](@ref) section -of the Linear Algebra documentation. - -| Type | Description | -|:----------------- |:-------------------------------------------------------------------------------------------------------------- | -| `Cholesky` | [Cholesky factorization](https://en.wikipedia.org/wiki/Cholesky_decomposition) | -| `CholeskyPivoted` | [Pivoted](https://en.wikipedia.org/wiki/Pivot_element) Cholesky factorization | -| `LU` | [LU factorization](https://en.wikipedia.org/wiki/LU_decomposition) | -| `LUTridiagonal` | LU factorization for [`Tridiagonal`](@ref) matrices | -| `QR` | [QR factorization](https://en.wikipedia.org/wiki/QR_decomposition) | -| `QRCompactWY` | Compact WY form of the QR factorization | -| `QRPivoted` | Pivoted [QR factorization](https://en.wikipedia.org/wiki/QR_decomposition) | -| `Hessenberg` | [Hessenberg decomposition](http://mathworld.wolfram.com/HessenbergDecomposition.html) | -| `Eigen` | [Spectral decomposition](https://en.wikipedia.org/wiki/Eigendecomposition_(matrix)) | -| `SVD` | [Singular value decomposition](https://en.wikipedia.org/wiki/Singular_value_decomposition) | -| `GeneralizedSVD` | [Generalized SVD](https://en.wikipedia.org/wiki/Generalized_singular_value_decomposition#Higher_order_version) | - - - - -## Standard Functions - -Linear algebra functions in Julia are largely implemented by calling functions from [LAPACK](http://www.netlib.org/lapack/). - Sparse factorizations call functions from [SuiteSparse](http://faculty.cse.tamu.edu/davis/suitesparse.html). - -```@docs -Base.:*(::AbstractMatrix, ::AbstractMatrix) -Base.:\(::AbstractMatrix, ::AbstractVecOrMat) -LinearAlgebra.dot -LinearAlgebra.cross -LinearAlgebra.factorize -LinearAlgebra.Diagonal -LinearAlgebra.Bidiagonal -LinearAlgebra.SymTridiagonal -LinearAlgebra.Tridiagonal -LinearAlgebra.Symmetric -LinearAlgebra.Hermitian -LinearAlgebra.LowerTriangular -LinearAlgebra.UpperTriangular -LinearAlgebra.UniformScaling -LinearAlgebra.lu -LinearAlgebra.lu! -LinearAlgebra.cholesky -LinearAlgebra.cholesky! -LinearAlgebra.lowrankupdate -LinearAlgebra.lowrankdowndate -LinearAlgebra.lowrankupdate! -LinearAlgebra.lowrankdowndate! -LinearAlgebra.ldlt -LinearAlgebra.ldlt! -LinearAlgebra.qr -LinearAlgebra.qr! -LinearAlgebra.QR -LinearAlgebra.QRCompactWY -LinearAlgebra.QRPivoted -LinearAlgebra.lq! -LinearAlgebra.lq -LinearAlgebra.bunchkaufman -LinearAlgebra.bunchkaufman! -LinearAlgebra.eigvals -LinearAlgebra.eigvals! -LinearAlgebra.eigmax -LinearAlgebra.eigmin -LinearAlgebra.eigvecs -LinearAlgebra.eigen -LinearAlgebra.eigen! -LinearAlgebra.hessenberg -LinearAlgebra.hessenberg! -LinearAlgebra.schur! -LinearAlgebra.schur -LinearAlgebra.ordschur -LinearAlgebra.ordschur! -LinearAlgebra.svd -LinearAlgebra.svd! -LinearAlgebra.svdvals -LinearAlgebra.svdvals! -LinearAlgebra.Givens -LinearAlgebra.givens -LinearAlgebra.triu -LinearAlgebra.triu! -LinearAlgebra.tril -LinearAlgebra.tril! -LinearAlgebra.diagind -LinearAlgebra.diag -LinearAlgebra.diagm -LinearAlgebra.rank -LinearAlgebra.norm -LinearAlgebra.opnorm -LinearAlgebra.normalize! -LinearAlgebra.normalize -LinearAlgebra.cond -LinearAlgebra.condskeel -LinearAlgebra.tr -LinearAlgebra.det -LinearAlgebra.logdet -LinearAlgebra.logabsdet -Base.inv(::AbstractMatrix) -LinearAlgebra.pinv -LinearAlgebra.nullspace -Base.kron -LinearAlgebra.exp(::StridedMatrix{<:LinearAlgebra.BlasFloat}) -LinearAlgebra.log(::StridedMatrix) -LinearAlgebra.sqrt(::StridedMatrix{<:Real}) -LinearAlgebra.cos(::StridedMatrix{<:Real}) -LinearAlgebra.sin(::StridedMatrix{<:Real}) -LinearAlgebra.sincos(::StridedMatrix{<:Real}) -LinearAlgebra.tan(::StridedMatrix{<:Real}) -LinearAlgebra.sec(::StridedMatrix) -LinearAlgebra.csc(::StridedMatrix) -LinearAlgebra.cot(::StridedMatrix) -LinearAlgebra.cosh(::StridedMatrix) -LinearAlgebra.sinh(::StridedMatrix) -LinearAlgebra.tanh(::StridedMatrix) -LinearAlgebra.sech(::StridedMatrix) -LinearAlgebra.csch(::StridedMatrix) -LinearAlgebra.coth(::StridedMatrix) -LinearAlgebra.acos(::StridedMatrix) -LinearAlgebra.asin(::StridedMatrix) -LinearAlgebra.atan(::StridedMatrix) -LinearAlgebra.asec(::StridedMatrix) -LinearAlgebra.acsc(::StridedMatrix) -LinearAlgebra.acot(::StridedMatrix) -LinearAlgebra.acosh(::StridedMatrix) -LinearAlgebra.asinh(::StridedMatrix) -LinearAlgebra.atanh(::StridedMatrix) -LinearAlgebra.asech(::StridedMatrix) -LinearAlgebra.acsch(::StridedMatrix) -LinearAlgebra.acoth(::StridedMatrix) -LinearAlgebra.lyap -LinearAlgebra.sylvester -LinearAlgebra.issuccess -LinearAlgebra.issymmetric -LinearAlgebra.isposdef -LinearAlgebra.isposdef! -LinearAlgebra.istril -LinearAlgebra.istriu -LinearAlgebra.isdiag -LinearAlgebra.ishermitian -Base.transpose -LinearAlgebra.transpose! -Base.adjoint -LinearAlgebra.adjoint! -Base.copy(::Union{Transpose,Adjoint}) -LinearAlgebra.stride1 -LinearAlgebra.checksquare -``` - -## Low-level matrix operations - -In many cases there are in-place versions of matrix operations that allow you to supply -a pre-allocated output vector or matrix. This is useful when optimizing critical code in order -to avoid the overhead of repeated allocations. These in-place operations are suffixed with `!` -below (e.g. `mul!`) according to the usual Julia convention. - -```@docs -LinearAlgebra.mul! -LinearAlgebra.lmul! -LinearAlgebra.rmul! -LinearAlgebra.ldiv! -LinearAlgebra.rdiv! -``` - -## BLAS Functions - -In Julia (as in much of scientific computation), dense linear-algebra operations are based on -the [LAPACK library](http://www.netlib.org/lapack/), which in turn is built on top of basic linear-algebra -building-blocks known as the [BLAS](http://www.netlib.org/blas/). There are highly optimized -implementations of BLAS available for every computer architecture, and sometimes in high-performance -linear algebra routines it is useful to call the BLAS functions directly. - -`LinearAlgebra.BLAS` provides wrappers for some of the BLAS functions. Those BLAS functions -that overwrite one of the input arrays have names ending in `'!'`. Usually, a BLAS function has -four methods defined, for [`Float64`](@ref), [`Float32`](@ref), `ComplexF64`, and `ComplexF32` arrays. - -### [BLAS Character Arguments](@id stdlib-blas-chars) -Many BLAS functions accept arguments that determine whether to transpose an argument (`trans`), -which triangle of a matrix to reference (`uplo` or `ul`), -whether the diagonal of a triangular matrix can be assumed to -be all ones (`dA`) or which side of a matrix multiplication -the input argument belongs on (`side`). The possibilities are: - -#### [Multplication Order](@id stdlib-blas-side) -| `side` | Meaning | -|:-------|:--------------------------------------------------------------------| -| `'L'` | The argument goes on the *left* side of a matrix-matrix operation. | -| `'R'` | The argument goes on the *right* side of a matrix-matrix operation. | - -#### [Triangle Referencing](@id stdlib-blas-uplo) -| `uplo`/`ul` | Meaning | -|:------------|:------------------------------------------------------| -| `'U'` | Only the *upper* triangle of the matrix will be used. | -| `'L'` | Only the *lower* triangle of the matrix will be used. | - -#### [Transposition Operation](@id stdlib-blas-trans) -| `trans`/`tX` | Meaning | -|:-------------|:--------------------------------------------------------| -| `'N'` | The input matrix `X` is not transposed or conjugated. | -| `'T'` | The input matrix `X` will be transposed. | -| `'C'` | The input matrix `X` will be conjugated and transposed. | - -#### [Unit Diagonal](@id stdlib-blas-diag) -| `diag`/`dX` | Meaning | -|:------------|:----------------------------------------------------------| -| `'N'` | The diagonal values of the matrix `X` will be read. | -| `'U'` | The diagonal of the matrix `X` is assumed to be all ones. | - -```@docs -LinearAlgebra.BLAS -LinearAlgebra.BLAS.dotu -LinearAlgebra.BLAS.dotc -LinearAlgebra.BLAS.blascopy! -LinearAlgebra.BLAS.nrm2 -LinearAlgebra.BLAS.asum -LinearAlgebra.axpy! -LinearAlgebra.BLAS.scal! -LinearAlgebra.BLAS.scal -LinearAlgebra.BLAS.ger! -LinearAlgebra.BLAS.syr! -LinearAlgebra.BLAS.syrk! -LinearAlgebra.BLAS.syrk -LinearAlgebra.BLAS.her! -LinearAlgebra.BLAS.herk! -LinearAlgebra.BLAS.herk -LinearAlgebra.BLAS.gbmv! -LinearAlgebra.BLAS.gbmv -LinearAlgebra.BLAS.sbmv! -LinearAlgebra.BLAS.sbmv(::Any, ::Any, ::Any, ::Any, ::Any) -LinearAlgebra.BLAS.sbmv(::Any, ::Any, ::Any, ::Any) -LinearAlgebra.BLAS.gemm! -LinearAlgebra.BLAS.gemm(::Any, ::Any, ::Any, ::Any, ::Any) -LinearAlgebra.BLAS.gemm(::Any, ::Any, ::Any, ::Any) -LinearAlgebra.BLAS.gemv! -LinearAlgebra.BLAS.gemv(::Any, ::Any, ::Any, ::Any) -LinearAlgebra.BLAS.gemv(::Any, ::Any, ::Any) -LinearAlgebra.BLAS.symm! -LinearAlgebra.BLAS.symm(::Any, ::Any, ::Any, ::Any, ::Any) -LinearAlgebra.BLAS.symm(::Any, ::Any, ::Any, ::Any) -LinearAlgebra.BLAS.symv! -LinearAlgebra.BLAS.symv(::Any, ::Any, ::Any, ::Any) -LinearAlgebra.BLAS.symv(::Any, ::Any, ::Any) -LinearAlgebra.BLAS.trmm! -LinearAlgebra.BLAS.trmm -LinearAlgebra.BLAS.trsm! -LinearAlgebra.BLAS.trsm -LinearAlgebra.BLAS.trmv! -LinearAlgebra.BLAS.trmv -LinearAlgebra.BLAS.trsv! -LinearAlgebra.BLAS.trsv -LinearAlgebra.BLAS.set_num_threads -LinearAlgebra.I -``` - -## LAPACK Functions - -`LinearAlgebra.LAPACK` provides wrappers for some of the LAPACK functions for linear algebra. - Those functions that overwrite one of the input arrays have names ending in `'!'`. - -Usually a function has 4 methods defined, one each for [`Float64`](@ref), [`Float32`](@ref), -`ComplexF64` and `ComplexF32` arrays. - -Note that the LAPACK API provided by Julia can and will change in the future. Since this API is -not user-facing, there is no commitment to support/deprecate this specific set of functions in -future releases. - -```@docs -LinearAlgebra.LAPACK -LinearAlgebra.LAPACK.gbtrf! -LinearAlgebra.LAPACK.gbtrs! -LinearAlgebra.LAPACK.gebal! -LinearAlgebra.LAPACK.gebak! -LinearAlgebra.LAPACK.gebrd! -LinearAlgebra.LAPACK.gelqf! -LinearAlgebra.LAPACK.geqlf! -LinearAlgebra.LAPACK.geqrf! -LinearAlgebra.LAPACK.geqp3! -LinearAlgebra.LAPACK.gerqf! -LinearAlgebra.LAPACK.geqrt! -LinearAlgebra.LAPACK.geqrt3! -LinearAlgebra.LAPACK.getrf! -LinearAlgebra.LAPACK.tzrzf! -LinearAlgebra.LAPACK.ormrz! -LinearAlgebra.LAPACK.gels! -LinearAlgebra.LAPACK.gesv! -LinearAlgebra.LAPACK.getrs! -LinearAlgebra.LAPACK.getri! -LinearAlgebra.LAPACK.gesvx! -LinearAlgebra.LAPACK.gelsd! -LinearAlgebra.LAPACK.gelsy! -LinearAlgebra.LAPACK.gglse! -LinearAlgebra.LAPACK.geev! -LinearAlgebra.LAPACK.gesdd! -LinearAlgebra.LAPACK.gesvd! -LinearAlgebra.LAPACK.ggsvd! -LinearAlgebra.LAPACK.ggsvd3! -LinearAlgebra.LAPACK.geevx! -LinearAlgebra.LAPACK.ggev! -LinearAlgebra.LAPACK.gtsv! -LinearAlgebra.LAPACK.gttrf! -LinearAlgebra.LAPACK.gttrs! -LinearAlgebra.LAPACK.orglq! -LinearAlgebra.LAPACK.orgqr! -LinearAlgebra.LAPACK.orgql! -LinearAlgebra.LAPACK.orgrq! -LinearAlgebra.LAPACK.ormlq! -LinearAlgebra.LAPACK.ormqr! -LinearAlgebra.LAPACK.ormql! -LinearAlgebra.LAPACK.ormrq! -LinearAlgebra.LAPACK.gemqrt! -LinearAlgebra.LAPACK.posv! -LinearAlgebra.LAPACK.potrf! -LinearAlgebra.LAPACK.potri! -LinearAlgebra.LAPACK.potrs! -LinearAlgebra.LAPACK.pstrf! -LinearAlgebra.LAPACK.ptsv! -LinearAlgebra.LAPACK.pttrf! -LinearAlgebra.LAPACK.pttrs! -LinearAlgebra.LAPACK.trtri! -LinearAlgebra.LAPACK.trtrs! -LinearAlgebra.LAPACK.trcon! -LinearAlgebra.LAPACK.trevc! -LinearAlgebra.LAPACK.trrfs! -LinearAlgebra.LAPACK.stev! -LinearAlgebra.LAPACK.stebz! -LinearAlgebra.LAPACK.stegr! -LinearAlgebra.LAPACK.stein! -LinearAlgebra.LAPACK.syconv! -LinearAlgebra.LAPACK.sysv! -LinearAlgebra.LAPACK.sytrf! -LinearAlgebra.LAPACK.sytri! -LinearAlgebra.LAPACK.sytrs! -LinearAlgebra.LAPACK.hesv! -LinearAlgebra.LAPACK.hetrf! -LinearAlgebra.LAPACK.hetri! -LinearAlgebra.LAPACK.hetrs! -LinearAlgebra.LAPACK.syev! -LinearAlgebra.LAPACK.syevr! -LinearAlgebra.LAPACK.sygvd! -LinearAlgebra.LAPACK.bdsqr! -LinearAlgebra.LAPACK.bdsdc! -LinearAlgebra.LAPACK.gecon! -LinearAlgebra.LAPACK.gehrd! -LinearAlgebra.LAPACK.orghr! -LinearAlgebra.LAPACK.gees! -LinearAlgebra.LAPACK.gges! -LinearAlgebra.LAPACK.trexc! -LinearAlgebra.LAPACK.trsen! -LinearAlgebra.LAPACK.tgsen! -LinearAlgebra.LAPACK.trsyl! -``` - -```@meta -DocTestSetup = nothing -``` diff --git a/src/stdlib/mmap.md b/src/stdlib/mmap.md deleted file mode 100644 index 9bd623d..0000000 --- a/src/stdlib/mmap.md +++ /dev/null @@ -1,15 +0,0 @@ -# Memory-mapped I/O - -```@meta -DocTestSetup = :(using Mmap) -``` - -```@docs -Mmap.Anonymous -Mmap.mmap -Mmap.sync! -``` - -```@meta -DocTestSetup = nothing -``` diff --git a/src/stdlib/printf.md b/src/stdlib/printf.md deleted file mode 100644 index de79d5c..0000000 --- a/src/stdlib/printf.md +++ /dev/null @@ -1,14 +0,0 @@ -# Printf - -```@meta -DocTestSetup = :(using Printf) -``` - -```@docs -Printf.@printf -Printf.@sprintf -``` - -```@meta -DocTestSetup = nothing -``` diff --git a/src/stdlib/profile.md b/src/stdlib/profile.md deleted file mode 100644 index ac60bb9..0000000 --- a/src/stdlib/profile.md +++ /dev/null @@ -1,17 +0,0 @@ -# [Profiling](@id lib-profiling) - -```@docs -Profile.@profile -``` - -The methods in `Profile` are not exported and need to be called e.g. as `Profile.print()`. - -```@docs -Profile.clear -Profile.print -Profile.init -Profile.fetch -Profile.retrieve -Profile.callers -Profile.clear_malloc_data -``` diff --git a/src/stdlib/random.md b/src/stdlib/random.md deleted file mode 100644 index 54abfc2..0000000 --- a/src/stdlib/random.md +++ /dev/null @@ -1,50 +0,0 @@ -# Random Numbers - -```@meta -DocTestSetup = :(using Random) -``` - -Random number generation in Julia uses the [Mersenne Twister library](http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/#dSFMT) -via `MersenneTwister` objects. Julia has a global RNG, which is used by default. Other RNG types -can be plugged in by inheriting the `AbstractRNG` type; they can then be used to have multiple -streams of random numbers. Besides `MersenneTwister`, Julia also provides the `RandomDevice` RNG -type, which is a wrapper over the OS provided entropy. - -Most functions related to random generation accept an optional `AbstractRNG` as the first argument, -`rng` , which defaults to the global one if not provided. Moreover, some of them accept optionally -dimension specifications `dims...` (which can be given as a tuple) to generate arrays of random -values. - -A `MersenneTwister` or `RandomDevice` RNG can generate random numbers of the following types: -[`Float16`](@ref), [`Float32`](@ref), [`Float64`](@ref), [`BigFloat`](@ref), [`Bool`](@ref), -[`Int8`](@ref), [`UInt8`](@ref), [`Int16`](@ref), [`UInt16`](@ref), [`Int32`](@ref), -[`UInt32`](@ref), [`Int64`](@ref), [`UInt64`](@ref), [`Int128`](@ref), [`UInt128`](@ref), -[`BigInt`](@ref) (or complex numbers of those types). -Random floating point numbers are generated uniformly in ``[0, 1)``. As `BigInt` represents -unbounded integers, the interval must be specified (e.g. `rand(big.(1:6))`). - -```@docs -Random.srand -Random.MersenneTwister -Random.RandomDevice -Random.rand -Random.rand! -Random.bitrand -Random.randn -Random.randn! -Random.randexp -Random.randexp! -Random.randstring -Random.randsubseq -Random.randsubseq! -Random.randperm -Random.randperm! -Random.randcycle -Random.randcycle! -Random.shuffle -Random.shuffle! -``` - -```@meta -DocTestSetup = nothing -``` diff --git a/src/stdlib/serialization.md b/src/stdlib/serialization.md deleted file mode 100644 index c01ead7..0000000 --- a/src/stdlib/serialization.md +++ /dev/null @@ -1,7 +0,0 @@ -# Serialization - -```@docs -Serialization.serialize -Serialization.deserialize -Serialization.writeheader -``` diff --git a/src/stdlib/sharedarrays.md b/src/stdlib/sharedarrays.md deleted file mode 100644 index bac1cd0..0000000 --- a/src/stdlib/sharedarrays.md +++ /dev/null @@ -1,9 +0,0 @@ -# Shared Arrays - -```@docs -SharedArrays.SharedArray -SharedArrays.procs(::SharedArray) -SharedArrays.sdata -SharedArrays.indexpids -SharedArrays.localindices -``` diff --git a/src/stdlib/sparsearrays.md b/src/stdlib/sparsearrays.md deleted file mode 100644 index af1be79..0000000 --- a/src/stdlib/sparsearrays.md +++ /dev/null @@ -1,228 +0,0 @@ -# Sparse Arrays - -```@meta -DocTestSetup = :(using SparseArrays, LinearAlgebra) -``` - -Julia has support for sparse vectors and [sparse matrices](https://en.wikipedia.org/wiki/Sparse_matrix) -in the `SparseArrays` stdlib module. Sparse arrays are arrays that contain enough zeros -that storing them in a special data structure leads to savings in space and execution time, -compared to dense arrays. - -## [Compressed Sparse Column (CSC) Sparse Matrix Storage](@id man-csc) - -In Julia, sparse matrices are stored in the [Compressed Sparse Column (CSC) format](https://en.wikipedia.org/wiki/Sparse_matrix#Compressed_sparse_column_.28CSC_or_CCS.29). -Julia sparse matrices have the type [`SparseMatrixCSC{Tv,Ti}`](@ref), where `Tv` is the -type of the stored values, and `Ti` is the integer type for storing column pointers and -row indices. The internal representation of `SparseMatrixCSC` is as follows: - -```julia -struct SparseMatrixCSC{Tv,Ti<:Integer} <: AbstractSparseMatrix{Tv,Ti} - m::Int # Number of rows - n::Int # Number of columns - colptr::Vector{Ti} # Column i is in colptr[i]:(colptr[i+1]-1) - rowval::Vector{Ti} # Row indices of stored values - nzval::Vector{Tv} # Stored values, typically nonzeros -end -``` - -The compressed sparse column storage makes it easy and quick to access the elements in the column -of a sparse matrix, whereas accessing the sparse matrix by rows is considerably slower. Operations -such as insertion of previously unstored entries one at a time in the CSC structure tend to be slow. This is -because all elements of the sparse matrix that are beyond the point of insertion have to be moved -one place over. - -All operations on sparse matrices are carefully implemented to exploit the CSC data structure -for performance, and to avoid expensive operations. - -If you have data in CSC format from a different application or library, and wish to import it -in Julia, make sure that you use 1-based indexing. The row indices in every column need to be -sorted. If your `SparseMatrixCSC` object contains unsorted row indices, one quick way to sort -them is by doing a double transpose. - -In some applications, it is convenient to store explicit zero values in a `SparseMatrixCSC`. These -*are* accepted by functions in `Base` (but there is no guarantee that they will be preserved in -mutating operations). Such explicitly stored zeros are treated as structural nonzeros by many -routines. The [`nnz`](@ref) function returns the number of elements explicitly stored in the -sparse data structure, including structural nonzeros. In order to count the exact number of -numerical nonzeros, use [`count(!iszero, x)`](@ref), which inspects every stored element of a sparse -matrix. [`dropzeros`](@ref), and the in-place [`dropzeros!`](@ref), can be used to -remove stored zeros from the sparse matrix. - -```jldoctest -julia> A = sparse([1, 2, 3], [1, 2, 3], [0, 2, 0]) -3×3 SparseMatrixCSC{Int64,Int64} with 3 stored entries: - [1, 1] = 0 - [2, 2] = 2 - [3, 3] = 0 - -julia> dropzeros(A) -3×3 SparseMatrixCSC{Int64,Int64} with 1 stored entry: - [2, 2] = 2 -``` - -## Sparse Vector Storage - -Sparse vectors are stored in a close analog to compressed sparse column format for sparse -matrices. In Julia, sparse vectors have the type [`SparseVector{Tv,Ti}`](@ref) where `Tv` -is the type of the stored values and `Ti` the integer type for the indices. The internal -representation is as follows: - -```julia -struct SparseVector{Tv,Ti<:Integer} <: AbstractSparseVector{Tv,Ti} - n::Int # Length of the sparse vector - nzind::Vector{Ti} # Indices of stored values - nzval::Vector{Tv} # Stored values, typically nonzeros -end -``` - -As for [`SparseMatrixCSC`](@ref), the `SparseVector` type can also contain explicitly -stored zeros. (See [Sparse Matrix Storage](@ref man-csc).). - -## Sparse Vector and Matrix Constructors - -The simplest way to create a sparse array is to use a function equivalent to the [`zeros`](@ref) -function that Julia provides for working with dense arrays. To produce a -sparse array instead, you can use the same name with an `sp` prefix: - -```jldoctest -julia> spzeros(3) -3-element SparseVector{Float64,Int64} with 0 stored entries -``` - -The [`sparse`](@ref) function is often a handy way to construct sparse arrays. For -example, to construct a sparse matrix we can input a vector `I` of row indices, a vector -`J` of column indices, and a vector `V` of stored values (this is also known as the -[COO (coordinate) format](https://en.wikipedia.org/wiki/Sparse_matrix#Coordinate_list_.28COO.29)). -`sparse(I,J,V)` then constructs a sparse matrix such that `S[I[k], J[k]] = V[k]`. The -equivalent sparse vector constructor is [`sparsevec`](@ref), which takes the (row) index -vector `I` and the vector `V` with the stored values and constructs a sparse vector `R` -such that `R[I[k]] = V[k]`. - -```jldoctest sparse_function -julia> I = [1, 4, 3, 5]; J = [4, 7, 18, 9]; V = [1, 2, -5, 3]; - -julia> S = sparse(I,J,V) -5×18 SparseMatrixCSC{Int64,Int64} with 4 stored entries: - [1 , 4] = 1 - [4 , 7] = 2 - [5 , 9] = 3 - [3 , 18] = -5 - -julia> R = sparsevec(I,V) -5-element SparseVector{Int64,Int64} with 4 stored entries: - [1] = 1 - [3] = -5 - [4] = 2 - [5] = 3 -``` - -The inverse of the [`sparse`](@ref) and [`sparsevec`](@ref) functions is -[`findnz`](@ref), which retrieves the inputs used to create the sparse array. -[`findall(!iszero, x)`](@ref) returns the cartesian indices of non-zero entries in `x` -(including stored entries equal to zero). - -```jldoctest sparse_function -julia> findnz(S) -([1, 4, 5, 3], [4, 7, 9, 18], [1, 2, 3, -5]) - -julia> findall(!iszero, S) -4-element Array{CartesianIndex{2},1}: - CartesianIndex(1, 4) - CartesianIndex(4, 7) - CartesianIndex(5, 9) - CartesianIndex(3, 18) - -julia> findnz(R) -([1, 3, 4, 5], [1, -5, 2, 3]) - -julia> findall(!iszero, R) -4-element Array{Int64,1}: - 1 - 3 - 4 - 5 -``` - -Another way to create a sparse array is to convert a dense array into a sparse array using -the [`sparse`](@ref) function: - -```jldoctest -julia> sparse(Matrix(1.0I, 5, 5)) -5×5 SparseMatrixCSC{Float64,Int64} with 5 stored entries: - [1, 1] = 1.0 - [2, 2] = 1.0 - [3, 3] = 1.0 - [4, 4] = 1.0 - [5, 5] = 1.0 - -julia> sparse([1.0, 0.0, 1.0]) -3-element SparseVector{Float64,Int64} with 2 stored entries: - [1] = 1.0 - [3] = 1.0 -``` - -You can go in the other direction using the [`Array`](@ref) constructor. The [`issparse`](@ref) -function can be used to query if a matrix is sparse. - -```jldoctest -julia> issparse(spzeros(5)) -true -``` - -## Sparse matrix operations - -Arithmetic operations on sparse matrices also work as they do on dense matrices. Indexing of, -assignment into, and concatenation of sparse matrices work in the same way as dense matrices. -Indexing operations, especially assignment, are expensive, when carried out one element at a time. -In many cases it may be better to convert the sparse matrix into `(I,J,V)` format using [`findnz`](@ref), -manipulate the values or the structure in the dense vectors `(I,J,V)`, and then reconstruct -the sparse matrix. - -## Correspondence of dense and sparse methods - -The following table gives a correspondence between built-in methods on sparse matrices and their -corresponding methods on dense matrix types. In general, methods that generate sparse matrices -differ from their dense counterparts in that the resulting matrix follows the same sparsity pattern -as a given sparse matrix `S`, or that the resulting sparse matrix has density `d`, i.e. each matrix -element has a probability `d` of being non-zero. - -Details can be found in the [Sparse Vectors and Matrices](@ref stdlib-sparse-arrays) -section of the standard library reference. - -| Sparse | Dense | Description | -|:-------------------------- |:---------------------- |:--------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [`spzeros(m,n)`](@ref) | [`zeros(m,n)`](@ref) | Creates a *m*-by-*n* matrix of zeros. ([`spzeros(m,n)`](@ref) is empty.) | -| [`sparse(I, n, n)`](@ref) | [`Matrix(I,n,n)`](@ref)| Creates a *n*-by-*n* identity matrix. | -| [`Array(S)`](@ref) | [`sparse(A)`](@ref) | Interconverts between dense and sparse formats. | -| [`sprand(m,n,d)`](@ref) | [`rand(m,n)`](@ref) | Creates a *m*-by-*n* random matrix (of density *d*) with iid non-zero elements distributed uniformly on the half-open interval ``[0, 1)``. | -| [`sprandn(m,n,d)`](@ref) | [`randn(m,n)`](@ref) | Creates a *m*-by-*n* random matrix (of density *d*) with iid non-zero elements distributed according to the standard normal (Gaussian) distribution. | -| [`sprandn(m,n,d,X)`](@ref) | [`randn(m,n,X)`](@ref) | Creates a *m*-by-*n* random matrix (of density *d*) with iid non-zero elements distributed according to the *X* distribution. (Requires the `Distributions` package.) | - -# [Sparse Arrays](@id stdlib-sparse-arrays) - -```@docs -SparseArrays.SparseVector -SparseArrays.SparseMatrixCSC -SparseArrays.sparse -SparseArrays.sparsevec -SparseArrays.issparse -SparseArrays.nnz -SparseArrays.findnz -SparseArrays.spzeros -SparseArrays.spdiagm -SparseArrays.blockdiag -SparseArrays.sprand -SparseArrays.sprandn -SparseArrays.nonzeros -SparseArrays.rowvals -SparseArrays.nzrange -SparseArrays.dropzeros! -SparseArrays.dropzeros -SparseArrays.permute -permute!{Tv, Ti, Tp <: Integer, Tq <: Integer}(::SparseMatrixCSC{Tv,Ti}, ::SparseMatrixCSC{Tv,Ti}, ::AbstractArray{Tp,1}, ::AbstractArray{Tq,1}) -``` - -```@meta -DocTestSetup = nothing -``` diff --git a/src/stdlib/test.md b/src/stdlib/test.md deleted file mode 100644 index 4211071..0000000 --- a/src/stdlib/test.md +++ /dev/null @@ -1,269 +0,0 @@ -# Unit Testing - -```@meta -DocTestSetup = :(using Test) -``` - -## Testing Base Julia - -Julia is under rapid development and has an extensive test suite to verify functionality across -multiple platforms. If you build Julia from source, you can run this test suite with `make test`. -In a binary install, you can run the test suite using `Base.runtests()`. - -```@docs -Base.runtests -``` - -## Basic Unit Tests - -The `Test` module provides simple *unit testing* functionality. Unit testing is a way to -see if your code is correct by checking that the results are what you expect. It can be helpful -to ensure your code still works after you make changes, and can be used when developing as a way -of specifying the behaviors your code should have when complete. - -Simple unit testing can be performed with the `@test` and `@test_throws` macros: - -```@docs -Test.@test -Test.@test_throws -``` - -For example, suppose we want to check our new function `foo(x)` works as expected: - -```jldoctest testfoo -julia> using Test - -julia> foo(x) = length(x)^2 -foo (generic function with 1 method) -``` - -If the condition is true, a `Pass` is returned: - -```jldoctest testfoo -julia> @test foo("bar") == 9 -Test Passed - -julia> @test foo("fizz") >= 10 -Test Passed -``` - -If the condition is false, then a `Fail` is returned and an exception is thrown: - -```jldoctest testfoo -julia> @test foo("f") == 20 -Test Failed at none:1 - Expression: foo("f") == 20 - Evaluated: 1 == 20 -ERROR: There was an error during testing -``` - -If the condition could not be evaluated because an exception was thrown, which occurs in this -case because `length` is not defined for symbols, an `Error` object is returned and an exception -is thrown: - -```julia-repl -julia> @test foo(:cat) == 1 -Error During Test - Test threw an exception of type MethodError - Expression: foo(:cat) == 1 - MethodError: no method matching length(::Symbol) - Closest candidates are: - length(::SimpleVector) at essentials.jl:256 - length(::Base.MethodList) at reflection.jl:521 - length(::MethodTable) at reflection.jl:597 - ... - Stacktrace: - [...] -ERROR: There was an error during testing -``` - -If we expect that evaluating an expression *should* throw an exception, then we can use `@test_throws` -to check that this occurs: - -```jldoctest testfoo -julia> @test_throws MethodError foo(:cat) -Test Passed - Thrown: MethodError -``` - -## Working with Test Sets - -Typically a large number of tests are used to make sure functions work correctly over a range -of inputs. In the event a test fails, the default behavior is to throw an exception immediately. -However, it is normally preferable to run the rest of the tests first to get a better picture -of how many errors there are in the code being tested. - -The `@testset` macro can be used to group tests into *sets*. All the tests in a test set will -be run, and at the end of the test set a summary will be printed. If any of the tests failed, -or could not be evaluated due to an error, the test set will then throw a `TestSetException`. - -```@docs -Test.@testset -``` - -We can put our tests for the `foo(x)` function in a test set: - -```jldoctest testfoo -julia> @testset "Foo Tests" begin - @test foo("a") == 1 - @test foo("ab") == 4 - @test foo("abc") == 9 - end; -Test Summary: | Pass Total -Foo Tests | 3 3 -``` - -Test sets can also be nested: - -```jldoctest testfoo -julia> @testset "Foo Tests" begin - @testset "Animals" begin - @test foo("cat") == 9 - @test foo("dog") == foo("cat") - end - @testset "Arrays $i" for i in 1:3 - @test foo(zeros(i)) == i^2 - @test foo(fill(1.0, i)) == i^2 - end - end; -Test Summary: | Pass Total -Foo Tests | 8 8 -``` - -In the event that a nested test set has no failures, as happened here, it will be hidden in the -summary. If we do have a test failure, only the details for the failed test sets will be shown: - -```julia-repl -julia> @testset "Foo Tests" begin - @testset "Animals" begin - @testset "Felines" begin - @test foo("cat") == 9 - end - @testset "Canines" begin - @test foo("dog") == 9 - end - end - @testset "Arrays" begin - @test foo(zeros(2)) == 4 - @test foo(fill(1.0, 4)) == 15 - end - end - -Arrays: Test Failed - Expression: foo(fill(1.0, 4)) == 15 - Evaluated: 16 == 15 -[...] -Test Summary: | Pass Fail Total -Foo Tests | 3 1 4 - Animals | 2 2 - Arrays | 1 1 2 -ERROR: Some tests did not pass: 3 passed, 1 failed, 0 errored, 0 broken. -``` - -## Other Test Macros - -As calculations on floating-point values can be imprecise, you can perform approximate equality -checks using either `@test a ≈ b` (where `≈`, typed via tab completion of `\approx`, is the -[`isapprox`](@ref) function) or use [`isapprox`](@ref) directly. - -```jldoctest -julia> @test 1 ≈ 0.999999999 -Test Passed - -julia> @test 1 ≈ 0.999999 -Test Failed at none:1 - Expression: 1 ≈ 0.999999 - Evaluated: 1 ≈ 0.999999 -ERROR: There was an error during testing -``` - -```@docs -Test.@inferred -Test.@test_logs -Test.@test_deprecated -Test.@test_warn -Test.@test_nowarn -``` - -## Broken Tests - -If a test fails consistently it can be changed to use the `@test_broken` macro. This will denote -the test as `Broken` if the test continues to fail and alerts the user via an `Error` if the test -succeeds. - -```@docs -Test.@test_broken -``` - -`@test_skip` is also available to skip a test without evaluation, but counting the skipped test -in the test set reporting. The test will not run but gives a `Broken` `Result`. - -```@docs -Test.@test_skip -``` - -## Creating Custom `AbstractTestSet` Types - -Packages can create their own `AbstractTestSet` subtypes by implementing the `record` and `finish` -methods. The subtype should have a one-argument constructor taking a description string, with -any options passed in as keyword arguments. - -```@docs -Test.record -Test.finish -``` - -`Test` takes responsibility for maintaining a stack of nested testsets as they are executed, -but any result accumulation is the responsibility of the `AbstractTestSet` subtype. You can access -this stack with the `get_testset` and `get_testset_depth` methods. Note that these functions are -not exported. - -```@docs -Test.get_testset -Test.get_testset_depth -``` - -`Test` also makes sure that nested `@testset` invocations use the same `AbstractTestSet` -subtype as their parent unless it is set explicitly. It does not propagate any properties of the -testset. Option inheritance behavior can be implemented by packages using the stack infrastructure -that `Test` provides. - -Defining a basic `AbstractTestSet` subtype might look like: - -```julia -import Test: record, finish -using Test: AbstractTestSet, Result, Pass, Fail, Error -using Test: get_testset_depth, get_testset -struct CustomTestSet <: Test.AbstractTestSet - description::AbstractString - foo::Int - results::Vector - # constructor takes a description string and options keyword arguments - CustomTestSet(desc; foo=1) = new(desc, foo, []) -end - -record(ts::CustomTestSet, child::AbstractTestSet) = push!(ts.results, child) -record(ts::CustomTestSet, res::Result) = push!(ts.results, res) -function finish(ts::CustomTestSet) - # just record if we're not the top-level parent - if get_testset_depth() > 0 - record(get_testset(), ts) - end - ts -end -``` - -And using that testset looks like: - -```julia -@testset CustomTestSet foo=4 "custom testset inner 2" begin - # this testset should inherit the type, but not the argument. - @testset "custom testset inner" begin - @test true - end -end -``` - -```@meta -DocTestSetup = nothing -``` diff --git a/src/stdlib/unicode.md b/src/stdlib/unicode.md deleted file mode 100644 index 474629d..0000000 --- a/src/stdlib/unicode.md +++ /dev/null @@ -1,15 +0,0 @@ -# Unicode - -```@meta -DocTestSetup = :(using Unicode) -``` - -```@docs -Unicode.isassigned -Unicode.normalize -Unicode.graphemes -``` - -```@meta -DocTestSetup = nothing -``` From cc93c62609bf3043341c8c258d9c035e54ac7e95 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Thu, 12 Jul 2018 15:45:28 +0900 Subject: [PATCH 043/153] update Julia Commit 8ab41d6d1f --- codex/NEWS.md | 12 ++- codex/base/base.md | 1 + codex/devdocs/eval.md | 2 +- codex/devdocs/offset-arrays.md | 98 +++++++++---------------- codex/manual/control-flow.md | 2 +- codex/manual/interfaces.md | 16 ++-- codex/manual/mathematical-operations.md | 1 + codex/manual/parallel-computing.md | 4 +- codex/manual/strings.md | 20 ++--- codex/manual/types.md | 26 +++---- codex/stdlib/Pkg.md | 47 ++++++++++-- src/NEWS.md | 13 +++- src/base/base.md | 1 + src/devdocs/eval.md | 2 +- src/devdocs/offset-arrays.md | 98 +++++++++---------------- src/manual/control-flow.md | 2 +- src/manual/interfaces.md | 16 ++-- src/manual/mathematical-operations.md | 1 + src/manual/parallel-computing.md | 4 +- src/manual/strings.md | 20 ++--- src/manual/types.md | 26 +++---- src/stdlib/Pkg.md | 47 ++++++++++-- 22 files changed, 241 insertions(+), 218 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index 847d70e..33e3d42 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -14,7 +14,7 @@ New language features * Named tuples, with the syntax `(a=1, b=2)`. These behave very similarly to tuples, except components can also be accessed by name using dot syntax `t.a` ([#22194](https://github.com/JuliaLang/julia/issues/22194)). - * Keyword argument containers (`kw` in `f(; kw...)`) are now named tuples. Dictionary + * Keyword argument containers (`kw` in `f(; kw...)`) are now based on named tuples. Dictionary functions like `haskey` and indexing can be used on them, and name-value pairs can be iterated using `pairs(kw)`. `kw` can no longer contain multiple entries for the same argument name ([#4916](https://github.com/JuliaLang/julia/issues/4916)). @@ -226,6 +226,10 @@ Language changes * `try` blocks without `catch` or `finally` are no longer allowed. An explicit empty `catch` block should be written instead ([#27554](https://github.com/JuliaLang/julia/issues/27554)). + * `AbstractArray` types that use unconventional (not 1-based) indexing can now support + `size`, `length`, and `@inbounds`. To optionally enforce conventional indices, + you can `@assert !has_offset_axes(A)`. + Breaking changes ---------------- @@ -496,8 +500,7 @@ This section lists changes that do not have deprecation warnings. * `isequal` for `Ptr`s now compares element types; `==` still compares only addresses ([#26858](https://github.com/JuliaLang/julia/issues/26858)). - * `widen` on 8- and 16-bit integer types now widens to the platform word size (`Int`) - instead of to a 32-bit type ([#26859](https://github.com/JuliaLang/julia/issues/26859)). + * `widen` on 8- and 16-bit integer types now widens to 16- and 32-bit types, respectively. ([#28045](https://github.com/JuliaLang/julia/issues/28045)). * `mv`,`cp`, `touch`, `mkdir`, `mkpath`, `chmod` and `chown` now return the path that was created/modified rather than `nothing` ([#27071](https://github.com/JuliaLang/julia/issues/27071)). @@ -721,7 +724,8 @@ Library improvements * The initial element `v0` in `reduce(op, v0, itr)` has been replaced with an `init` optional keyword argument, as in `reduce(op, itr; init=v0)`. Similarly for `foldl`, - `foldr`, `mapreduce`, `mapfoldl` and `mapfoldr`. ([#27711](https://github.com/JuliaLang/julia/issues/27711)) + `foldr`, `mapreduce`, `mapfoldl`, `mapfoldr`, `accumulate` and `accumulate!`. + ([#27711](https://github.com/JuliaLang/julia/issues/27711), [#27859](https://github.com/JuliaLang/julia/issues/27859)) Compiler/Runtime improvements ----------------------------- diff --git a/codex/base/base.md b/codex/base/base.md index cea99f4..44d0fa2 100644 --- a/codex/base/base.md +++ b/codex/base/base.md @@ -288,6 +288,7 @@ Base.@assert Base.ArgumentError Base.AssertionError Core.BoundsError +Base.CompositeException Base.DimensionMismatch Core.DivideError Core.DomainError diff --git a/codex/devdocs/eval.md b/codex/devdocs/eval.md index 3922ef6..f91d379 100644 --- a/codex/devdocs/eval.md +++ b/codex/devdocs/eval.md @@ -83,7 +83,7 @@ although it can also be invoked directly by a call to [`macroexpand()`](@ref)/`j ## [Type Inference](@id dev-type-inference) -Type inference is implemented in Julia by [`typeinf()` in `compiler/typeinf.jl`](https://github.com/JuliaLang/julia/blob/master/base/compiler/typeinf.jl). +Type inference is implemented in Julia by [`typeinf()` in `compiler/typeinfer.jl`](https://github.com/JuliaLang/julia/blob/master/base/compiler/typeinfer.jl). Type inference is the process of examining a Julia function and determining bounds for the types of each of its variables, as well as bounds on the type of the return value from the function. This enables many future optimizations, such as unboxing of known immutable values, and compile-time diff --git a/codex/devdocs/offset-arrays.md b/codex/devdocs/offset-arrays.md index 9bca679..3464b94 100644 --- a/codex/devdocs/offset-arrays.md +++ b/codex/devdocs/offset-arrays.md @@ -1,17 +1,25 @@ # [Arrays with custom indices](@id man-custom-indices) -Julia 0.5 adds experimental support for arrays with arbitrary indices. Conventionally, Julia's +Conventionally, Julia's arrays are indexed starting at 1, whereas some other languages start numbering at 0, and yet others (e.g., Fortran) allow you to specify arbitrary starting indices. While there is much merit in picking a standard (i.e., 1 for Julia), there are some algorithms which simplify considerably -if you can index outside the range `1:size(A,d)` (and not just `0:size(A,d)-1`, either). Such -array types are expected to be supplied through packages. +if you can index outside the range `1:size(A,d)` (and not just `0:size(A,d)-1`, either). +To facilitate such computations, Julia supports arrays with arbitrary indices. The purpose of this page is to address the question, "what do I have to do to support such arrays in my own code?" First, let's address the simplest case: if you know that your code will never need to handle arrays with unconventional indexing, hopefully the answer is "nothing." Old code, on conventional arrays, should function essentially without alteration as long as it was using the exported interfaces of Julia. +If you find it more convenient to just force your users to supply traditional arrays where indexing starts at one, you can add + +```julia +@assert !Base.has_offset_axes(arrays...) +``` + +where `arrays...` is a list of the array objects that you wish to check for anything that +violates 1-based indexing. ## Generalizing existing code @@ -19,16 +27,16 @@ As an overview, the steps are: * replace many uses of `size` with `axes` * replace `1:length(A)` with `eachindex(A)`, or in some cases `LinearIndices(A)` - * replace `length(A)` with `length(LinearIndices(A))` * replace explicit allocations like `Array{Int}(size(B))` with `similar(Array{Int}, axes(B))` These are described in more detail below. -### Background +### Things to watch out for -Because unconventional indexing breaks deeply-held assumptions throughout the Julia ecosystem, -early adopters running code that has not been updated are likely to experience errors. The most -frustrating bugs would be incorrect results or segfaults (total crashes of Julia). For example, +Because unconventional indexing breaks many people's assumptions that all arrays start indexing with 1, there is always the chance that using such arrays will trigger errors. +The most +frustrating bugs would be incorrect results or segfaults (total crashes of Julia). +For example, consider the following function: ```julia @@ -42,16 +50,10 @@ function mycopy!(dest::AbstractVector, src::AbstractVector) end ``` -This code implicitly assumes that vectors are indexed from 1. Previously that was a safe assumption, -so this code was fine, but (depending on what types the user passes to this function) it may no -longer be safe. If this code continued to work when passed a vector with non-1 indices, it would -either produce an incorrect answer or it would segfault. (If you do get segfaults, to help locate +This code implicitly assumes that vectors are indexed from 1; if `dest` starts at a different index than `src`, there is a chance that this code would trigger a segfault. +(If you do get segfaults, to help locate the cause try running julia with the option `--check-bounds=yes`.) -To ensure that such errors are caught, in Julia 0.5 both `length` and `size`**should** throw an -error when passed an array with non-1 indexing. This is designed to force users of such arrays -to check the code, and inspect it for whether it needs to be generalized. - ### Using `axes` for bounds checks and loop iteration `axes(A)` (reminiscent of `size(A)`) returns a tuple of `AbstractUnitRange` objects, specifying @@ -62,14 +64,7 @@ is `axes(A, d)`. Base implements a custom range type, `OneTo`, where `OneTo(n)` means the same thing as `1:n` but in a form that guarantees (via the type system) that the lower index is 1. For any new [`AbstractArray`](@ref) type, this is the default returned by `axes`, and it indicates that this array type uses "conventional" -1-based indexing. Note that if you don't want to be bothered supporting arrays with non-1 indexing, -you can add the following line: - -```julia -@assert all(x->isa(x, Base.OneTo), axes(A)) -``` - -at the top of any function. +1-based indexing. For bounds checking, note that there are dedicated functions `checkbounds` and `checkindex` which can sometimes simplify such tests. @@ -115,40 +110,11 @@ then "wrap" it in a type that shifts the indices.) Note also that `similar(Array{Int}, (axes(A, 2),))` would allocate an `AbstractVector{Int}` (i.e., 1-dimensional array) that matches the indices of the columns of `A`. -### Deprecations - -In generalizing Julia's code base, at least one deprecation was unavoidable: earlier versions -of Julia defined `first(::Colon) = 1`, meaning that the first index along a dimension indexed -by `:` is 1. This definition can no longer be justified, so it was deprecated. There is no provided -replacement, because the proper replacement depends on what you are doing and might need to know -more about the array. However, it appears that many uses of `first(::Colon)` are really about -computing an index offset; when that is the case, a candidate replacement is: - -```julia -indexoffset(r::AbstractVector) = first(r) - 1 -indexoffset(::Colon) = 0 -``` - -In other words, while `first(:)` does not itself make sense, in general you can say that the offset -associated with a colon-index is zero. - ## Writing custom array types with non-1 indexing Most of the methods you'll need to define are standard for any `AbstractArray` type, see [Abstract Arrays](@ref man-interface-array). This page focuses on the steps needed to define unconventional indexing. -### Do **not** implement `size` or `length` - -Perhaps the majority of pre-existing code that uses `size` will not work properly for arrays with -non-1 indices. For that reason, it is much better to avoid implementing these methods, and use -the resulting `MethodError` to identify code that needs to be audited and perhaps generalized. - -### Do **not** annotate bounds checks - -Julia 0.5 includes `@boundscheck` to annotate code that can be removed for callers that exploit -`@inbounds`. Initially, it seems far preferable to run with bounds checking always enabled (i.e., -omit the `@boundscheck` annotation so the check always runs). - ### Custom `AbstractUnitRange` types If you're writing a non-1 indexed array type, you will want to specialize `axes` so it returns @@ -223,15 +189,21 @@ Base.reshape(A::AbstractArray, shape::Tuple{ZeroRange,Vararg{ZeroRange}}) = ... and you can `reshape` an array so that the result has custom indices. -## Summary +### For objects that mimic AbstractArray but are not subtypes + +`has_offset_axes` depends on having `axes` defined for the objects you call it on. If there is +some reason you don't have an `axes` method defined for your object, consider defining a method +```julia +Base.has_offset_axes(obj::MyNon1IndexedArraylikeObject) = true +``` +This will allow code that assumes 1-based indexing to detect a problem +and throw a helpful error, rather than returning incorrect results or +segfaulting julia. + +### Catching errors -Writing code that doesn't make assumptions about indexing requires a few extra abstractions, but -hopefully the necessary changes are relatively straightforward. +If your new array type triggers errors in other code, one helpful debugging step can be to comment out `@boundscheck` in your `getindex` and `setindex!` implementation. +This will ensure that every element access checks bounds. Or, restart julia with `--check-bounds=yes`. -As a reminder, this support is still experimental. While much of Julia's base code has been updated -to support unconventional indexing, without a doubt there are many omissions that will be discovered -only through usage. Moreover, at the time of this writing, most packages do not support unconventional -indexing. As a consequence, early adopters should be prepared to identify and/or fix bugs. On -the other hand, only through practical usage will it become clear whether this experimental feature -should be retained in future versions of Julia; consequently, interested parties are encouraged -to accept some ownership for putting it through its paces. +In some cases it may also be helpful to temporarily disable `size` and `length` for your new array type, +since code that makes incorrect assumptions frequently uses these functions. diff --git a/codex/manual/control-flow.md b/codex/manual/control-flow.md index 44e034e..f73e523 100644 --- a/codex/manual/control-flow.md +++ b/codex/manual/control-flow.md @@ -563,7 +563,7 @@ below all interrupt the normal flow of control. |:----------------------------- | | [`ArgumentError`](@ref) | | [`BoundsError`](@ref) | -| `CompositeException` | +| [`CompositeException`](@ref) | | [`DivideError`](@ref) | | [`DomainError`](@ref) | | [`EOFError`](@ref) | diff --git a/codex/manual/interfaces.md b/codex/manual/interfaces.md index 618f55f..d21c493 100644 --- a/codex/manual/interfaces.md +++ b/codex/manual/interfaces.md @@ -9,18 +9,18 @@ to generically build upon those behaviors. | Required methods |   | Brief description | |:------------------------------ |:---------------------- |:------------------------------------------------------------------------------------- | -| `iterate(iter)` |   | Returns either a tuple of the first item and initial state or `nothing` if empty | +| `iterate(iter)` |   | Returns either a tuple of the first item and initial state or [`nothing`](@ref) if empty | | `iterate(iter, state)` |   | Returns either a tuple of the next item and next state or `nothing` if no items remain | | **Important optional methods** | **Default definition** | **Brief description** | | `IteratorSize(IterType)` | `HasLength()` | One of `HasLength()`, `HasShape{N}()`, `IsInfinite()`, or `SizeUnknown()` as appropriate | | `IteratorEltype(IterType)` | `HasEltype()` | Either `EltypeUnknown()` or `HasEltype()` as appropriate | -| `eltype(IterType)` | `Any` | The type of the first entry of the tuple returned by `iterate()` | +| `eltype(IterType)` | `Any` | The type of the first entry of the tuple returned by `iterate()` | | `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)` | +| `HasLength()` | [`length(iter)`](@ref) | | `HasShape{N}()` | `length(iter)` and `size(iter, [dim...])` | | `IsInfinite()` | (*none*) | | `SizeUnknown()` | (*none*) | @@ -38,7 +38,7 @@ The state object will be passed back to the iterate function on the next iterati and is generally considered an implementation detail private to the iterable object. Any object that defines this function is iterable and can be used in the [many functions that rely upon iteration](@ref lib-collections-iteration). -It can also be used directly in a `for` loop since the syntax: +It can also be used directly in a [`for`](@ref) loop since the syntax: ```julia for i in iter # or "for i = iter" @@ -258,7 +258,7 @@ efficiently converts the indices into one linear index and then calls the above arrays, on the other hand, require methods to be defined for each supported dimensionality with `ndims(A)` `Int` indices. For example, [`SparseMatrixCSC`](@ref) from the `SparseArrays` standard library module, only supports two dimensions, so it just defines -`getindex(A::SparseMatrixCSC, i::Int, j::Int)`. The same holds for `setindex!`. +`getindex(A::SparseMatrixCSC, i::Int, j::Int)`. The same holds for [`setindex!`](@ref). Returning to the sequence of squares from above, we could instead define it as a subtype of an `AbstractArray{Int, 1}`: @@ -396,7 +396,7 @@ julia> sum(A) ``` If you are defining an array type that allows non-traditional indexing (indices that start at -something other than 1), you should specialize `axes`. You should also specialize [`similar`](@ref) +something other than 1), you should specialize [`axes`](@ref). 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 man-custom-indices). @@ -463,13 +463,13 @@ The [`Base.broadcastable`](@ref) function is called on each argument to broadcas it to return something different that supports `axes` and indexing. By default, this is the identity function for all `AbstractArray`s and `Number`s — they already support `axes` and indexing. For a handful of other types (including but not limited to -types themselves, functions, special singletons like `missing` and `nothing`, and dates), +types themselves, functions, special singletons like [`missing`](@ref) and [`nothing`](@ref), and dates), `Base.broadcastable` returns the argument wrapped in a `Ref` to act as a 0-dimensional "scalar" for the purposes of broadcasting. Custom types can similarly specialize `Base.broadcastable` to define their shape, but they should follow the convention that `collect(Base.broadcastable(x)) == collect(x)`. A notable exception is `AbstractString`; strings are special-cased to behave as scalars for the purposes of broadcast even though -they are iterable collections of their characters. +they are iterable collections of their characters (see [Strings](@ref) for more). The next two steps (selecting the output array and implementation) are dependent upon determining a single answer for a given set of arguments. Broadcast must take all the varied diff --git a/codex/manual/mathematical-operations.md b/codex/manual/mathematical-operations.md index 0e60705..456146a 100644 --- a/codex/manual/mathematical-operations.md +++ b/codex/manual/mathematical-operations.md @@ -366,6 +366,7 @@ Julia applies the following order and associativity of operations, from highest | Syntax | `<\|` | Right | | Comparisons | `> < >= <= == === != !== <:` | Non-associative | | Control flow | `&&` followed by `\|\|` followed by `?` | Right | +| Pair | `=>` | Right | | Assignments | `= += -= *= /= //= \= ^= ÷= %= \|= &= ⊻= <<= >>= >>>=` | Right | [^1]: diff --git a/codex/manual/parallel-computing.md b/codex/manual/parallel-computing.md index 320983c..7efd4a4 100644 --- a/codex/manual/parallel-computing.md +++ b/codex/manual/parallel-computing.md @@ -1143,7 +1143,7 @@ Newly launched workers are connected to each other and the master process in an Specifying the command line argument `--worker[=]` results in the launched processes initializing themselves as workers and connections being set up via TCP/IP sockets. -All workers in a cluster share the same [cookie](#cluster-cookie) as the master. When the cookie is +All workers in a cluster share the same [cookie](@ref man-cluster-cookie) as the master. When the cookie is unspecified, i.e, with the `--worker` option, the worker tries to read it from its standard input. `LocalManager` and `SSHManager` both pass the cookie to newly launched workers via their standard inputs. @@ -1306,7 +1306,7 @@ requirements for the inbuilt `LocalManager` and `SSHManager`: Securing and encrypting all worker-worker traffic (via SSH) or encrypting individual messages can be done via a custom `ClusterManager`. -## Cluster Cookie +## [Cluster Cookie](@id man-cluster-cookie) All processes in a cluster share the same cookie which, by default, is a randomly generated string on the master process: diff --git a/codex/manual/strings.md b/codex/manual/strings.md index 5494e6a..304b3c2 100644 --- a/codex/manual/strings.md +++ b/codex/manual/strings.md @@ -29,7 +29,7 @@ There are a few noteworthy high-level features about Julia's strings: a string argument, you should declare the type as `AbstractString` in order to accept any string type. * Like C and Java, but unlike most dynamic languages, Julia has a first-class type for representing - a single character, called `AbstractChar`. The built-in `Char` subtype of `AbstractChar` + a single character, called [`AbstractChar`](@ref). The built-in [`Char`](@ref) subtype of `AbstractChar` is a 32-bit primitive type that can represent any Unicode character (and which is based on the UTF-8 encoding). * As in Java, strings are immutable: the value of an `AbstractString` object cannot be changed. @@ -42,7 +42,7 @@ There are a few noteworthy high-level features about Julia's strings: ## [Characters](@id man-characters) -An `Char` value represents a single character: it is just a 32-bit primitive type with a special literal +A `Char` value represents a single character: it is just a 32-bit primitive type with a special literal representation and appropriate arithmetic behaviors, and which can be converted to a numeric value representing a [Unicode code point](https://en.wikipedia.org/wiki/Code_point). (Julia packages may define @@ -58,7 +58,7 @@ julia> typeof(ans) Char ``` -You can convert a `Char` to its integer value, i.e. code point, easily: +You can easily convert a `Char` to its integer value, i.e. code point: ```jldoctest julia> Int('x') @@ -187,7 +187,7 @@ Most indexing in Julia is 1-based: the first element of many integer-indexed obj index 1. (As we will see below, this does not necessarily mean that the last element is found at index `n`, where `n` is the length of the string.) -You can perform arithmetic and other operations with `end`, just like +You can perform arithmetic and other operations with [`end`](@ref), just like a normal value: ```jldoctest helloworldstring @@ -419,8 +419,8 @@ julia> string(greet, ", ", whom, ".\n") "Hello, world.\n" ``` -A situation which is important to be aware of is when invalid UTF-8 strings are concatenated. -In that case the resulting string may contain different characters than the input strings, +It's important to be aware of potentially dangerous situations such as concatenation of invalid UTF-8 strings. +The resulting string may contain different characters than the input strings, and its number of characters may be lower than sum of numbers of characters of the concatenated strings, e.g.: @@ -447,7 +447,7 @@ julia> length.([a, b, c]) This situation can happen only for invalid UTF-8 strings. For valid UTF-8 strings concatenation preserves all characters in strings and additivity of string lengths. -Julia also provides `*` for string concatenation: +Julia also provides [`*`](@ref) for string concatenation: ```jldoctest stringconcat julia> greet * ", " * whom * ".\n" @@ -581,7 +581,7 @@ hello""" will contain a literal newline at the beginning. -Stripping of the newline is performed after the dedentation for example: +Stripping of the newline is performed after the dedentation. For example: ```jldoctest julia> """ @@ -732,7 +732,7 @@ julia> match(r"^\s*(?:#|$)", "# a comment") RegexMatch("#") ``` -If the regular expression does not match the given string, [`match`](@ref) returns `nothing` +If the regular expression does not match the given string, [`match`](@ref) returns [`nothing`](@ref) -- a special value that does not print anything at the interactive prompt. Other than not printing, it is a completely normal value and you can test for it programmatically: @@ -1037,7 +1037,7 @@ is equivalent to `v"0.2.0"` (with empty pre-release/build annotations), `v"2"` i `v"2.0.0"`, and so on. `VersionNumber` objects are mostly useful to easily and correctly compare two (or more) versions. -For example, the constant `VERSION` holds Julia version number as a `VersionNumber` object, and +For example, the constant [`VERSION`](@ref) holds Julia version number as a `VersionNumber` object, and therefore one can define some version-specific behavior using simple statements as: ```julia diff --git a/codex/manual/types.md b/codex/manual/types.md index a56ffd2..08de781 100644 --- a/codex/manual/types.md +++ b/codex/manual/types.md @@ -43,7 +43,7 @@ up front are: * Only values, not variables, have types -- variables are simply names bound to values. * Both abstract and concrete types can be parameterized by other types. They can also be parameterized by symbols, by values of any type for which [`isbits`](@ref) returns true (essentially, things - like numbers and bools that are stored like C types or structs with no pointers to other objects), + like numbers and bools that are stored like C types or `struct`s with no pointers to other objects), and also by tuples thereof. Type parameters may be omitted when they do not need to be referenced or restricted. @@ -148,7 +148,7 @@ numbers. Abstract types allow the construction of a hierarchy of types, providin into which concrete types can fit. This allows you, for example, to easily program to any type that is an integer, without restricting an algorithm to a specific type of integer. -Abstract types are declared using the `abstract type` keyword. The general syntaxes for declaring an +Abstract types are declared using the [`abstract type`](@ref) keyword. The general syntaxes for declaring an abstract type are: ``` @@ -157,7 +157,7 @@ abstract type «name» <: «supertype» end ``` The `abstract type` keyword introduces a new abstract type, whose name is given by `«name»`. This -name can be optionally followed by `<:` and an already-existing type, indicating that the newly +name can be optionally followed by [`<:`](@ref) and an already-existing type, indicating that the newly declared abstract type is a subtype of this "parent" type. When no supertype is given, the default supertype is `Any` -- a predefined abstract type that @@ -309,7 +309,7 @@ for more information on methods and dispatch). Thus, it would be inappropriate f named bags of methods "inside" each object ends up being a highly beneficial aspect of the language design. -Composite types are introduced with the `struct` keyword followed by a block of field names, optionally +Composite types are introduced with the [`struct`](@ref) keyword followed by a block of field names, optionally annotated with types using the `::` operator: ```jldoctest footype @@ -349,7 +349,7 @@ Stacktrace: [...] ``` -You may find a list of field names using the `fieldnames` function. +You may find a list of field names using the [`fieldnames`](@ref) function. ```jldoctest footype julia> fieldnames(Foo) @@ -381,7 +381,7 @@ An immutable object might contain mutable objects, such as arrays, as fields. Th objects will remain mutable; only the fields of the immutable object itself cannot be changed to point to different objects. -Where required, mutable composite objects can be declared with the keyword `mutable struct`, to be +Where required, mutable composite objects can be declared with the keyword [`mutable struct`](@ref), to be discussed in the next section. Immutable composite types with no fields are singletons; there can be only one instance of such types: @@ -394,7 +394,7 @@ julia> NoFields() === NoFields() true ``` -The `===` function confirms that the "two" constructed instances of `NoFields` are actually one +The [`===`](@ref) function confirms that the "two" constructed instances of `NoFields` are actually one and the same. Singleton types are described in further detail [below](@ref man-singleton-types). There is much more to say about how instances of composite types are created, but that discussion @@ -480,7 +480,7 @@ Every concrete value in the system is an instance of some `DataType`. ## Type Unions A type union is a special abstract type which includes as objects all instances of any of its -argument types, constructed using the special `Union` keyword: +argument types, constructed using the special [`Union`](@ref) keyword: ```jldoctest julia> IntOrString = Union{Int,AbstractString} @@ -502,7 +502,7 @@ presence of `Union` types with a small number of types [^1], by generating speci in separate branches for each possible type. A particularly useful case of a `Union` type is `Union{T, Nothing}`, where `T` can be any type and -[`Nothing`](@ref) is the singleton type whose only instance is the object `nothing`. This pattern +[`Nothing`](@ref) is the singleton type whose only instance is the object [`nothing`](@ref). This pattern is the Julia equivalent of [`Nullable`, `Option` or `Maybe`](https://en.wikipedia.org/wiki/Nullable_type) types in other languages. Declaring a function argument or a field as `Union{T, Nothing}` allows setting it either to a value of type `T`, or to `nothing` to indicate that there is no value. @@ -887,7 +887,7 @@ signature (when the signature matches). ### Vararg Tuple Types -The last parameter of a tuple type can be the special type `Vararg`, which denotes any number +The last parameter of a tuple type can be the special type [`Vararg`](@ref), which denotes any number of trailing elements: ```jldoctest @@ -1012,7 +1012,7 @@ is that the type parameter `T` is not used in the definition of the type itself an abstract tag, essentially defining an entire family of types with identical structure, differentiated only by their type parameter. Thus, `Ptr{Float64}` and `Ptr{Int64}` are distinct types, even though they have identical representations. And of course, all specific pointer types are subtypes of -the umbrella `Ptr` type: +the umbrella [`Ptr`](@ref) type: ```jldoctest julia> Ptr{Float64} <: Ptr @@ -1028,7 +1028,7 @@ We have said that a parametric type like `Ptr` acts as a supertype of all its in (`Ptr{Int64}` etc.). How does this work? `Ptr` itself cannot be a normal data type, since without knowing the type of the referenced data the type clearly cannot be used for memory operations. The answer is that `Ptr` (or other parametric types like `Array`) is a different kind of type called a -`UnionAll` type. Such a type expresses the *iterated union* of types for all values of some parameter. +[`UnionAll`](@ref) type. Such a type expresses the *iterated union* of types for all values of some parameter. `UnionAll` types are usually written using the keyword `where`. For example `Ptr` could be more accurately written as `Ptr{T} where T`, meaning all values whose type is `Ptr{T}` for some value @@ -1377,7 +1377,7 @@ of custom types. By way of illustration of this idea, let's introduce a parametr and a constructor `Val(x) = Val{x}()`, which serves as a customary way to exploit this technique for cases where you don't need a more elaborate hierarchy. -`Val` is defined as: +[`Val`](@ref) is defined as: ```jldoctest valtype julia> struct Val{x} diff --git a/codex/stdlib/Pkg.md b/codex/stdlib/Pkg.md index 6e9c8f4..2f9888d 100644 --- a/codex/stdlib/Pkg.md +++ b/codex/stdlib/Pkg.md @@ -456,7 +456,7 @@ shell> cat ~/.julia/packages/MbedTLS/h1Vu/deps/build.log So far we have added packages to the default project at `~/.julia/environments/v0.7`, it is, however, easy to create other, independent, projects. It should be pointed out if two projects uses the same package at the same version, the content of this package is not duplicated. -This is done using the `init` command. Below we make a new directory and create a new project in it: +In order to create a new project, create a directory for it and then activate that directory to make it the "active project" which package operations manipulate: ``` shell> mkdir MyProject @@ -464,16 +464,49 @@ shell> mkdir MyProject shell> cd MyProject /Users/kristoffer/MyProject -(v0.7) pkg> init -Initialized project at /Users/kristoffer/MyProject/Project.toml +(v0.7) pkg> activate . (MyProject) pkg> st Status `Project.toml` ``` -Note that the REPL prompt changed when the new project was initiated, in other words, Pkg automatically set the current environment to the -one that just got initiated. Since this is a newly created project, the status command show it contains no packages. -Packages added here again in a completely separate environment from the one earlier used. +Note that the REPL prompt changed when the new project is activated. Since this is a newly created project, the status command show it contains no packages, and in fact, it has no project or manifest file until we add a package to it: + +``` +shell> ls -l +total 0 + +(MyProject) pkg> add Example + Updating registry at `~/.julia/registries/Uncurated` + Updating git-repo `https://github.com/JuliaRegistries/Uncurated.git` + Resolving package versions... + Updating `Project.toml` + [7876af07] + Example v0.5.1 + Updating `Manifest.toml` + [7876af07] + Example v0.5.1 + [8dfed614] + Test + +shell> ls -l +total 8 +-rw-r--r-- 1 stefan staff 207 Jul 3 16:35 Manifest.toml +-rw-r--r-- 1 stefan staff 56 Jul 3 16:35 Project.toml + +shell> cat Project.toml +[deps] +Example = "7876af07-990d-54b4-ab0e-23690620f79a" + +shell> cat Manifest.toml +[[Example]] +deps = ["Test"] +git-tree-sha1 = "8eb7b4d4ca487caade9ba3e85932e28ce6d6e1f8" +uuid = "7876af07-990d-54b4-ab0e-23690620f79a" +version = "0.5.1" + +[[Test]] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +``` + +This new environment is completely separate from the one we used earlier. ## Garbage collecting old, unused packages @@ -661,7 +694,7 @@ This is possible by adding dependencies to a "test target" to the Project file. test-only dependency by adding the following to the Project file: ``` -[target.test.deps] +[targets.test.deps] Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" ``` diff --git a/src/NEWS.md b/src/NEWS.md index dc06803..bacf289 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -12,7 +12,7 @@ * 네임드 터플(이름을 갖는 터플, named tuples). 문법은 `(a=1, b=2)` 이런 식입니다. 터플처럼 쓰면 되는데 .이름 `t.a` 이런 식으로 해당 요소에 접근할 수 있습니다 ([#22194](https://github.com/JuliaLang/julia/issues/22194)). - * 키워드 인자 컨테이너(`f(; kw...)` 에서 `kw`)는 네임드 터플입니다. `haskey`와 같은 딕셔너리 함수로 인덱싱할 수 있고, + * 키워드 인자 컨테이너(`f(; kw...)` 에서 `kw`)는 네임드 터플(named tuples)을 기반으로 합니다. `haskey`와 같은 딕셔너리 함수로 인덱싱할 수 있고, 이름-값 쌍은 `pairs(kw)`를 사용하여 차례대로 접근할 수 있습니다. `kw`는 더 이상 같은 인자 이름을 중복하여 쓸 수 없습니다 ([#4916](https://github.com/JuliaLang/julia/issues/4916)). * 사용자 정의 infix 연산자를 유니코드 결합 기호, 부호, 윗/아래 첨자로 정의할 수 있습니다. @@ -214,6 +214,10 @@ Language changes * `try` blocks without `catch` or `finally` are no longer allowed. An explicit empty `catch` block should be written instead ([#27554](https://github.com/JuliaLang/julia/issues/27554)). + * `AbstractArray` types that use unconventional (not 1-based) indexing can now support + `size`, `length`, and `@inbounds`. To optionally enforce conventional indices, + you can `@assert !has_offset_axes(A)`. + Breaking changes ---------------- @@ -484,8 +488,8 @@ This section lists changes that do not have deprecation warnings. * `isequal` for `Ptr`s now compares element types; `==` still compares only addresses ([#26858](https://github.com/JuliaLang/julia/issues/26858)). - * `widen` on 8- and 16-bit integer types now widens to the platform word size (`Int`) - instead of to a 32-bit type ([#26859](https://github.com/JuliaLang/julia/issues/26859)). + * `widen` on 8- and 16-bit integer types now widens to 16- and 32-bit types, respectively. ([#28045](https://github.com/JuliaLang/julia/issues/28045)). + * `mv`,`cp`, `touch`, `mkdir`, `mkpath`, `chmod` and `chown` now return the path that was created/modified rather than `nothing` ([#27071](https://github.com/JuliaLang/julia/issues/27071)). @@ -709,7 +713,8 @@ Library improvements * The initial element `v0` in `reduce(op, v0, itr)` has been replaced with an `init` optional keyword argument, as in `reduce(op, itr; init=v0)`. Similarly for `foldl`, - `foldr`, `mapreduce`, `mapfoldl` and `mapfoldr`. ([#27711](https://github.com/JuliaLang/julia/issues/27711)) + `foldr`, `mapreduce`, `mapfoldl`, `mapfoldr`, `accumulate` and `accumulate!`. + ([#27711](https://github.com/JuliaLang/julia/issues/27711), [#27859](https://github.com/JuliaLang/julia/issues/27859)) Compiler/Runtime improvements ----------------------------- diff --git a/src/base/base.md b/src/base/base.md index cea99f4..44d0fa2 100644 --- a/src/base/base.md +++ b/src/base/base.md @@ -288,6 +288,7 @@ Base.@assert Base.ArgumentError Base.AssertionError Core.BoundsError +Base.CompositeException Base.DimensionMismatch Core.DivideError Core.DomainError diff --git a/src/devdocs/eval.md b/src/devdocs/eval.md index 3922ef6..f91d379 100644 --- a/src/devdocs/eval.md +++ b/src/devdocs/eval.md @@ -83,7 +83,7 @@ although it can also be invoked directly by a call to [`macroexpand()`](@ref)/`j ## [Type Inference](@id dev-type-inference) -Type inference is implemented in Julia by [`typeinf()` in `compiler/typeinf.jl`](https://github.com/JuliaLang/julia/blob/master/base/compiler/typeinf.jl). +Type inference is implemented in Julia by [`typeinf()` in `compiler/typeinfer.jl`](https://github.com/JuliaLang/julia/blob/master/base/compiler/typeinfer.jl). Type inference is the process of examining a Julia function and determining bounds for the types of each of its variables, as well as bounds on the type of the return value from the function. This enables many future optimizations, such as unboxing of known immutable values, and compile-time diff --git a/src/devdocs/offset-arrays.md b/src/devdocs/offset-arrays.md index 9bca679..3464b94 100644 --- a/src/devdocs/offset-arrays.md +++ b/src/devdocs/offset-arrays.md @@ -1,17 +1,25 @@ # [Arrays with custom indices](@id man-custom-indices) -Julia 0.5 adds experimental support for arrays with arbitrary indices. Conventionally, Julia's +Conventionally, Julia's arrays are indexed starting at 1, whereas some other languages start numbering at 0, and yet others (e.g., Fortran) allow you to specify arbitrary starting indices. While there is much merit in picking a standard (i.e., 1 for Julia), there are some algorithms which simplify considerably -if you can index outside the range `1:size(A,d)` (and not just `0:size(A,d)-1`, either). Such -array types are expected to be supplied through packages. +if you can index outside the range `1:size(A,d)` (and not just `0:size(A,d)-1`, either). +To facilitate such computations, Julia supports arrays with arbitrary indices. The purpose of this page is to address the question, "what do I have to do to support such arrays in my own code?" First, let's address the simplest case: if you know that your code will never need to handle arrays with unconventional indexing, hopefully the answer is "nothing." Old code, on conventional arrays, should function essentially without alteration as long as it was using the exported interfaces of Julia. +If you find it more convenient to just force your users to supply traditional arrays where indexing starts at one, you can add + +```julia +@assert !Base.has_offset_axes(arrays...) +``` + +where `arrays...` is a list of the array objects that you wish to check for anything that +violates 1-based indexing. ## Generalizing existing code @@ -19,16 +27,16 @@ As an overview, the steps are: * replace many uses of `size` with `axes` * replace `1:length(A)` with `eachindex(A)`, or in some cases `LinearIndices(A)` - * replace `length(A)` with `length(LinearIndices(A))` * replace explicit allocations like `Array{Int}(size(B))` with `similar(Array{Int}, axes(B))` These are described in more detail below. -### Background +### Things to watch out for -Because unconventional indexing breaks deeply-held assumptions throughout the Julia ecosystem, -early adopters running code that has not been updated are likely to experience errors. The most -frustrating bugs would be incorrect results or segfaults (total crashes of Julia). For example, +Because unconventional indexing breaks many people's assumptions that all arrays start indexing with 1, there is always the chance that using such arrays will trigger errors. +The most +frustrating bugs would be incorrect results or segfaults (total crashes of Julia). +For example, consider the following function: ```julia @@ -42,16 +50,10 @@ function mycopy!(dest::AbstractVector, src::AbstractVector) end ``` -This code implicitly assumes that vectors are indexed from 1. Previously that was a safe assumption, -so this code was fine, but (depending on what types the user passes to this function) it may no -longer be safe. If this code continued to work when passed a vector with non-1 indices, it would -either produce an incorrect answer or it would segfault. (If you do get segfaults, to help locate +This code implicitly assumes that vectors are indexed from 1; if `dest` starts at a different index than `src`, there is a chance that this code would trigger a segfault. +(If you do get segfaults, to help locate the cause try running julia with the option `--check-bounds=yes`.) -To ensure that such errors are caught, in Julia 0.5 both `length` and `size`**should** throw an -error when passed an array with non-1 indexing. This is designed to force users of such arrays -to check the code, and inspect it for whether it needs to be generalized. - ### Using `axes` for bounds checks and loop iteration `axes(A)` (reminiscent of `size(A)`) returns a tuple of `AbstractUnitRange` objects, specifying @@ -62,14 +64,7 @@ is `axes(A, d)`. Base implements a custom range type, `OneTo`, where `OneTo(n)` means the same thing as `1:n` but in a form that guarantees (via the type system) that the lower index is 1. For any new [`AbstractArray`](@ref) type, this is the default returned by `axes`, and it indicates that this array type uses "conventional" -1-based indexing. Note that if you don't want to be bothered supporting arrays with non-1 indexing, -you can add the following line: - -```julia -@assert all(x->isa(x, Base.OneTo), axes(A)) -``` - -at the top of any function. +1-based indexing. For bounds checking, note that there are dedicated functions `checkbounds` and `checkindex` which can sometimes simplify such tests. @@ -115,40 +110,11 @@ then "wrap" it in a type that shifts the indices.) Note also that `similar(Array{Int}, (axes(A, 2),))` would allocate an `AbstractVector{Int}` (i.e., 1-dimensional array) that matches the indices of the columns of `A`. -### Deprecations - -In generalizing Julia's code base, at least one deprecation was unavoidable: earlier versions -of Julia defined `first(::Colon) = 1`, meaning that the first index along a dimension indexed -by `:` is 1. This definition can no longer be justified, so it was deprecated. There is no provided -replacement, because the proper replacement depends on what you are doing and might need to know -more about the array. However, it appears that many uses of `first(::Colon)` are really about -computing an index offset; when that is the case, a candidate replacement is: - -```julia -indexoffset(r::AbstractVector) = first(r) - 1 -indexoffset(::Colon) = 0 -``` - -In other words, while `first(:)` does not itself make sense, in general you can say that the offset -associated with a colon-index is zero. - ## Writing custom array types with non-1 indexing Most of the methods you'll need to define are standard for any `AbstractArray` type, see [Abstract Arrays](@ref man-interface-array). This page focuses on the steps needed to define unconventional indexing. -### Do **not** implement `size` or `length` - -Perhaps the majority of pre-existing code that uses `size` will not work properly for arrays with -non-1 indices. For that reason, it is much better to avoid implementing these methods, and use -the resulting `MethodError` to identify code that needs to be audited and perhaps generalized. - -### Do **not** annotate bounds checks - -Julia 0.5 includes `@boundscheck` to annotate code that can be removed for callers that exploit -`@inbounds`. Initially, it seems far preferable to run with bounds checking always enabled (i.e., -omit the `@boundscheck` annotation so the check always runs). - ### Custom `AbstractUnitRange` types If you're writing a non-1 indexed array type, you will want to specialize `axes` so it returns @@ -223,15 +189,21 @@ Base.reshape(A::AbstractArray, shape::Tuple{ZeroRange,Vararg{ZeroRange}}) = ... and you can `reshape` an array so that the result has custom indices. -## Summary +### For objects that mimic AbstractArray but are not subtypes + +`has_offset_axes` depends on having `axes` defined for the objects you call it on. If there is +some reason you don't have an `axes` method defined for your object, consider defining a method +```julia +Base.has_offset_axes(obj::MyNon1IndexedArraylikeObject) = true +``` +This will allow code that assumes 1-based indexing to detect a problem +and throw a helpful error, rather than returning incorrect results or +segfaulting julia. + +### Catching errors -Writing code that doesn't make assumptions about indexing requires a few extra abstractions, but -hopefully the necessary changes are relatively straightforward. +If your new array type triggers errors in other code, one helpful debugging step can be to comment out `@boundscheck` in your `getindex` and `setindex!` implementation. +This will ensure that every element access checks bounds. Or, restart julia with `--check-bounds=yes`. -As a reminder, this support is still experimental. While much of Julia's base code has been updated -to support unconventional indexing, without a doubt there are many omissions that will be discovered -only through usage. Moreover, at the time of this writing, most packages do not support unconventional -indexing. As a consequence, early adopters should be prepared to identify and/or fix bugs. On -the other hand, only through practical usage will it become clear whether this experimental feature -should be retained in future versions of Julia; consequently, interested parties are encouraged -to accept some ownership for putting it through its paces. +In some cases it may also be helpful to temporarily disable `size` and `length` for your new array type, +since code that makes incorrect assumptions frequently uses these functions. diff --git a/src/manual/control-flow.md b/src/manual/control-flow.md index 57afc3d..d5d8119 100644 --- a/src/manual/control-flow.md +++ b/src/manual/control-flow.md @@ -483,7 +483,7 @@ be different: the second and fourth values would contain `0`. |:----------------------------- | | [`ArgumentError`](@ref) | | [`BoundsError`](@ref) | -| `CompositeException` | +| [`CompositeException`](@ref) | | [`DivideError`](@ref) | | [`DomainError`](@ref) | | [`EOFError`](@ref) | diff --git a/src/manual/interfaces.md b/src/manual/interfaces.md index 618f55f..d21c493 100644 --- a/src/manual/interfaces.md +++ b/src/manual/interfaces.md @@ -9,18 +9,18 @@ to generically build upon those behaviors. | Required methods |   | Brief description | |:------------------------------ |:---------------------- |:------------------------------------------------------------------------------------- | -| `iterate(iter)` |   | Returns either a tuple of the first item and initial state or `nothing` if empty | +| `iterate(iter)` |   | Returns either a tuple of the first item and initial state or [`nothing`](@ref) if empty | | `iterate(iter, state)` |   | Returns either a tuple of the next item and next state or `nothing` if no items remain | | **Important optional methods** | **Default definition** | **Brief description** | | `IteratorSize(IterType)` | `HasLength()` | One of `HasLength()`, `HasShape{N}()`, `IsInfinite()`, or `SizeUnknown()` as appropriate | | `IteratorEltype(IterType)` | `HasEltype()` | Either `EltypeUnknown()` or `HasEltype()` as appropriate | -| `eltype(IterType)` | `Any` | The type of the first entry of the tuple returned by `iterate()` | +| `eltype(IterType)` | `Any` | The type of the first entry of the tuple returned by `iterate()` | | `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)` | +| `HasLength()` | [`length(iter)`](@ref) | | `HasShape{N}()` | `length(iter)` and `size(iter, [dim...])` | | `IsInfinite()` | (*none*) | | `SizeUnknown()` | (*none*) | @@ -38,7 +38,7 @@ The state object will be passed back to the iterate function on the next iterati and is generally considered an implementation detail private to the iterable object. Any object that defines this function is iterable and can be used in the [many functions that rely upon iteration](@ref lib-collections-iteration). -It can also be used directly in a `for` loop since the syntax: +It can also be used directly in a [`for`](@ref) loop since the syntax: ```julia for i in iter # or "for i = iter" @@ -258,7 +258,7 @@ efficiently converts the indices into one linear index and then calls the above arrays, on the other hand, require methods to be defined for each supported dimensionality with `ndims(A)` `Int` indices. For example, [`SparseMatrixCSC`](@ref) from the `SparseArrays` standard library module, only supports two dimensions, so it just defines -`getindex(A::SparseMatrixCSC, i::Int, j::Int)`. The same holds for `setindex!`. +`getindex(A::SparseMatrixCSC, i::Int, j::Int)`. The same holds for [`setindex!`](@ref). Returning to the sequence of squares from above, we could instead define it as a subtype of an `AbstractArray{Int, 1}`: @@ -396,7 +396,7 @@ julia> sum(A) ``` If you are defining an array type that allows non-traditional indexing (indices that start at -something other than 1), you should specialize `axes`. You should also specialize [`similar`](@ref) +something other than 1), you should specialize [`axes`](@ref). 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 man-custom-indices). @@ -463,13 +463,13 @@ The [`Base.broadcastable`](@ref) function is called on each argument to broadcas it to return something different that supports `axes` and indexing. By default, this is the identity function for all `AbstractArray`s and `Number`s — they already support `axes` and indexing. For a handful of other types (including but not limited to -types themselves, functions, special singletons like `missing` and `nothing`, and dates), +types themselves, functions, special singletons like [`missing`](@ref) and [`nothing`](@ref), and dates), `Base.broadcastable` returns the argument wrapped in a `Ref` to act as a 0-dimensional "scalar" for the purposes of broadcasting. Custom types can similarly specialize `Base.broadcastable` to define their shape, but they should follow the convention that `collect(Base.broadcastable(x)) == collect(x)`. A notable exception is `AbstractString`; strings are special-cased to behave as scalars for the purposes of broadcast even though -they are iterable collections of their characters. +they are iterable collections of their characters (see [Strings](@ref) for more). The next two steps (selecting the output array and implementation) are dependent upon determining a single answer for a given set of arguments. Broadcast must take all the varied diff --git a/src/manual/mathematical-operations.md b/src/manual/mathematical-operations.md index 0e60705..456146a 100644 --- a/src/manual/mathematical-operations.md +++ b/src/manual/mathematical-operations.md @@ -366,6 +366,7 @@ Julia applies the following order and associativity of operations, from highest | Syntax | `<\|` | Right | | Comparisons | `> < >= <= == === != !== <:` | Non-associative | | Control flow | `&&` followed by `\|\|` followed by `?` | Right | +| Pair | `=>` | Right | | Assignments | `= += -= *= /= //= \= ^= ÷= %= \|= &= ⊻= <<= >>= >>>=` | Right | [^1]: diff --git a/src/manual/parallel-computing.md b/src/manual/parallel-computing.md index 320983c..7efd4a4 100644 --- a/src/manual/parallel-computing.md +++ b/src/manual/parallel-computing.md @@ -1143,7 +1143,7 @@ Newly launched workers are connected to each other and the master process in an Specifying the command line argument `--worker[=]` results in the launched processes initializing themselves as workers and connections being set up via TCP/IP sockets. -All workers in a cluster share the same [cookie](#cluster-cookie) as the master. When the cookie is +All workers in a cluster share the same [cookie](@ref man-cluster-cookie) as the master. When the cookie is unspecified, i.e, with the `--worker` option, the worker tries to read it from its standard input. `LocalManager` and `SSHManager` both pass the cookie to newly launched workers via their standard inputs. @@ -1306,7 +1306,7 @@ requirements for the inbuilt `LocalManager` and `SSHManager`: Securing and encrypting all worker-worker traffic (via SSH) or encrypting individual messages can be done via a custom `ClusterManager`. -## Cluster Cookie +## [Cluster Cookie](@id man-cluster-cookie) All processes in a cluster share the same cookie which, by default, is a randomly generated string on the master process: diff --git a/src/manual/strings.md b/src/manual/strings.md index 5494e6a..304b3c2 100644 --- a/src/manual/strings.md +++ b/src/manual/strings.md @@ -29,7 +29,7 @@ There are a few noteworthy high-level features about Julia's strings: a string argument, you should declare the type as `AbstractString` in order to accept any string type. * Like C and Java, but unlike most dynamic languages, Julia has a first-class type for representing - a single character, called `AbstractChar`. The built-in `Char` subtype of `AbstractChar` + a single character, called [`AbstractChar`](@ref). The built-in [`Char`](@ref) subtype of `AbstractChar` is a 32-bit primitive type that can represent any Unicode character (and which is based on the UTF-8 encoding). * As in Java, strings are immutable: the value of an `AbstractString` object cannot be changed. @@ -42,7 +42,7 @@ There are a few noteworthy high-level features about Julia's strings: ## [Characters](@id man-characters) -An `Char` value represents a single character: it is just a 32-bit primitive type with a special literal +A `Char` value represents a single character: it is just a 32-bit primitive type with a special literal representation and appropriate arithmetic behaviors, and which can be converted to a numeric value representing a [Unicode code point](https://en.wikipedia.org/wiki/Code_point). (Julia packages may define @@ -58,7 +58,7 @@ julia> typeof(ans) Char ``` -You can convert a `Char` to its integer value, i.e. code point, easily: +You can easily convert a `Char` to its integer value, i.e. code point: ```jldoctest julia> Int('x') @@ -187,7 +187,7 @@ Most indexing in Julia is 1-based: the first element of many integer-indexed obj index 1. (As we will see below, this does not necessarily mean that the last element is found at index `n`, where `n` is the length of the string.) -You can perform arithmetic and other operations with `end`, just like +You can perform arithmetic and other operations with [`end`](@ref), just like a normal value: ```jldoctest helloworldstring @@ -419,8 +419,8 @@ julia> string(greet, ", ", whom, ".\n") "Hello, world.\n" ``` -A situation which is important to be aware of is when invalid UTF-8 strings are concatenated. -In that case the resulting string may contain different characters than the input strings, +It's important to be aware of potentially dangerous situations such as concatenation of invalid UTF-8 strings. +The resulting string may contain different characters than the input strings, and its number of characters may be lower than sum of numbers of characters of the concatenated strings, e.g.: @@ -447,7 +447,7 @@ julia> length.([a, b, c]) This situation can happen only for invalid UTF-8 strings. For valid UTF-8 strings concatenation preserves all characters in strings and additivity of string lengths. -Julia also provides `*` for string concatenation: +Julia also provides [`*`](@ref) for string concatenation: ```jldoctest stringconcat julia> greet * ", " * whom * ".\n" @@ -581,7 +581,7 @@ hello""" will contain a literal newline at the beginning. -Stripping of the newline is performed after the dedentation for example: +Stripping of the newline is performed after the dedentation. For example: ```jldoctest julia> """ @@ -732,7 +732,7 @@ julia> match(r"^\s*(?:#|$)", "# a comment") RegexMatch("#") ``` -If the regular expression does not match the given string, [`match`](@ref) returns `nothing` +If the regular expression does not match the given string, [`match`](@ref) returns [`nothing`](@ref) -- a special value that does not print anything at the interactive prompt. Other than not printing, it is a completely normal value and you can test for it programmatically: @@ -1037,7 +1037,7 @@ is equivalent to `v"0.2.0"` (with empty pre-release/build annotations), `v"2"` i `v"2.0.0"`, and so on. `VersionNumber` objects are mostly useful to easily and correctly compare two (or more) versions. -For example, the constant `VERSION` holds Julia version number as a `VersionNumber` object, and +For example, the constant [`VERSION`](@ref) holds Julia version number as a `VersionNumber` object, and therefore one can define some version-specific behavior using simple statements as: ```julia diff --git a/src/manual/types.md b/src/manual/types.md index a56ffd2..08de781 100644 --- a/src/manual/types.md +++ b/src/manual/types.md @@ -43,7 +43,7 @@ up front are: * Only values, not variables, have types -- variables are simply names bound to values. * Both abstract and concrete types can be parameterized by other types. They can also be parameterized by symbols, by values of any type for which [`isbits`](@ref) returns true (essentially, things - like numbers and bools that are stored like C types or structs with no pointers to other objects), + like numbers and bools that are stored like C types or `struct`s with no pointers to other objects), and also by tuples thereof. Type parameters may be omitted when they do not need to be referenced or restricted. @@ -148,7 +148,7 @@ numbers. Abstract types allow the construction of a hierarchy of types, providin into which concrete types can fit. This allows you, for example, to easily program to any type that is an integer, without restricting an algorithm to a specific type of integer. -Abstract types are declared using the `abstract type` keyword. The general syntaxes for declaring an +Abstract types are declared using the [`abstract type`](@ref) keyword. The general syntaxes for declaring an abstract type are: ``` @@ -157,7 +157,7 @@ abstract type «name» <: «supertype» end ``` The `abstract type` keyword introduces a new abstract type, whose name is given by `«name»`. This -name can be optionally followed by `<:` and an already-existing type, indicating that the newly +name can be optionally followed by [`<:`](@ref) and an already-existing type, indicating that the newly declared abstract type is a subtype of this "parent" type. When no supertype is given, the default supertype is `Any` -- a predefined abstract type that @@ -309,7 +309,7 @@ for more information on methods and dispatch). Thus, it would be inappropriate f named bags of methods "inside" each object ends up being a highly beneficial aspect of the language design. -Composite types are introduced with the `struct` keyword followed by a block of field names, optionally +Composite types are introduced with the [`struct`](@ref) keyword followed by a block of field names, optionally annotated with types using the `::` operator: ```jldoctest footype @@ -349,7 +349,7 @@ Stacktrace: [...] ``` -You may find a list of field names using the `fieldnames` function. +You may find a list of field names using the [`fieldnames`](@ref) function. ```jldoctest footype julia> fieldnames(Foo) @@ -381,7 +381,7 @@ An immutable object might contain mutable objects, such as arrays, as fields. Th objects will remain mutable; only the fields of the immutable object itself cannot be changed to point to different objects. -Where required, mutable composite objects can be declared with the keyword `mutable struct`, to be +Where required, mutable composite objects can be declared with the keyword [`mutable struct`](@ref), to be discussed in the next section. Immutable composite types with no fields are singletons; there can be only one instance of such types: @@ -394,7 +394,7 @@ julia> NoFields() === NoFields() true ``` -The `===` function confirms that the "two" constructed instances of `NoFields` are actually one +The [`===`](@ref) function confirms that the "two" constructed instances of `NoFields` are actually one and the same. Singleton types are described in further detail [below](@ref man-singleton-types). There is much more to say about how instances of composite types are created, but that discussion @@ -480,7 +480,7 @@ Every concrete value in the system is an instance of some `DataType`. ## Type Unions A type union is a special abstract type which includes as objects all instances of any of its -argument types, constructed using the special `Union` keyword: +argument types, constructed using the special [`Union`](@ref) keyword: ```jldoctest julia> IntOrString = Union{Int,AbstractString} @@ -502,7 +502,7 @@ presence of `Union` types with a small number of types [^1], by generating speci in separate branches for each possible type. A particularly useful case of a `Union` type is `Union{T, Nothing}`, where `T` can be any type and -[`Nothing`](@ref) is the singleton type whose only instance is the object `nothing`. This pattern +[`Nothing`](@ref) is the singleton type whose only instance is the object [`nothing`](@ref). This pattern is the Julia equivalent of [`Nullable`, `Option` or `Maybe`](https://en.wikipedia.org/wiki/Nullable_type) types in other languages. Declaring a function argument or a field as `Union{T, Nothing}` allows setting it either to a value of type `T`, or to `nothing` to indicate that there is no value. @@ -887,7 +887,7 @@ signature (when the signature matches). ### Vararg Tuple Types -The last parameter of a tuple type can be the special type `Vararg`, which denotes any number +The last parameter of a tuple type can be the special type [`Vararg`](@ref), which denotes any number of trailing elements: ```jldoctest @@ -1012,7 +1012,7 @@ is that the type parameter `T` is not used in the definition of the type itself an abstract tag, essentially defining an entire family of types with identical structure, differentiated only by their type parameter. Thus, `Ptr{Float64}` and `Ptr{Int64}` are distinct types, even though they have identical representations. And of course, all specific pointer types are subtypes of -the umbrella `Ptr` type: +the umbrella [`Ptr`](@ref) type: ```jldoctest julia> Ptr{Float64} <: Ptr @@ -1028,7 +1028,7 @@ We have said that a parametric type like `Ptr` acts as a supertype of all its in (`Ptr{Int64}` etc.). How does this work? `Ptr` itself cannot be a normal data type, since without knowing the type of the referenced data the type clearly cannot be used for memory operations. The answer is that `Ptr` (or other parametric types like `Array`) is a different kind of type called a -`UnionAll` type. Such a type expresses the *iterated union* of types for all values of some parameter. +[`UnionAll`](@ref) type. Such a type expresses the *iterated union* of types for all values of some parameter. `UnionAll` types are usually written using the keyword `where`. For example `Ptr` could be more accurately written as `Ptr{T} where T`, meaning all values whose type is `Ptr{T}` for some value @@ -1377,7 +1377,7 @@ of custom types. By way of illustration of this idea, let's introduce a parametr and a constructor `Val(x) = Val{x}()`, which serves as a customary way to exploit this technique for cases where you don't need a more elaborate hierarchy. -`Val` is defined as: +[`Val`](@ref) is defined as: ```jldoctest valtype julia> struct Val{x} diff --git a/src/stdlib/Pkg.md b/src/stdlib/Pkg.md index 6e9c8f4..2f9888d 100644 --- a/src/stdlib/Pkg.md +++ b/src/stdlib/Pkg.md @@ -456,7 +456,7 @@ shell> cat ~/.julia/packages/MbedTLS/h1Vu/deps/build.log So far we have added packages to the default project at `~/.julia/environments/v0.7`, it is, however, easy to create other, independent, projects. It should be pointed out if two projects uses the same package at the same version, the content of this package is not duplicated. -This is done using the `init` command. Below we make a new directory and create a new project in it: +In order to create a new project, create a directory for it and then activate that directory to make it the "active project" which package operations manipulate: ``` shell> mkdir MyProject @@ -464,16 +464,49 @@ shell> mkdir MyProject shell> cd MyProject /Users/kristoffer/MyProject -(v0.7) pkg> init -Initialized project at /Users/kristoffer/MyProject/Project.toml +(v0.7) pkg> activate . (MyProject) pkg> st Status `Project.toml` ``` -Note that the REPL prompt changed when the new project was initiated, in other words, Pkg automatically set the current environment to the -one that just got initiated. Since this is a newly created project, the status command show it contains no packages. -Packages added here again in a completely separate environment from the one earlier used. +Note that the REPL prompt changed when the new project is activated. Since this is a newly created project, the status command show it contains no packages, and in fact, it has no project or manifest file until we add a package to it: + +``` +shell> ls -l +total 0 + +(MyProject) pkg> add Example + Updating registry at `~/.julia/registries/Uncurated` + Updating git-repo `https://github.com/JuliaRegistries/Uncurated.git` + Resolving package versions... + Updating `Project.toml` + [7876af07] + Example v0.5.1 + Updating `Manifest.toml` + [7876af07] + Example v0.5.1 + [8dfed614] + Test + +shell> ls -l +total 8 +-rw-r--r-- 1 stefan staff 207 Jul 3 16:35 Manifest.toml +-rw-r--r-- 1 stefan staff 56 Jul 3 16:35 Project.toml + +shell> cat Project.toml +[deps] +Example = "7876af07-990d-54b4-ab0e-23690620f79a" + +shell> cat Manifest.toml +[[Example]] +deps = ["Test"] +git-tree-sha1 = "8eb7b4d4ca487caade9ba3e85932e28ce6d6e1f8" +uuid = "7876af07-990d-54b4-ab0e-23690620f79a" +version = "0.5.1" + +[[Test]] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +``` + +This new environment is completely separate from the one we used earlier. ## Garbage collecting old, unused packages @@ -661,7 +694,7 @@ This is possible by adding dependencies to a "test target" to the Project file. test-only dependency by adding the following to the Project file: ``` -[target.test.deps] +[targets.test.deps] Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" ``` From 55d92588c1dd0b79c91f38edb07d4b6045013885 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Wed, 18 Jul 2018 10:34:26 +0900 Subject: [PATCH 044/153] update Julia Commit b6a60dd660 --- codex/NEWS.md | 5 +++ codex/base/arrays.md | 5 +++ codex/base/collections.md | 23 +++++++--- codex/base/constants.md | 2 +- codex/devdocs/ast.md | 2 +- codex/manual/environment-variables.md | 4 +- codex/manual/functions.md | 11 +++++ codex/manual/getting-started.md | 2 +- codex/manual/parallel-computing.md | 63 +++++++++++++++++---------- codex/stdlib/Pkg.md | 28 ++++++------ src/NEWS.md | 5 +++ src/base/arrays.md | 5 +++ src/base/collections.md | 23 +++++++--- src/base/constants.md | 2 +- src/devdocs/ast.md | 2 +- src/manual/environment-variables.md | 4 +- src/manual/functions.md | 11 +++++ src/manual/getting-started.md | 2 +- src/manual/parallel-computing.md | 63 +++++++++++++++++---------- src/stdlib/Pkg.md | 28 ++++++------ 20 files changed, 196 insertions(+), 94 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index 33e3d42..51af85f 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -524,6 +524,11 @@ This section lists changes that do not have deprecation warnings. * `dot(u, v)` now acts recursively. Instead of `sum(u[i]' * v[i] for i in ...)`, it computes `sum(dot(u[i], v[i]) for i in ...)`, similarly to `vecdot` before ([#27401](https://github.com/JuliaLang/julia/issues/27401)). + * `Sys.CPU_CORES` has been renamed to `Sys.CPU_THREADS`; it still gives the number + of "logical cores" (including hyperthreading) rather than the number of physical + cores present on the CPU. Similarly, the environment variable `JULIA_CPU_CORES` is + deprecated in favor of `JULIA_CPU_THREADS` ([#27856](https://github.com/JuliaLang/julia/issues/27856)). + Library improvements -------------------- diff --git a/codex/base/arrays.md b/codex/base/arrays.md index 5ed3ebf..f2bb0b9 100644 --- a/codex/base/arrays.md +++ b/codex/base/arrays.md @@ -22,6 +22,10 @@ Base.Matrix(::UndefInitializer, ::Any, ::Any) Base.Matrix(::Nothing, ::Any, ::Any) Base.Matrix(::Missing, ::Any, ::Any) Base.VecOrMat +Core.DenseArray +Base.DenseVector +Base.DenseMatrix +Base.DenseVecOrMat Base.getindex(::Type, ::Any...) Base.zeros Base.ones @@ -83,6 +87,7 @@ Base.isassigned Base.Colon Base.CartesianIndex Base.CartesianIndices +Base.Dims Base.LinearIndices Base.to_indices Base.checkbounds diff --git a/codex/base/collections.md b/codex/base/collections.md index 0396091..bc7c6a4 100644 --- a/codex/base/collections.md +++ b/codex/base/collections.md @@ -34,8 +34,8 @@ Base.IteratorEltype Fully implemented by: - * `AbstractRange` - * `UnitRange` + * [`AbstractRange`](@ref) + * [`UnitRange`](@ref) * `Tuple` * `Number` * [`AbstractArray`](@ref) @@ -49,6 +49,17 @@ Fully implemented by: * [`Pair`](@ref) * [`NamedTuple`](@ref) +## Constructors and Types + +```@docs +Base.AbstractRange +Base.OrdinalRange +Base.AbstractUnitRange +Base.StepRange +Base.UnitRange +Base.LinRange +``` + ## General Collections ```@docs @@ -59,8 +70,8 @@ Base.length Fully implemented by: - * `AbstractRange` - * `UnitRange` + * [`AbstractRange`](@ref) + * [`UnitRange`](@ref) * `Tuple` * `Number` * [`AbstractArray`](@ref) @@ -146,8 +157,8 @@ Fully implemented by: Partially implemented by: - * `AbstractRange` - * `UnitRange` + * [`AbstractRange`](@ref) + * [`UnitRange`](@ref) * `Tuple` * `AbstractString` * [`Dict`](@ref) diff --git a/codex/base/constants.md b/codex/base/constants.md index b56659e..0893c3a 100644 --- a/codex/base/constants.md +++ b/codex/base/constants.md @@ -8,7 +8,7 @@ Base.C_NULL Base.VERSION Base.LOAD_PATH Base.Sys.BINDIR -Base.Sys.CPU_CORES +Base.Sys.CPU_THREADS Base.Sys.WORD_SIZE Base.Sys.KERNEL Base.Sys.ARCH diff --git a/codex/devdocs/ast.md b/codex/devdocs/ast.md index 8837b92..8669b0f 100644 --- a/codex/devdocs/ast.md +++ b/codex/devdocs/ast.md @@ -1,7 +1,7 @@ # Julia ASTs Julia has two representations of code. First there is a surface syntax AST returned by the parser -(e.g. the [`parse`](@ref) function), and manipulated by macros. It is a structured representation +(e.g. the [`Meta.parse`](@ref) function), and manipulated by macros. It is a structured representation of code as it is written, constructed by `julia-parser.scm` from a character stream. Next there is a lowered form, or IR (intermediate representation), which is used by type inference and code generation. In the lowered form there are fewer types of nodes, all macros are expanded, and all diff --git a/codex/manual/environment-variables.md b/codex/manual/environment-variables.md index 6d6286d..853dd77 100644 --- a/codex/manual/environment-variables.md +++ b/codex/manual/environment-variables.md @@ -128,9 +128,9 @@ exists, or `emacs` otherwise. ## Parallelization -### `JULIA_CPU_CORES` +### `JULIA_CPU_THREADS` -Overrides the global variable [`Base.Sys.CPU_CORES`](@ref), the number of +Overrides the global variable [`Base.Sys.CPU_THREADS`](@ref), the number of logical CPU cores available. ### `JULIA_WORKER_TIMEOUT` diff --git a/codex/manual/functions.md b/codex/manual/functions.md index a24e382..45c170b 100644 --- a/codex/manual/functions.md +++ b/codex/manual/functions.md @@ -760,6 +760,17 @@ they are equivalent to `broadcast` calls and are fused with other nested "dot" c `X .+= Y` etcetera is equivalent to `X .= X .+ Y` and results in a fused in-place assignment; see also [dot operators](@ref man-dot-operators). +You can also combine dot operations with function chaining using [`|>`](@ref), as in this example: +```jldoctest +julia> [1:5;] .|> [x->x^2, inv, x->2*x, -, isodd] +5-element Array{Real,1}: + 1 + 0.5 + 6 + -4 + true +``` + ## Further Reading We should mention here that this is far from a complete picture of defining functions. Julia has diff --git a/codex/manual/getting-started.md b/codex/manual/getting-started.md index f3c4849..b41eab6 100644 --- a/codex/manual/getting-started.md +++ b/codex/manual/getting-started.md @@ -102,7 +102,7 @@ julia [switches] -- [programfile] [args...] |`-e`, `--eval ` |Evaluate ``| |`-E`, `--print ` |Evaluate `` and display the result| |`-L`, `--load ` |Load `` immediately on all processors| -|`-p`, `--procs {N\|auto`} |Integer value N launches N additional local worker processes; `auto` launches as many workers as the number of local cores| +|`-p`, `--procs {N\|auto`} |Integer value N launches N additional local worker processes; `auto` launches as many workers as the number of local CPU threads (logical cores)| |`--machine-file ` |Run processes on hosts listed in ``| |`-i` |Interactive mode; REPL runs and `isinteractive()` is true| |`-q`, `--quiet` |Quiet startup: no banner, suppress REPL warnings| diff --git a/codex/manual/parallel-computing.md b/codex/manual/parallel-computing.md index 7efd4a4..481c296 100644 --- a/codex/manual/parallel-computing.md +++ b/codex/manual/parallel-computing.md @@ -49,7 +49,7 @@ to as "workers". When there is only one process, process 1 is considered a worke workers are considered to be all processes other than process 1. Let's try this out. Starting with `julia -p n` provides `n` worker processes on the local machine. -Generally it makes sense for `n` to equal the number of CPU cores on the machine. Note that the `-p` +Generally it makes sense for `n` to equal the number of CPU threads (logical cores) on the machine. Note that the `-p` argument implicitly loads module `Distributed`. @@ -164,34 +164,47 @@ println("loaded") end ``` -Starting Julia with `julia -p 2`, you can use this to verify the following: +In order to refer to `MyType` across all processes, `DummyModule.jl` needs to be loaded on +every process. Calling `include("DummyModule.jl")` loads it only on a single process. To +load it on every process, use the [`@everywhere`](@ref) macro (starting Julia with `julia -p +2`): - * `include("DummyModule.jl")` loads the file on just a single process - (whichever one executes the statement). - * `using DummyModule` causes the module to be loaded on all processes; however, the module is brought - into scope only on the one executing the statement. - * As long as `DummyModule` is loaded on process 2, commands like +```julia-repl +julia> @everywhere include("DummyModule.jl") +loaded + From worker 3: loaded + From worker 2: loaded +``` - ```julia - rr = RemoteChannel(2) - put!(rr, MyType(7)) - ``` +As usual, this does not bring `DummyModule` into scope on any of the process, which requires +`using` or `import`. Moreover, when `DummyModule` is brought into scope on one process, it +is not on any other: - allow you to store an object of type `MyType` on process 2 even if `DummyModule` is not in scope - on process 2. +```julia-repl +julia> using .DummyModule -You can force a command to run on all processes using the [`@everywhere`](@ref) macro. For example, `@everywhere` -can also be used to directly define a function on all processes: +julia> MyType(7) +MyType(7) -```julia-repl -julia> @everywhere id = myid() +julia> fetch(@spawnat 2 MyType(7)) +ERROR: On worker 2: +UndefVarError: MyType not defined +⋮ -julia> remotecall_fetch(()->id, 2) -2 +julia> fetch(@spawnat 2 DummyModule.MyType(7)) +MyType(7) ``` -A file can also be preloaded on multiple processes at startup, and a driver script can be used -to drive the computation: +However, it's still possible, for instance, to send a `MyType` to a process which has loaded +`DummyModule` even if it's not in scope: + +```julia-repl +julia> put!(RemoteChannel(2), MyType(7)) +RemoteChannel{Channel{Any}}(2, 1, 13) +``` + +A file can also be preloaded on multiple processes at startup with the `-L` flag, and a +driver script can be used to drive the computation: ``` julia -p -L file1.jl -L file2.jl driver.jl @@ -200,6 +213,12 @@ julia -p -L file1.jl -L file2.jl driver.jl The Julia process running the driver script in the example above has an `id` equal to 1, just like a process providing an interactive prompt. +Finally, if `DummyModule.jl` is not a standalone file but a package, then `using +DummyModule` will _load_ `DummyModule.jl` on all processes, but only bring it into scope on +the process where `using` was called. + +## Starting and managing worker processes + The base Julia installation has in-built support for two types of clusters: * A local cluster specified with the `-p` option as shown above. @@ -1200,7 +1219,7 @@ would typically specify only `io` or `host` / `port`: workers. * `count` with an integer value `n` will launch a total of `n` workers. - * `count` with a value of `:auto` will launch as many workers as the number of cores on that machine. + * `count` with a value of `:auto` will launch as many workers as the number of CPU threads (logical cores) on that machine. * `exename` is the name of the `julia` executable including the full path. * `exeflags` should be set to the required command line arguments for new workers. * `tunnel`, `bind_addr`, `sshflags` and `max_parallel` are used when a ssh tunnel is required to diff --git a/codex/stdlib/Pkg.md b/codex/stdlib/Pkg.md index 2f9888d..93cf971 100644 --- a/codex/stdlib/Pkg.md +++ b/codex/stdlib/Pkg.md @@ -156,7 +156,7 @@ including: - `dev`: default directory for package development - `logs`: log files (e.g. `manifest_usage.toml`, `repl_history.jl`) - `packages`: installed package versions -- `registries`: clones of registries (e.g. `Uncurated`) +- `registries`: clones of registries (e.g. `General`) **Load path:** a stack of environments where package identities, their dependencies, and entry-points are searched for. The load path is controlled in @@ -209,9 +209,9 @@ In the Pkg REPL packages can be added with the `add` command followed by the nam ``` (v0.7) pkg> add Example Cloning default registries into /Users/kristoffer/.julia/registries - Cloning registry Uncurated from "https://github.com/JuliaRegistries/Uncurated.git" - Updating registry at `~/.julia/registries/Uncurated` - Updating git-repo `https://github.com/JuliaRegistries/Uncurated.git` + Cloning registry General from "https://github.com/JuliaRegistries/General.git" + Updating registry at `~/.julia/registries/General` + Updating git-repo `https://github.com/JuliaRegistries/General.git` Resolving package versions... Updating `~/.julia/environments/v0.7/Project.toml` [7876af07] + Example v0.5.1 @@ -221,7 +221,7 @@ In the Pkg REPL packages can be added with the `add` command followed by the nam ``` Here we added the package Example to the current project. In this example, we are using a fresh Julia installation, -and this is our first time adding a package using Pkg. By default, Pkg clones Julia's Uncurated registry, +and this is our first time adding a package using Pkg. By default, Pkg clones Julia's General registry, and uses this registry to look up packages requested for inclusion in the current environment. The status update shows a short form of the package UUID to the left, then the package name, and the version. Since standard libraries (e.g. `Test`) are shipped with Julia, they do not have a version. The project status contains the packages @@ -272,9 +272,9 @@ we can explicitly track a branch (or commit) by appending `#branch` (or `#commit Updating git-repo `https://github.com/JuliaLang/Example.jl.git` Resolving package versions... Updating `~/.julia/environments/v0.7/Project.toml` - [7876af07] ~ Example v0.5.1 ⇒ v0.5.1+ #master [https://github.com/JuliaLang/Example.jl.git] + [7876af07] ~ Example v0.5.1 ⇒ v0.5.1+ #master (https://github.com/JuliaLang/Example.jl.git) Updating `~/.julia/environments/v0.7/Manifest.toml` - [7876af07] ~ Example v0.5.1 ⇒ v0.5.1+ #master [https://github.com/JuliaLang/Example.jl.git] + [7876af07] ~ Example v0.5.1 ⇒ v0.5.1+ #master (https://github.com/JuliaLang/Example.jl.git) ``` The status output now shows that we are tracking the `master` branch of `Example`. @@ -286,9 +286,9 @@ To go back to tracking the registry version of `Example`, the command `free` is (v0.7) pkg> free Example Resolving package versions... Updating `~/.julia/environments/v0.7/Project.toml` - [7876af07] ~ Example v0.5.1+ #master [https://github.com/JuliaLang/Example.jl.git] ⇒ v0.5.1 + [7876af07] ~ Example v0.5.1+ #master (https://github.com/JuliaLang/Example.jl.git) ⇒ v0.5.1 Updating `~/.julia/environments/v0.7/Manifest.toml` - [7876af07] ~ Example v0.5.1+ #master [https://github.com/JuliaLang/Example.jl.git] ⇒ v0.5.1 + [7876af07] ~ Example v0.5.1+ #master )https://github.com/JuliaLang/Example.jl.git) ⇒ v0.5.1 ``` @@ -302,9 +302,9 @@ If a package is not in a registry, it can still be added by instead of the packa Resolving package versions... Downloaded MacroTools ─ v0.4.1 Updating `~/.julia/environments/v0.7/Project.toml` - [e6797606] + ImportMacros v0.0.0 # [https://github.com/fredrikekre/ImportMacros.jl] + [e6797606] + ImportMacros v0.0.0 # (https://github.com/fredrikekre/ImportMacros.jl) Updating `~/.julia/environments/v0.7/Manifest.toml` - [e6797606] + ImportMacros v0.0.0 # [https://github.com/fredrikekre/ImportMacros.jl] + [e6797606] + ImportMacros v0.0.0 # (https://github.com/fredrikekre/ImportMacros.jl) [1914dd2f] + MacroTools v0.4.1 ``` @@ -477,8 +477,8 @@ shell> ls -l total 0 (MyProject) pkg> add Example - Updating registry at `~/.julia/registries/Uncurated` - Updating git-repo `https://github.com/JuliaRegistries/Uncurated.git` + Updating registry at `~/.julia/registries/General` + Updating git-repo `https://github.com/JuliaRegistries/General.git` Resolving package versions... Updating `Project.toml` [7876af07] + Example v0.5.1 @@ -733,7 +733,7 @@ After a compatibility entry is put into the project file, `up` can be used to ap The format of the version specifier is described in detail below. !!! info - There is currently no way to give compatibility from the Pkg REPL mode so for now, one has to manually edit the project file. + There is currently no way to give compatibility from the Pkg REPL mode so for now, one has to manually edit the project file. #### Version specifier format diff --git a/src/NEWS.md b/src/NEWS.md index bacf289..9929b42 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -513,6 +513,11 @@ This section lists changes that do not have deprecation warnings. * `dot(u, v)` now acts recursively. Instead of `sum(u[i]' * v[i] for i in ...)`, it computes `sum(dot(u[i], v[i]) for i in ...)`, similarly to `vecdot` before ([#27401](https://github.com/JuliaLang/julia/issues/27401)). + * `Sys.CPU_CORES` has been renamed to `Sys.CPU_THREADS`; it still gives the number + of "logical cores" (including hyperthreading) rather than the number of physical + cores present on the CPU. Similarly, the environment variable `JULIA_CPU_CORES` is + deprecated in favor of `JULIA_CPU_THREADS` ([#27856](https://github.com/JuliaLang/julia/issues/27856)). + Library improvements -------------------- diff --git a/src/base/arrays.md b/src/base/arrays.md index 5ed3ebf..f2bb0b9 100644 --- a/src/base/arrays.md +++ b/src/base/arrays.md @@ -22,6 +22,10 @@ Base.Matrix(::UndefInitializer, ::Any, ::Any) Base.Matrix(::Nothing, ::Any, ::Any) Base.Matrix(::Missing, ::Any, ::Any) Base.VecOrMat +Core.DenseArray +Base.DenseVector +Base.DenseMatrix +Base.DenseVecOrMat Base.getindex(::Type, ::Any...) Base.zeros Base.ones @@ -83,6 +87,7 @@ Base.isassigned Base.Colon Base.CartesianIndex Base.CartesianIndices +Base.Dims Base.LinearIndices Base.to_indices Base.checkbounds diff --git a/src/base/collections.md b/src/base/collections.md index 0396091..bc7c6a4 100644 --- a/src/base/collections.md +++ b/src/base/collections.md @@ -34,8 +34,8 @@ Base.IteratorEltype Fully implemented by: - * `AbstractRange` - * `UnitRange` + * [`AbstractRange`](@ref) + * [`UnitRange`](@ref) * `Tuple` * `Number` * [`AbstractArray`](@ref) @@ -49,6 +49,17 @@ Fully implemented by: * [`Pair`](@ref) * [`NamedTuple`](@ref) +## Constructors and Types + +```@docs +Base.AbstractRange +Base.OrdinalRange +Base.AbstractUnitRange +Base.StepRange +Base.UnitRange +Base.LinRange +``` + ## General Collections ```@docs @@ -59,8 +70,8 @@ Base.length Fully implemented by: - * `AbstractRange` - * `UnitRange` + * [`AbstractRange`](@ref) + * [`UnitRange`](@ref) * `Tuple` * `Number` * [`AbstractArray`](@ref) @@ -146,8 +157,8 @@ Fully implemented by: Partially implemented by: - * `AbstractRange` - * `UnitRange` + * [`AbstractRange`](@ref) + * [`UnitRange`](@ref) * `Tuple` * `AbstractString` * [`Dict`](@ref) diff --git a/src/base/constants.md b/src/base/constants.md index b56659e..0893c3a 100644 --- a/src/base/constants.md +++ b/src/base/constants.md @@ -8,7 +8,7 @@ Base.C_NULL Base.VERSION Base.LOAD_PATH Base.Sys.BINDIR -Base.Sys.CPU_CORES +Base.Sys.CPU_THREADS Base.Sys.WORD_SIZE Base.Sys.KERNEL Base.Sys.ARCH diff --git a/src/devdocs/ast.md b/src/devdocs/ast.md index 8837b92..8669b0f 100644 --- a/src/devdocs/ast.md +++ b/src/devdocs/ast.md @@ -1,7 +1,7 @@ # Julia ASTs Julia has two representations of code. First there is a surface syntax AST returned by the parser -(e.g. the [`parse`](@ref) function), and manipulated by macros. It is a structured representation +(e.g. the [`Meta.parse`](@ref) function), and manipulated by macros. It is a structured representation of code as it is written, constructed by `julia-parser.scm` from a character stream. Next there is a lowered form, or IR (intermediate representation), which is used by type inference and code generation. In the lowered form there are fewer types of nodes, all macros are expanded, and all diff --git a/src/manual/environment-variables.md b/src/manual/environment-variables.md index 6d6286d..853dd77 100644 --- a/src/manual/environment-variables.md +++ b/src/manual/environment-variables.md @@ -128,9 +128,9 @@ exists, or `emacs` otherwise. ## Parallelization -### `JULIA_CPU_CORES` +### `JULIA_CPU_THREADS` -Overrides the global variable [`Base.Sys.CPU_CORES`](@ref), the number of +Overrides the global variable [`Base.Sys.CPU_THREADS`](@ref), the number of logical CPU cores available. ### `JULIA_WORKER_TIMEOUT` diff --git a/src/manual/functions.md b/src/manual/functions.md index a24e382..45c170b 100644 --- a/src/manual/functions.md +++ b/src/manual/functions.md @@ -760,6 +760,17 @@ they are equivalent to `broadcast` calls and are fused with other nested "dot" c `X .+= Y` etcetera is equivalent to `X .= X .+ Y` and results in a fused in-place assignment; see also [dot operators](@ref man-dot-operators). +You can also combine dot operations with function chaining using [`|>`](@ref), as in this example: +```jldoctest +julia> [1:5;] .|> [x->x^2, inv, x->2*x, -, isodd] +5-element Array{Real,1}: + 1 + 0.5 + 6 + -4 + true +``` + ## Further Reading We should mention here that this is far from a complete picture of defining functions. Julia has diff --git a/src/manual/getting-started.md b/src/manual/getting-started.md index 087956e..2ebfa06 100644 --- a/src/manual/getting-started.md +++ b/src/manual/getting-started.md @@ -82,7 +82,7 @@ julia [switches] -- [programfile] [args...] |`-e`, `--eval ` |``를 실행만 한다| |`-E`, `--print ` |``를 실행하고 결과를 표시한다| |`-L`, `--load ` |``을 모든 프로세서에 로드한다| -|`-p`, `--procs {N\|auto`} |N개의 worker 프로세스를 추가로 생성한다; `auto`는 현재 컴퓨터의 최대 코어수만큼 worker 프로세스를 생성한다| +|`-p`, `--procs {N\|auto`} |N개의 로컬 worker 프로세스를 추가로 생성한다; `auto`는 로컬 CPU 스레드 (논리적 코어) 만큼의 worker 프로세스를 생성한다| |`--machine-file ` |``에 나열된 호스트에서 worker 프로세스를 실행한다| |`-i` |대화형 모드; PEPL을 돌리며 `ininteractive()`는 true이다| |`-q`, `--quiet` |깔끔히 시작하기: 배너 없이, REPL 경고도 안 보여준다| diff --git a/src/manual/parallel-computing.md b/src/manual/parallel-computing.md index 7efd4a4..481c296 100644 --- a/src/manual/parallel-computing.md +++ b/src/manual/parallel-computing.md @@ -49,7 +49,7 @@ to as "workers". When there is only one process, process 1 is considered a worke workers are considered to be all processes other than process 1. Let's try this out. Starting with `julia -p n` provides `n` worker processes on the local machine. -Generally it makes sense for `n` to equal the number of CPU cores on the machine. Note that the `-p` +Generally it makes sense for `n` to equal the number of CPU threads (logical cores) on the machine. Note that the `-p` argument implicitly loads module `Distributed`. @@ -164,34 +164,47 @@ println("loaded") end ``` -Starting Julia with `julia -p 2`, you can use this to verify the following: +In order to refer to `MyType` across all processes, `DummyModule.jl` needs to be loaded on +every process. Calling `include("DummyModule.jl")` loads it only on a single process. To +load it on every process, use the [`@everywhere`](@ref) macro (starting Julia with `julia -p +2`): - * `include("DummyModule.jl")` loads the file on just a single process - (whichever one executes the statement). - * `using DummyModule` causes the module to be loaded on all processes; however, the module is brought - into scope only on the one executing the statement. - * As long as `DummyModule` is loaded on process 2, commands like +```julia-repl +julia> @everywhere include("DummyModule.jl") +loaded + From worker 3: loaded + From worker 2: loaded +``` - ```julia - rr = RemoteChannel(2) - put!(rr, MyType(7)) - ``` +As usual, this does not bring `DummyModule` into scope on any of the process, which requires +`using` or `import`. Moreover, when `DummyModule` is brought into scope on one process, it +is not on any other: - allow you to store an object of type `MyType` on process 2 even if `DummyModule` is not in scope - on process 2. +```julia-repl +julia> using .DummyModule -You can force a command to run on all processes using the [`@everywhere`](@ref) macro. For example, `@everywhere` -can also be used to directly define a function on all processes: +julia> MyType(7) +MyType(7) -```julia-repl -julia> @everywhere id = myid() +julia> fetch(@spawnat 2 MyType(7)) +ERROR: On worker 2: +UndefVarError: MyType not defined +⋮ -julia> remotecall_fetch(()->id, 2) -2 +julia> fetch(@spawnat 2 DummyModule.MyType(7)) +MyType(7) ``` -A file can also be preloaded on multiple processes at startup, and a driver script can be used -to drive the computation: +However, it's still possible, for instance, to send a `MyType` to a process which has loaded +`DummyModule` even if it's not in scope: + +```julia-repl +julia> put!(RemoteChannel(2), MyType(7)) +RemoteChannel{Channel{Any}}(2, 1, 13) +``` + +A file can also be preloaded on multiple processes at startup with the `-L` flag, and a +driver script can be used to drive the computation: ``` julia -p -L file1.jl -L file2.jl driver.jl @@ -200,6 +213,12 @@ julia -p -L file1.jl -L file2.jl driver.jl The Julia process running the driver script in the example above has an `id` equal to 1, just like a process providing an interactive prompt. +Finally, if `DummyModule.jl` is not a standalone file but a package, then `using +DummyModule` will _load_ `DummyModule.jl` on all processes, but only bring it into scope on +the process where `using` was called. + +## Starting and managing worker processes + The base Julia installation has in-built support for two types of clusters: * A local cluster specified with the `-p` option as shown above. @@ -1200,7 +1219,7 @@ would typically specify only `io` or `host` / `port`: workers. * `count` with an integer value `n` will launch a total of `n` workers. - * `count` with a value of `:auto` will launch as many workers as the number of cores on that machine. + * `count` with a value of `:auto` will launch as many workers as the number of CPU threads (logical cores) on that machine. * `exename` is the name of the `julia` executable including the full path. * `exeflags` should be set to the required command line arguments for new workers. * `tunnel`, `bind_addr`, `sshflags` and `max_parallel` are used when a ssh tunnel is required to diff --git a/src/stdlib/Pkg.md b/src/stdlib/Pkg.md index 2f9888d..93cf971 100644 --- a/src/stdlib/Pkg.md +++ b/src/stdlib/Pkg.md @@ -156,7 +156,7 @@ including: - `dev`: default directory for package development - `logs`: log files (e.g. `manifest_usage.toml`, `repl_history.jl`) - `packages`: installed package versions -- `registries`: clones of registries (e.g. `Uncurated`) +- `registries`: clones of registries (e.g. `General`) **Load path:** a stack of environments where package identities, their dependencies, and entry-points are searched for. The load path is controlled in @@ -209,9 +209,9 @@ In the Pkg REPL packages can be added with the `add` command followed by the nam ``` (v0.7) pkg> add Example Cloning default registries into /Users/kristoffer/.julia/registries - Cloning registry Uncurated from "https://github.com/JuliaRegistries/Uncurated.git" - Updating registry at `~/.julia/registries/Uncurated` - Updating git-repo `https://github.com/JuliaRegistries/Uncurated.git` + Cloning registry General from "https://github.com/JuliaRegistries/General.git" + Updating registry at `~/.julia/registries/General` + Updating git-repo `https://github.com/JuliaRegistries/General.git` Resolving package versions... Updating `~/.julia/environments/v0.7/Project.toml` [7876af07] + Example v0.5.1 @@ -221,7 +221,7 @@ In the Pkg REPL packages can be added with the `add` command followed by the nam ``` Here we added the package Example to the current project. In this example, we are using a fresh Julia installation, -and this is our first time adding a package using Pkg. By default, Pkg clones Julia's Uncurated registry, +and this is our first time adding a package using Pkg. By default, Pkg clones Julia's General registry, and uses this registry to look up packages requested for inclusion in the current environment. The status update shows a short form of the package UUID to the left, then the package name, and the version. Since standard libraries (e.g. `Test`) are shipped with Julia, they do not have a version. The project status contains the packages @@ -272,9 +272,9 @@ we can explicitly track a branch (or commit) by appending `#branch` (or `#commit Updating git-repo `https://github.com/JuliaLang/Example.jl.git` Resolving package versions... Updating `~/.julia/environments/v0.7/Project.toml` - [7876af07] ~ Example v0.5.1 ⇒ v0.5.1+ #master [https://github.com/JuliaLang/Example.jl.git] + [7876af07] ~ Example v0.5.1 ⇒ v0.5.1+ #master (https://github.com/JuliaLang/Example.jl.git) Updating `~/.julia/environments/v0.7/Manifest.toml` - [7876af07] ~ Example v0.5.1 ⇒ v0.5.1+ #master [https://github.com/JuliaLang/Example.jl.git] + [7876af07] ~ Example v0.5.1 ⇒ v0.5.1+ #master (https://github.com/JuliaLang/Example.jl.git) ``` The status output now shows that we are tracking the `master` branch of `Example`. @@ -286,9 +286,9 @@ To go back to tracking the registry version of `Example`, the command `free` is (v0.7) pkg> free Example Resolving package versions... Updating `~/.julia/environments/v0.7/Project.toml` - [7876af07] ~ Example v0.5.1+ #master [https://github.com/JuliaLang/Example.jl.git] ⇒ v0.5.1 + [7876af07] ~ Example v0.5.1+ #master (https://github.com/JuliaLang/Example.jl.git) ⇒ v0.5.1 Updating `~/.julia/environments/v0.7/Manifest.toml` - [7876af07] ~ Example v0.5.1+ #master [https://github.com/JuliaLang/Example.jl.git] ⇒ v0.5.1 + [7876af07] ~ Example v0.5.1+ #master )https://github.com/JuliaLang/Example.jl.git) ⇒ v0.5.1 ``` @@ -302,9 +302,9 @@ If a package is not in a registry, it can still be added by instead of the packa Resolving package versions... Downloaded MacroTools ─ v0.4.1 Updating `~/.julia/environments/v0.7/Project.toml` - [e6797606] + ImportMacros v0.0.0 # [https://github.com/fredrikekre/ImportMacros.jl] + [e6797606] + ImportMacros v0.0.0 # (https://github.com/fredrikekre/ImportMacros.jl) Updating `~/.julia/environments/v0.7/Manifest.toml` - [e6797606] + ImportMacros v0.0.0 # [https://github.com/fredrikekre/ImportMacros.jl] + [e6797606] + ImportMacros v0.0.0 # (https://github.com/fredrikekre/ImportMacros.jl) [1914dd2f] + MacroTools v0.4.1 ``` @@ -477,8 +477,8 @@ shell> ls -l total 0 (MyProject) pkg> add Example - Updating registry at `~/.julia/registries/Uncurated` - Updating git-repo `https://github.com/JuliaRegistries/Uncurated.git` + Updating registry at `~/.julia/registries/General` + Updating git-repo `https://github.com/JuliaRegistries/General.git` Resolving package versions... Updating `Project.toml` [7876af07] + Example v0.5.1 @@ -733,7 +733,7 @@ After a compatibility entry is put into the project file, `up` can be used to ap The format of the version specifier is described in detail below. !!! info - There is currently no way to give compatibility from the Pkg REPL mode so for now, one has to manually edit the project file. + There is currently no way to give compatibility from the Pkg REPL mode so for now, one has to manually edit the project file. #### Version specifier format From eed88d98f01c20beb35c81307aaaf8164006d409 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Sat, 21 Jul 2018 21:50:34 +0900 Subject: [PATCH 045/153] update Julia Commit 49577e9e6d --- codex/NEWS.md | 3 +++ codex/base/base.md | 1 + codex/devdocs/llvm.md | 29 +++++++++++++++-------------- codex/devdocs/reflection.md | 6 +++--- codex/manual/faq.md | 7 +++++++ src/NEWS.md | 3 +++ src/base/base.md | 1 + src/devdocs/llvm.md | 29 +++++++++++++++-------------- src/devdocs/reflection.md | 6 +++--- src/manual/faq.md | 7 +++++++ 10 files changed, 58 insertions(+), 34 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index 51af85f..f0447fb 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -78,6 +78,9 @@ Language changes * Declaring arguments as `x::ANY` to avoid specialization has been replaced by `@nospecialize x`. ([#22666](https://github.com/JuliaLang/julia/issues/22666)). + This can also be used in global scope, to apply to all subsequent method definitions + in the module (until `@specialize`). ([#28065](https://github.com/JuliaLang/julia/issues/28065)) + * Keyword argument default values are now evaluated in successive scopes --- the scope for each expression includes only previous keyword arguments, in left-to-right order ([#17240](https://github.com/JuliaLang/julia/issues/17240)). diff --git a/codex/base/base.md b/codex/base/base.md index 44d0fa2..00ed2db 100644 --- a/codex/base/base.md +++ b/codex/base/base.md @@ -213,6 +213,7 @@ Base.@boundscheck Base.@inline Base.@noinline Base.@nospecialize +Base.@specialize Base.gensym Base.@gensym Base.@goto diff --git a/codex/devdocs/llvm.md b/codex/devdocs/llvm.md index 7b4a731..10af27f 100644 --- a/codex/devdocs/llvm.md +++ b/codex/devdocs/llvm.md @@ -12,14 +12,14 @@ The code for lowering Julia AST to LLVM IR or interpreting it directly is in dir | File | Description | |:------------------- |:---------------------------------------------------------- | | `builtins.c` | Builtin functions | -| `ccall.cpp` | Lowering `ccall` | +| `ccall.cpp` | Lowering [`ccall`](@ref) | | `cgutils.cpp` | Lowering utilities, notably for array and tuple accesses | | `codegen.cpp` | Top-level of code generation, pass list, lowering builtins | | `debuginfo.cpp` | Tracks debug information for JIT code | | `disasm.cpp` | Handles native object file and JIT code diassembly | | `gf.c` | Generic functions | | `intrinsics.cpp` | Lowering intrinsics | -| `llvm-simdloop.cpp` | Custom LLVM pass for `@simd` | +| `llvm-simdloop.cpp` | Custom LLVM pass for [`@simd`](@ref) | | `sys.c` | I/O and operating system utility functions | Some of the `.cpp` files form a group that compile to a single object. @@ -168,7 +168,7 @@ without having to worry (too much) about which values may or may not be GC tracked. However, in order to be able to do late GC root placement, we need to be able to -identify a) which pointers are gc tracked and b) all uses of such pointers. The +identify a) which pointers are GC tracked and b) all uses of such pointers. The goal of the GC placement pass is thus simple: Minimize the number of needed GC roots/stores to them subject to the constraint @@ -257,27 +257,28 @@ optimizer from making optimizations that would introduce these operations. Note we can still insert static constants at JIT time by using `inttoptr` in address space 0 and then decaying to the appropriate address space afterwards. -### Supporting ccall +### Supporting [`ccall`](@ref) One important aspect missing from the discussion so far is the handling of -`ccall`. `ccall` has the peculiar feature that the location and scope of a use -do not coincide. As an example consider: +[`ccall`](@ref). [`ccall`](@ref) has the peculiar feature that the location and +scope of a use do not coincide. As an example consider: ```julia A = randn(1024) ccall(:foo, Cvoid, (Ptr{Float64},), A) ``` In lowering, the compiler will insert a conversion from the array to the pointer which drops the reference to the array value. However, we of course -need to make sure that the array does stay alive while we're doing the `ccall`. -To understand how this is done, first recall the lowering of the above code: +need to make sure that the array does stay alive while we're doing the +[`ccall`](@ref). To understand how this is done, first recall the lowering of the +above code: ```julia return $(Expr(:foreigncall, :(:foo), Cvoid, svec(Ptr{Float64}), :(:ccall), 1, :($(Expr(:foreigncall, :(:jl_array_ptr), Ptr{Float64}, svec(Any), :(:ccall), 1, :(A)))), :(A))) ``` The last `:(A)`, is an extra argument list inserted during lowering that informs the code generator which Julia level values need to be kept alive for the -duration of this `ccall`. We then take this information and represent it in an -"operand bundle" at the IR level. An operand bundle is essentially a fake use -that is attached to the call site. At the IR level, this looks like so: +duration of this [`ccall`](@ref). We then take this information and represent +it in an "operand bundle" at the IR level. An operand bundle is essentially a fake +use that is attached to the call site. At the IR level, this looks like so: ```llvm call void inttoptr (i64 ... to void (double*)*)(double* %5) [ "jl_roots"(%jl_value_t addrspace(10)* %A) ] ``` @@ -285,10 +286,10 @@ The GC root placement pass will treat the `jl_roots` operand bundle as if it wer a regular operand. However, as a final step, after the GC roots are inserted, it will drop the operand bundle to avoid confusing instruction selection. -### Supporting pointer_from_objref +### Supporting [`pointer_from_objref`](@ref) -`pointer_from_objref` is special because it requires the user to take explicit -control of GC rooting. By our above invariants, this function is illegal, +[`pointer_from_objref`](@ref) is special because it requires the user to take +explicit control of GC rooting. By our above invariants, this function is illegal, because it performs an address space cast from 10 to 0. However, it can be useful, in certain situations, so we provide a special intrinsic: ```llvm diff --git a/codex/devdocs/reflection.md b/codex/devdocs/reflection.md index b4abeb4..bcf22fd 100644 --- a/codex/devdocs/reflection.md +++ b/codex/devdocs/reflection.md @@ -96,9 +96,9 @@ as assignments, branches, and calls: ```jldoctest julia> Meta.lower(@__MODULE__, :([1+2, sin(0.5)]) ) :($(Expr(:thunk, CodeInfo( - 1 ─ %1 = :+(1, 2)::Any - │ %2 = :sin(0.5)::Any - │ %3 = Base.vect(%1, %2)::Any + 1 ─ %1 = 1 + 2 + │ %2 = sin(0.5) + │ %3 = (Base.vect)(%1, %2) └── return %3 )))) ``` diff --git a/codex/manual/faq.md b/codex/manual/faq.md index 6f9e0fe..80b1751 100644 --- a/codex/manual/faq.md +++ b/codex/manual/faq.md @@ -645,6 +645,13 @@ as nothing but rather a tuple of zero values. The empty (or "bottom") type, written as `Union{}` (an empty union type), is a type with no values and no subtypes (except itself). You will generally not need to use this type. + +### How do I check if the current file is being run as the main script? + +When a file is run as the main script using `julia file.jl` one might want to activate extra +functionality like command line argument handling. A way to determine that a file is run in +this fashion is to check if `abspath(PROGRAM_FILE) == @__FILE__` is `true`. + ## Memory ### Why does `x += y` allocate memory when `x` and `y` are arrays? diff --git a/src/NEWS.md b/src/NEWS.md index 9929b42..e3c475c 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -66,6 +66,9 @@ Language changes * Declaring arguments as `x::ANY` to avoid specialization has been replaced by `@nospecialize x`. ([#22666](https://github.com/JuliaLang/julia/issues/22666)). + This can also be used in global scope, to apply to all subsequent method definitions + in the module (until `@specialize`). ([#28065](https://github.com/JuliaLang/julia/issues/28065)) + * Keyword argument default values are now evaluated in successive scopes --- the scope for each expression includes only previous keyword arguments, in left-to-right order ([#17240](https://github.com/JuliaLang/julia/issues/17240)). diff --git a/src/base/base.md b/src/base/base.md index 44d0fa2..00ed2db 100644 --- a/src/base/base.md +++ b/src/base/base.md @@ -213,6 +213,7 @@ Base.@boundscheck Base.@inline Base.@noinline Base.@nospecialize +Base.@specialize Base.gensym Base.@gensym Base.@goto diff --git a/src/devdocs/llvm.md b/src/devdocs/llvm.md index 7b4a731..10af27f 100644 --- a/src/devdocs/llvm.md +++ b/src/devdocs/llvm.md @@ -12,14 +12,14 @@ The code for lowering Julia AST to LLVM IR or interpreting it directly is in dir | File | Description | |:------------------- |:---------------------------------------------------------- | | `builtins.c` | Builtin functions | -| `ccall.cpp` | Lowering `ccall` | +| `ccall.cpp` | Lowering [`ccall`](@ref) | | `cgutils.cpp` | Lowering utilities, notably for array and tuple accesses | | `codegen.cpp` | Top-level of code generation, pass list, lowering builtins | | `debuginfo.cpp` | Tracks debug information for JIT code | | `disasm.cpp` | Handles native object file and JIT code diassembly | | `gf.c` | Generic functions | | `intrinsics.cpp` | Lowering intrinsics | -| `llvm-simdloop.cpp` | Custom LLVM pass for `@simd` | +| `llvm-simdloop.cpp` | Custom LLVM pass for [`@simd`](@ref) | | `sys.c` | I/O and operating system utility functions | Some of the `.cpp` files form a group that compile to a single object. @@ -168,7 +168,7 @@ without having to worry (too much) about which values may or may not be GC tracked. However, in order to be able to do late GC root placement, we need to be able to -identify a) which pointers are gc tracked and b) all uses of such pointers. The +identify a) which pointers are GC tracked and b) all uses of such pointers. The goal of the GC placement pass is thus simple: Minimize the number of needed GC roots/stores to them subject to the constraint @@ -257,27 +257,28 @@ optimizer from making optimizations that would introduce these operations. Note we can still insert static constants at JIT time by using `inttoptr` in address space 0 and then decaying to the appropriate address space afterwards. -### Supporting ccall +### Supporting [`ccall`](@ref) One important aspect missing from the discussion so far is the handling of -`ccall`. `ccall` has the peculiar feature that the location and scope of a use -do not coincide. As an example consider: +[`ccall`](@ref). [`ccall`](@ref) has the peculiar feature that the location and +scope of a use do not coincide. As an example consider: ```julia A = randn(1024) ccall(:foo, Cvoid, (Ptr{Float64},), A) ``` In lowering, the compiler will insert a conversion from the array to the pointer which drops the reference to the array value. However, we of course -need to make sure that the array does stay alive while we're doing the `ccall`. -To understand how this is done, first recall the lowering of the above code: +need to make sure that the array does stay alive while we're doing the +[`ccall`](@ref). To understand how this is done, first recall the lowering of the +above code: ```julia return $(Expr(:foreigncall, :(:foo), Cvoid, svec(Ptr{Float64}), :(:ccall), 1, :($(Expr(:foreigncall, :(:jl_array_ptr), Ptr{Float64}, svec(Any), :(:ccall), 1, :(A)))), :(A))) ``` The last `:(A)`, is an extra argument list inserted during lowering that informs the code generator which Julia level values need to be kept alive for the -duration of this `ccall`. We then take this information and represent it in an -"operand bundle" at the IR level. An operand bundle is essentially a fake use -that is attached to the call site. At the IR level, this looks like so: +duration of this [`ccall`](@ref). We then take this information and represent +it in an "operand bundle" at the IR level. An operand bundle is essentially a fake +use that is attached to the call site. At the IR level, this looks like so: ```llvm call void inttoptr (i64 ... to void (double*)*)(double* %5) [ "jl_roots"(%jl_value_t addrspace(10)* %A) ] ``` @@ -285,10 +286,10 @@ The GC root placement pass will treat the `jl_roots` operand bundle as if it wer a regular operand. However, as a final step, after the GC roots are inserted, it will drop the operand bundle to avoid confusing instruction selection. -### Supporting pointer_from_objref +### Supporting [`pointer_from_objref`](@ref) -`pointer_from_objref` is special because it requires the user to take explicit -control of GC rooting. By our above invariants, this function is illegal, +[`pointer_from_objref`](@ref) is special because it requires the user to take +explicit control of GC rooting. By our above invariants, this function is illegal, because it performs an address space cast from 10 to 0. However, it can be useful, in certain situations, so we provide a special intrinsic: ```llvm diff --git a/src/devdocs/reflection.md b/src/devdocs/reflection.md index b4abeb4..bcf22fd 100644 --- a/src/devdocs/reflection.md +++ b/src/devdocs/reflection.md @@ -96,9 +96,9 @@ as assignments, branches, and calls: ```jldoctest julia> Meta.lower(@__MODULE__, :([1+2, sin(0.5)]) ) :($(Expr(:thunk, CodeInfo( - 1 ─ %1 = :+(1, 2)::Any - │ %2 = :sin(0.5)::Any - │ %3 = Base.vect(%1, %2)::Any + 1 ─ %1 = 1 + 2 + │ %2 = sin(0.5) + │ %3 = (Base.vect)(%1, %2) └── return %3 )))) ``` diff --git a/src/manual/faq.md b/src/manual/faq.md index 6f9e0fe..80b1751 100644 --- a/src/manual/faq.md +++ b/src/manual/faq.md @@ -645,6 +645,13 @@ as nothing but rather a tuple of zero values. The empty (or "bottom") type, written as `Union{}` (an empty union type), is a type with no values and no subtypes (except itself). You will generally not need to use this type. + +### How do I check if the current file is being run as the main script? + +When a file is run as the main script using `julia file.jl` one might want to activate extra +functionality like command line argument handling. A way to determine that a file is run in +this fashion is to check if `abspath(PROGRAM_FILE) == @__FILE__` is `true`. + ## Memory ### Why does `x += y` allocate memory when `x` and `y` are arrays? From c1e9fca04c823a6de469b0ac3d023ce42789bd1f Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Thu, 26 Jul 2018 16:20:28 +0900 Subject: [PATCH 046/153] update Julia Commit 04dbf7a3ec --- codex/NEWS.md | 10 +- codex/base/base.md | 2 + codex/base/collections.md | 2 + codex/base/numbers.md | 3 + codex/devdocs/init.md | 6 +- codex/devdocs/isbitsunionarrays.md | 13 + codex/manual/parallel-computing.md | 1156 ++++++++++++++++------------ make.jl | 1 + src/NEWS.md | 10 +- src/base/base.md | 2 + src/base/collections.md | 2 + src/base/numbers.md | 3 + src/devdocs/init.md | 6 +- src/devdocs/isbitsunionarrays.md | 13 + src/manual/parallel-computing.md | 1156 ++++++++++++++++------------ 15 files changed, 1361 insertions(+), 1024 deletions(-) create mode 100644 codex/devdocs/isbitsunionarrays.md create mode 100644 src/devdocs/isbitsunionarrays.md diff --git a/codex/NEWS.md b/codex/NEWS.md index f0447fb..30611c5 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -520,9 +520,9 @@ This section lists changes that do not have deprecation warnings. This change makes `@schedule` redundant with `@async`, so `@schedule` has been deprecated ([#27164](https://github.com/JuliaLang/julia/issues/27164)). - * `norm(A::AbstractMatrix, p=2)` computes no longer the operator/matrix norm but the `norm` of `A` - as for other iterables, i.e. as if it were a vector. Especially, `norm(A::AbstractMatrix)` is the - Frobenius norm. To compute the operator/matrix norm, use the new function `opnorm` ([#27401](https://github.com/JuliaLang/julia/issues/27401)). + * `norm(A::AbstractMatrix, p=2)` computes no longer the operator/matrix norm but the `norm` of `A` + as for other iterables, i.e. as if it were a vector. Especially, `norm(A::AbstractMatrix)` is the + Frobenius norm. To compute the operator/matrix norm, use the new function `opnorm` ([#27401](https://github.com/JuliaLang/julia/issues/27401)). * `dot(u, v)` now acts recursively. Instead of `sum(u[i]' * v[i] for i in ...)`, it computes `sum(dot(u[i], v[i]) for i in ...)`, similarly to `vecdot` before ([#27401](https://github.com/JuliaLang/julia/issues/27401)). @@ -532,12 +532,16 @@ This section lists changes that do not have deprecation warnings. cores present on the CPU. Similarly, the environment variable `JULIA_CPU_CORES` is deprecated in favor of `JULIA_CPU_THREADS` ([#27856](https://github.com/JuliaLang/julia/issues/27856)). + * `WeakKeyDict` does not convert keys on insertion anymore (#24941). + Library improvements -------------------- * The function `thisind(s::AbstractString, i::Integer)` returns the largest valid index less or equal than `i` in the string `s` or `0` if no such index exists ([#24414](https://github.com/JuliaLang/julia/issues/24414)). + * Support for Unicode 11 ([#28266](https://github.com/JuliaLang/julia/issues/28266)). + * `Char` is now a subtype of `AbstractChar`, and most of the functions that take character arguments now accept any `AbstractChar` ([#26286](https://github.com/JuliaLang/julia/issues/26286)). diff --git a/codex/base/base.md b/codex/base/base.md index 00ed2db..36e47cc 100644 --- a/codex/base/base.md +++ b/codex/base/base.md @@ -220,6 +220,8 @@ Base.@goto Base.@label Base.@simd Base.@polly +Base.@generated +Base.@pure ``` ## Missing Values diff --git a/codex/base/collections.md b/codex/base/collections.md index bc7c6a4..0e1ece3 100644 --- a/codex/base/collections.md +++ b/codex/base/collections.md @@ -176,6 +176,8 @@ two functions for custom types to override how they are stored in a hash table. [`WeakKeyDict`](@ref) is a hash table implementation where the keys are weak references to objects, and thus may be garbage collected even when referenced in a hash table. +Like `Dict` it uses `hash` for hashing and `isequal` for equality, unlike `Dict` it does +not convert keys on insertion. [`Dict`](@ref)s can be created by passing pair objects constructed with `=>` to a [`Dict`](@ref) constructor: `Dict("A"=>1, "B"=>2)`. This call will attempt to infer type information from the diff --git a/codex/base/numbers.md b/codex/base/numbers.md index deea1c2..190584b 100644 --- a/codex/base/numbers.md +++ b/codex/base/numbers.md @@ -109,6 +109,8 @@ Base.trailing_zeros Base.trailing_ones Base.isodd Base.iseven +Base.@int128_str +Base.@uint128_str ``` ## BigFloats @@ -124,4 +126,5 @@ Base.MPFR.BigFloat(x, prec::Int) BigFloat(x::Union{Integer, AbstractFloat, String}, rounding::RoundingMode) Base.MPFR.BigFloat(x, prec::Int, rounding::RoundingMode) Base.MPFR.BigFloat(x::String) +Base.@big_str ``` diff --git a/codex/devdocs/init.md b/codex/devdocs/init.md index fcd427e..056186d 100644 --- a/codex/devdocs/init.md +++ b/codex/devdocs/init.md @@ -10,11 +10,11 @@ Execution starts at [`main()` in `ui/repl.c`](https://github.com/JuliaLang/julia to set the C library locale and to initialize the "ios" library (see [`ios_init_stdstreams()`](https://github.com/JuliaLang/julia/blob/master/src/support/ios.c) and [Legacy `ios.c` library](@ref)). -Next [`parse_opts()`](https://github.com/JuliaLang/julia/blob/master/ui/repl.c) is called to process -command line options. Note that `parse_opts()` only deals with options that affect code generation +Next [`jl_parse_opts()`](https://github.com/JuliaLang/julia/blob/master/src/jloptions.c) is called to process +command line options. Note that `jl_parse_opts()` only deals with options that affect code generation or early initialization. Other options are handled later by [`process_options()` in `base/client.jl`](https://github.com/JuliaLang/julia/blob/master/base/client.jl). -`parse_opts()` stores command line options in the [global `jl_options` struct](https://github.com/JuliaLang/julia/blob/master/src/julia.h). +`jl_parse_opts()` stores command line options in the [global `jl_options` struct](https://github.com/JuliaLang/julia/blob/master/src/julia.h). ## julia_init() diff --git a/codex/devdocs/isbitsunionarrays.md b/codex/devdocs/isbitsunionarrays.md new file mode 100644 index 0000000..9831998 --- /dev/null +++ b/codex/devdocs/isbitsunionarrays.md @@ -0,0 +1,13 @@ +# isbits Union Optimizations + +In Julia, the `Array` type holds both "bits" values as well as heap-allocated "boxed" values. The distinction is whether the value itself is stored inline (in the direct allocated memory of the array), or if the memory of the array is simply a collection of pointers to objects allocated elsewhere. In terms of performance, accessing values inline is clearly an advantage over having to follow a pointer to the actual value. The definition of "isbits" generally means any Julia type with a fixed, determinate size, meaning no "pointer" fields, see `?isbitstype`. + +Julia also supports Union types, quite literally the union of a set of types. Custom Union type definitions can be extremely handy for applications wishing to "cut across" the nominal type system (i.e. explicit subtype relationships) and define methods or functionality on these, otherwise unrelated, set of types. A compiler challenge, however, is in determining how to treat these Union types. The naive approach (and indeed, what Julia itself did pre-0.7), is to simply make a "box" and then a pointer in the box to the actual value, similar to the previously mentioned "boxed" values. This is unfortunate, however, because of the number of small, primitive "bits" types (think `UInt8`, `Int32`, `Float64`, etc.) that would easily fit themselves inline in this "box" without needing any indirection for value access. There are two main ways Julia can take advantage of this optimization as of 0.7: isbits Union fields in types, and isbits Union Arrays. + +## isbits Union Structs + +Julia now includes an optimization wherein "isbits Union" fields in types (`mutable struct`, `struct`, etc.) will be stored inline. This is accomplished by determining the "inline size" of the Union type (e.g. `Union{UInt8, Int16}` will have a size of 16 bytes, which represents the size needed of the largest Union type `Int16`), and in addition, allocating an extra "type tag byte" (`UInt8`), whose value signals the type of the actual value stored inline of the "Union bytes". The type tag byte value is the index of the actual value's type in the Union type's order of types. For example, a type tag value of `0x02` for a field with type `Union{Nothing, UInt8, Int16}` would indicate that an `Int16` value is stored in the 16 bytes of the field in the structure's memory; a `0x01` value would indicate that a `UInt8` value was stored in the first 8 bytes of the 16 bytes of the field's memory. Lastly, a value of `0x00` signals that the `nothing` value will be returned for this field, even though, as a singleton type with a single type instance, it technically has a size of 0. The type tag byte for a type's Union field is stored directly after the field's computed Union memory. + +## isbits Union Arrays + +Julia can now also store "isbits Union" values inline in an Array, as opposed to requiring an indirection box. The optimization is accomplished by storing an extra "type tag array" of bytes, one byte per array element, alongside the bytes of the actual array data. This type tag array serves the same function as the type field case: it's value signals the type of the actual stored Union value in the array. In terms of layout, a Julia Array can include extra "buffer" space before and after it's actual data values, which are tracked in the `a->offset` and `a->maxsize` fields of the `jl_array_t*` type. The "type tag array" is treated exactly as another `jl_array_t*`, but which shares the same `a->offset`, `a->maxsize`, and `a->len` fields. So the formula to access an isbits Union Array's type tag bytes is `a->data + (a->maxsize - a->offset) * a->elsize + a->offset`; i.e. the Array's `a->data` pointer is already shifted by `a->offset`, so correcting for that, we follow the data all the way to the max of what it can hold `a->maxsize`, then adjust by `a->ofset` more bytes to account for any present "front buffering" the array might be doing. This layout in particular allows for very efficient resizing operations as the type tag data only ever has to move when the actual array's data has to move. \ No newline at end of file diff --git a/codex/manual/parallel-computing.md b/codex/manual/parallel-computing.md index 481c296..a803696 100644 --- a/codex/manual/parallel-computing.md +++ b/codex/manual/parallel-computing.md @@ -1,12 +1,510 @@ # Parallel Computing -This part of the manual details the following types of parallel programming available in Julia. +For newcomers to multi-threading and parallel computing it can be useful to first appreciate +the different levels of parallelism offered by Julia. We can divide them in three main categories : + +1. Julia Coroutines (Green Threading) +2. Multi-Threading +3. Multi-Core or Distributed Processing + +We will first consider Julia [Tasks (aka Coroutines)](@ref man-tasks) and other modules that rely on the Julia runtime library, that allow to suspend and resume computations with full control of inter-`Tasks` communication without having to manually interface with the operative system's scheduler. +Julia also allows to communicate between `Tasks` through operations like [`wait`](@ref) and [`fetch`](@ref). +Communication and data synchronization is managed through [`Channel`](@ref)s, which are the conduit +that allows inter-`Tasks` communication. + +Julia also supports experimental multi-threading, where execution is forked and an anonymous function is run across all +threads. +Described as a fork-join approach, parallel threads are branched off and they all have to join the Julia main thread to make serial execution continue. +Multi-threading is supported using the `Base.Threads` module that is still considered experimental, as Julia is +not fully thread-safe yet. In particular segfaults seem to emerge for I\O operations and task switching. +As an un up-to-date reference, keep an eye on [the issue tracker](https://github.com/JuliaLang/julia/issues?q=is%3Aopen+is%3Aissue+label%3Amultithreading). +Multi-Threading should only be used if you take into consideration global variables, locks and +atomics, so we will explain it later. + +In the end we will present Julia's way to distributed and parallel computing. With scientific computing +in mind, Julia natively implements interfaces to distribute a process through multiple cores or machines. +Also we will mention useful external packages for distributed programming like `MPI.jl` and `DistributedArrays.jl`. + +# Coroutines + +Julia's parallel programming platform uses [Tasks (aka Coroutines)](@ref man-tasks) to switch among multiple computations. +To express an order of execution between lightweight threads communication primitives are necessary. +Julia offers `Channel(func::Function, ctype=Any, csize=0, taskref=nothing)` that creates a new task from `func`, +binds it to a new channel of type `ctype` and size `csize` and schedule the task. +`Channels` can serve as a way to communicate between tasks, as `Channel{T}(sz::Int)` creates a buffered channel of type `T` and size `sz`. +Whenever code performs a communication operation like [`fetch`](@ref) or [`wait`](@ref), +the current task is suspended and a scheduler picks another task to run. +A task is restarted when the event it is waiting for completes. -1. Distributed memory using multiple processes on one or more nodes -2. Shared memory using multiple processes on a single node -3. Multi-threading +For many problems, it is not necessary to think about tasks directly. However, they can be used +to wait for multiple events at the same time, which provides for *dynamic scheduling*. In dynamic +scheduling, a program decides what to compute or where to compute it based on when other jobs +finish. This is needed for unpredictable or unbalanced workloads, where we want to assign more +work to processes only when they finish their current tasks. + +## Channels + +The section on [`Task`](@ref)s in [Control Flow](@ref) discussed the execution of multiple functions in +a co-operative manner. [`Channel`](@ref)s can be quite useful to pass data between running tasks, particularly +those involving I/O operations. + +Examples of operations involving I/O include reading/writing to files, accessing web services, +executing external programs, etc. In all these cases, overall execution time can be improved if +other tasks can be run while a file is being read, or while waiting for an external service/program +to complete. + +A channel can be visualized as a pipe, i.e., it has a write end and a read end : + + * Multiple writers in different tasks can write to the same channel concurrently via [`put!`](@ref) + calls. + * Multiple readers in different tasks can read data concurrently via [`take!`](@ref) calls. + * As an example: + + ```julia + # Given Channels c1 and c2, + c1 = Channel(32) + c2 = Channel(32) + + # and a function `foo` which reads items from from c1, processes the item read + # and writes a result to c2, + function foo() + while true + data = take!(c1) + [...] # process data + put!(c2, result) # write out result + end + end + + # we can schedule `n` instances of `foo` to be active concurrently. + for _ in 1:n + @schedule foo() + end + ``` +* Channels are created via the `Channel{T}(sz)` constructor. The channel will only hold objects + of type `T`. If the type is not specified, the channel can hold objects of any type. `sz` refers + to the maximum number of elements that can be held in the channel at any time. For example, `Channel(32)` + creates a channel that can hold a maximum of 32 objects of any type. A `Channel{MyType}(64)` can + hold up to 64 objects of `MyType` at any time. +* If a [`Channel`](@ref) is empty, readers (on a [`take!`](@ref) call) will block until data is available. +* If a [`Channel`](@ref) is full, writers (on a [`put!`](@ref) call) will block until space becomes available. +* [`isready`](@ref) tests for the presence of any object in the channel, while [`wait`](@ref) + waits for an object to become available. +* A [`Channel`](@ref) is in an open state initially. This means that it can be read from and written to + freely via [`take!`](@ref) and [`put!`](@ref) calls. [`close`](@ref) closes a [`Channel`](@ref). + On a closed [`Channel`](@ref), [`put!`](@ref) will fail. For example: + +```julia-repl +julia> c = Channel(2); + +julia> put!(c, 1) # `put!` on an open channel succeeds +1 + +julia> close(c); + +julia> put!(c, 2) # `put!` on a closed channel throws an exception. +ERROR: InvalidStateException("Channel is closed.",:closed) +Stacktrace: +[...] +``` + + * [`take!`](@ref) and [`fetch`](@ref) (which retrieves but does not remove the value) on a closed + channel successfully return any existing values until it is emptied. Continuing the above example: + +```julia-repl +julia> fetch(c) # Any number of `fetch` calls succeed. +1 + +julia> fetch(c) +1 + +julia> take!(c) # The first `take!` removes the value. +1 + +julia> take!(c) # No more data available on a closed channel. +ERROR: InvalidStateException("Channel is closed.",:closed) +Stacktrace: +[...] +``` + +A `Channel` can be used as an iterable object in a `for` loop, in which case the loop runs as +long as the `Channel` has data or is open. The loop variable takes on all values added to the +`Channel`. The `for` loop is terminated once the `Channel` is closed and emptied. + +For example, the following would cause the `for` loop to wait for more data: + +```julia-repl +julia> c = Channel{Int}(10); + +julia> foreach(i->put!(c, i), 1:3) # add a few entries + +julia> data = [i for i in c] +``` + +while this will return after reading all data: + +```julia-repl +julia> c = Channel{Int}(10); + +julia> foreach(i->put!(c, i), 1:3); # add a few entries + +julia> close(c); # `for` loops can exit + +julia> data = [i for i in c] +3-element Array{Int64,1}: + 1 + 2 + 3 +``` + +Consider a simple example using channels for inter-task communication. We start 4 tasks to process +data from a single `jobs` channel. Jobs, identified by an id (`job_id`), are written to the channel. +Each task in this simulation reads a `job_id`, waits for a random amout of time and writes back +a tuple of `job_id` and the simulated time to the results channel. Finally all the `results` are +printed out. + +```julia-repl +julia> const jobs = Channel{Int}(32); + +julia> const results = Channel{Tuple}(32); + +julia> function do_work() + for job_id in jobs + exec_time = rand() + sleep(exec_time) # simulates elapsed time doing actual work + # typically performed externally. + put!(results, (job_id, exec_time)) + end + end; + +julia> function make_jobs(n) + for i in 1:n + put!(jobs, i) + end + end; + +julia> n = 12; + +julia> @schedule make_jobs(n); # feed the jobs channel with "n" jobs + +julia> for i in 1:4 # start 4 tasks to process requests in parallel + @schedule do_work() + end + +julia> @elapsed while n > 0 # print out results + job_id, exec_time = take!(results) + println("$job_id finished in $(round(exec_time,2)) seconds") + n = n - 1 + end +4 finished in 0.22 seconds +3 finished in 0.45 seconds +1 finished in 0.5 seconds +7 finished in 0.14 seconds +2 finished in 0.78 seconds +5 finished in 0.9 seconds +9 finished in 0.36 seconds +6 finished in 0.87 seconds +8 finished in 0.79 seconds +10 finished in 0.64 seconds +12 finished in 0.5 seconds +11 finished in 0.97 seconds +0.029772311 +``` + +The current version of Julia multiplexes all tasks onto a single OS thread. Thus, while tasks +involving I/O operations benefit from parallel execution, compute bound tasks are effectively +executed sequentially on a single OS thread. Future versions of Julia may support scheduling of +tasks on multiple threads, in which case compute bound tasks will see benefits of parallel execution +too. + +# Multi-Threading (Experimental) + +In addition to tasks Julia forwards natively supports multi-threading. +Note that this section is experimental and the interfaces may change in the future. + +## Setup + +By default, Julia starts up with a single thread of execution. This can be verified by using the +command [`Threads.nthreads()`](@ref): + +```julia-repl +julia> Threads.nthreads() +1 +``` + +The number of threads Julia starts up with is controlled by an environment variable called `JULIA_NUM_THREADS`. +Now, let's start up Julia with 4 threads: + +```bash +export JULIA_NUM_THREADS=4 +``` + +(The above command works on bourne shells on Linux and OSX. Note that if you're using a C shell +on these platforms, you should use the keyword `set` instead of `export`. If you're on Windows, +start up the command line in the location of `julia.exe` and use `set` instead of `export`.) + +Let's verify there are 4 threads at our disposal. + +```julia-repl +julia> Threads.nthreads() +4 +``` + +But we are currently on the master thread. To check, we use the function [`Threads.threadid`](@ref) + +```julia-repl +julia> Threads.threadid() +1 +``` + +## The `@threads` Macro + +Let's work a simple example using our native threads. Let us create an array of zeros: + +```jldoctest +julia> a = zeros(10) +10-element Array{Float64,1}: + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 +``` + +Let us operate on this array simultaneously using 4 threads. We'll have each thread write its +thread ID into each location. + +Julia supports parallel loops using the [`Threads.@threads`](@ref) macro. This macro is affixed +in front of a `for` loop to indicate to Julia that the loop is a multi-threaded region: + +```julia-repl +julia> Threads.@threads for i = 1:10 + a[i] = Threads.threadid() + end +``` + +The iteration space is split amongst the threads, after which each thread writes its thread ID +to its assigned locations: + +```julia-repl +julia> a +10-element Array{Float64,1}: + 1.0 + 1.0 + 1.0 + 2.0 + 2.0 + 2.0 + 3.0 + 3.0 + 4.0 + 4.0 +``` + +Note that [`Threads.@threads`](@ref) does not have an optional reduction parameter like [`@distributed`](@ref). + +## Atomic Operations + +Julia supports accessing and modifying values *atomically*, that is, in a thread-safe way to avoid +[race conditions](https://en.wikipedia.org/wiki/Race_condition). A value (which must be of a primitive +type) can be wrapped as [`Threads.Atomic`](@ref) to indicate it must be accessed in this way. +Here we can see an example: + +```julia-repl +julia> i = Threads.Atomic{Int}(0); + +julia> ids = zeros(4); + +julia> old_is = zeros(4); + +julia> Threads.@threads for id in 1:4 + old_is[id] = Threads.atomic_add!(i, id) + ids[id] = id + end + +julia> old_is +4-element Array{Float64,1}: + 0.0 + 1.0 + 7.0 + 3.0 + +julia> ids +4-element Array{Float64,1}: + 1.0 + 2.0 + 3.0 + 4.0 +``` + +Had we tried to do the addition without the atomic tag, we might have gotten the +wrong answer due to a race condition. An example of what would happen if we didn't +avoid the race: + +```julia-repl +julia> using Base.Threads + +julia> nthreads() +4 + +julia> acc = Ref(0) +Base.RefValue{Int64}(0) + +julia> @threads for i in 1:1000 + acc[] += 1 + end + +julia> acc[] +926 + +julia> acc = Atomic{Int64}(0) +Atomic{Int64}(0) + +julia> @threads for i in 1:1000 + atomic_add!(acc, 1) + end + +julia> acc[] +1000 +``` + +!!! note + Not *all* primitive types can be wrapped in an `Atomic` tag. Supported types + are `Int8`, `Int16`, `Int32`, `Int64`, `Int128`, `UInt8`, `UInt16`, `UInt32`, + `UInt64`, `UInt128`, `Float16`, `Float32`, and `Float64`. Additionally, + `Int128` and `UInt128` are not supported on AAarch32 and ppc64le. + +## Side effects and mutable function arguments + +When using multi-threading we have to be careful when using functions that are not +[pure](https://en.wikipedia.org/wiki/Pure_function) as we might get a wrong answer. +For instance functions that have their +[name ending with `!`](https://docs.julialang.org/en/latest/manual/style-guide/#Append-!-to-names-of-functions-that-modify-their-arguments-1) +by convention modify their arguments and thus are not pure. However, there are +functions that have side effects and their name does not end with `!`. For +instance [`findfirst(regex, str)`](@ref) mutates its `regex` argument or +[`rand()`](@ref) changes `Base.GLOBAL_RNG` : + +```julia-repl +julia> using Base.Threads + +julia> nthreads() +4 + +julia> function f() + s = repeat(["123", "213", "231"], outer=1000) + x = similar(s, Int) + rx = r"1" + @threads for i in 1:3000 + x[i] = findfirst(rx, s[i]).start + end + count(v -> v == 1, x) + end +f (generic function with 1 method) + +julia> f() # the correct result is 1000 +1017 + +julia> function g() + a = zeros(1000) + @threads for i in 1:1000 + a[i] = rand() + end + length(unique(a)) + end +g (generic function with 1 method) + +julia> srand(1); g() # the result for a single thread is 1000 +781 +``` + +In such cases one should redesign the code to avoid the possibility of a race condition or use +[synchronization primitives](https://docs.julialang.org/en/latest/base/multi-threading/#Synchronization-Primitives-1). + +For example in order to fix `findfirst` example above one needs to have a +separate copy of `rx` variable for each thread: + +```julia-repl +julia> function f_fix() + s = repeat(["123", "213", "231"], outer=1000) + x = similar(s, Int) + rx = [Regex("1") for i in 1:nthreads()] + @threads for i in 1:3000 + x[i] = findfirst(rx[threadid()], s[i]).start + end + count(v -> v == 1, x) + end +f_fix (generic function with 1 method) + +julia> f_fix() +1000 +``` + +We now use `Regex("1")` instead of `r"1"` to make sure that Julia +creates separate instances of `Regex` object for each entry of `rx` vector. + +The case of `rand` is a bit more complex as we have to ensure that each thread +uses non-overlapping pseudorandom number sequences. This can be simply ensured +by using `Future.randjump` function: + + +```julia-repl +julia> using Random; import Future -# Distributed Memory Parallelism +julia> function g_fix(r) + a = zeros(1000) + @threads for i in 1:1000 + a[i] = rand(r[threadid()]) + end + length(unique(a)) + end +g_fix (generic function with 1 method) + +julia> r = let m = MersenneTwister(1) + [m; accumulate(Future.randjump, m, fill(big(10)^20, nthreads()-1))] + end; + +julia> g_fix(r) +1000 +``` + +We pass the `r` vector to `g_fix` as generating several RGNs is an expensive +operation so we do not want to repeat it every time we run the function. + +## @threadcall (Experimental) + +All I/O tasks, timers, REPL commands, etc are multiplexed onto a single OS thread via an event +loop. A patched version of libuv ([http://docs.libuv.org/en/v1.x/](http://docs.libuv.org/en/v1.x/)) +provides this functionality. Yield points provide for co-operatively scheduling multiple tasks +onto the same OS thread. I/O tasks and timers yield implicitly while waiting for the event to +occur. Calling [`yield`](@ref) explicitly allows for other tasks to be scheduled. + +Thus, a task executing a [`ccall`](@ref) effectively prevents the Julia scheduler from executing any other +tasks till the call returns. This is true for all calls into external libraries. Exceptions are +calls into custom C code that call back into Julia (which may then yield) or C code that calls +`jl_yield()` (C equivalent of [`yield`](@ref)). + +Note that while Julia code runs on a single thread (by default), libraries used by Julia may launch +their own internal threads. For example, the BLAS library may start as many threads as there are +cores on a machine. + +The [`@threadcall`](@ref) macro addresses scenarios where we do not want a [`ccall`](@ref) to block the main Julia +event loop. It schedules a C function for execution in a separate thread. A threadpool with a +default size of 4 is used for this. The size of the threadpool is controlled via environment variable +`UV_THREADPOOL_SIZE`. While waiting for a free thread, and during function execution once a thread +is available, the requesting task (on the main Julia event loop) yields to other tasks. Note that +`@threadcall` does not return till the execution is complete. From a user point of view, it is +therefore a blocking call like other Julia APIs. + +It is very important that the called function does not call back into Julia, as it will segfault. + +`@threadcall` may be removed/changed in future versions of Julia. + +# Multi-Core or Distributed Processing An implementation of distributed memory parallel computing is provided by module `Distributed` as part of the standard library shipped with Julia. @@ -121,6 +619,24 @@ An important thing to remember is that, once fetched, a [`Future`](@ref) will ca locally. Further [`fetch`](@ref) calls do not entail a network hop. Once all referencing [`Future`](@ref)s have fetched, the remote stored value is deleted. +[`@async`](@ref) is similar to [`@spawn`](@ref), but only runs tasks on the local process. We +use it to create a "feeder" task for each process. Each task picks the next index that needs to +be computed, then waits for its process to finish, then repeats until we run out of indices. Note +that the feeder tasks do not begin to execute until the main task reaches the end of the [`@sync`](@ref) +block, at which point it surrenders control and waits for all the local tasks to complete before +returning from the function. +As for v0.7 and beyond, the feeder tasks are able to share state via `nextidx` because +they all run on the same process. +Even if `Tasks` are scheduled cooperatively, locking may still be required in some contexts, as in [asynchronous I\O](https://docs.julialang.org/en/stable/manual/faq/#Asynchronous-IO-and-concurrent-synchronous-writes-1). +This means context switches only occur at well-defined points: in this case, +when [`remotecall_fetch`](@ref) is called. This is the current state of implementation (dev v0.7) and it may change +for future Julia versions, as it is intended to make it possible to run up to N `Tasks` on M `Process`, aka +[M:N Threading](https://en.wikipedia.org/wiki/Thread_(computing)#Models). Then a lock acquiring\releasing +model for `nextidx` will be needed, as it is not safe to let multiple processes read-write a resource at +the same time. + + + ## Code Availability and Loading Packages Your code must be available on any process that runs it. For example, type the following into @@ -295,7 +811,7 @@ and `fetch(Bref)`, it might be better to eliminate the parallelism altogether. O is replaced with a more expensive operation. Then it might make sense to add another [`@spawn`](@ref) statement just for this step. -# Global variables +## Global variables Expressions executed remotely via `@spawn`, or closures specified for remote execution using `remotecall` may refer to global variables. Global bindings under module `Main` are treated a little differently compared to global bindings in other modules. Consider the following code @@ -462,266 +978,28 @@ end Here each iteration applies `f` to a randomly-chosen sample from a vector `a` shared by all processes. -As you could see, the reduction operator can be omitted if it is not needed. In that case, the -loop executes asynchronously, i.e. it spawns independent tasks on all available workers and returns -an array of [`Future`](@ref) immediately without waiting for completion. The caller can wait for -the [`Future`](@ref) completions at a later point by calling [`fetch`](@ref) on them, or wait -for completion at the end of the loop by prefixing it with [`@sync`](@ref), like `@sync @distributed for`. - -In some cases no reduction operator is needed, and we merely wish to apply a function to all integers -in some range (or, more generally, to all elements in some collection). This is another useful -operation called *parallel map*, implemented in Julia as the [`pmap`](@ref) function. For example, -we could compute the singular values of several large random matrices in parallel as follows: - -```julia-repl -julia> M = Matrix{Float64}[rand(1000,1000) for i = 1:10]; - -julia> pmap(svdvals, M); -``` - -Julia's [`pmap`](@ref) is designed for the case where each function call does a large amount -of work. In contrast, `@distributed for` can handle situations where each iteration is tiny, perhaps -merely summing two numbers. Only worker processes are used by both [`pmap`](@ref) and `@distributed for` -for the parallel computation. In case of `@distributed for`, the final reduction is done on the calling -process. - -## Synchronization With Remote References - -## Scheduling - -Julia's parallel programming platform uses [Tasks (aka Coroutines)](@ref man-tasks) to switch among multiple -computations. Whenever code performs a communication operation like [`fetch`](@ref) or [`wait`](@ref), -the current task is suspended and a scheduler picks another task to run. A task is restarted when -the event it is waiting for completes. - -For many problems, it is not necessary to think about tasks directly. However, they can be used -to wait for multiple events at the same time, which provides for *dynamic scheduling*. In dynamic -scheduling, a program decides what to compute or where to compute it based on when other jobs -finish. This is needed for unpredictable or unbalanced workloads, where we want to assign more -work to processes only when they finish their current tasks. - -As an example, consider computing the singular values of matrices of different sizes: - -```julia-repl -julia> M = Matrix{Float64}[rand(800,800), rand(600,600), rand(800,800), rand(600,600)]; - -julia> pmap(svdvals, M); -``` - -If one process handles both 800×800 matrices and another handles both 600×600 matrices, we will -not get as much scalability as we could. The solution is to make a local task to "feed" work to -each process when it completes its current task. For example, consider a simple [`pmap`](@ref) -implementation: - -```julia -function pmap(f, lst) - np = nprocs() # determine the number of processes available - n = length(lst) - results = Vector{Any}(n) - i = 1 - # function to produce the next work item from the queue. - # in this case it's just an index. - nextidx() = (global i; idx=i; i+=1; idx) - @sync begin - for p=1:np - if p != myid() || np == 1 - @async begin - while true - idx = nextidx() - idx > n && break - results[idx] = remotecall_fetch(f, p, lst[idx]) - end - end - end - end - end - results -end -``` - -[`@async`](@ref) is similar to [`@spawn`](@ref), but only runs tasks on the local process. We -use it to create a "feeder" task for each process. Each task picks the next index that needs to -be computed, then waits for its process to finish, then repeats until we run out of indices. Note -that the feeder tasks do not begin to execute until the main task reaches the end of the [`@sync`](@ref) -block, at which point it surrenders control and waits for all the local tasks to complete before -returning from the function. The feeder tasks are able to share state via `nextidx` because -they all run on the same process. No locking is required, since the threads are scheduled cooperatively -and not preemptively. This means context switches only occur at well-defined points: in this case, -when [`remotecall_fetch`](@ref) is called. - -## Channels - -The section on [`Task`](@ref)s in [Control Flow](@ref) discussed the execution of multiple functions in -a co-operative manner. [`Channel`](@ref)s can be quite useful to pass data between running tasks, particularly -those involving I/O operations. - -Examples of operations involving I/O include reading/writing to files, accessing web services, -executing external programs, etc. In all these cases, overall execution time can be improved if -other tasks can be run while a file is being read, or while waiting for an external service/program -to complete. - -A channel can be visualized as a pipe, i.e., it has a write end and read end. - - * Multiple writers in different tasks can write to the same channel concurrently via [`put!`](@ref) - calls. - * Multiple readers in different tasks can read data concurrently via [`take!`](@ref) calls. - * As an example: - - ```julia - # Given Channels c1 and c2, - c1 = Channel(32) - c2 = Channel(32) - - # and a function `foo` which reads items from from c1, processes the item read - # and writes a result to c2, - function foo() - while true - data = take!(c1) - [...] # process data - put!(c2, result) # write out result - end - end - - # we can schedule `n` instances of `foo` to be active concurrently. - for _ in 1:n - @async foo() - end - ``` - * Channels are created via the `Channel{T}(sz)` constructor. The channel will only hold objects - of type `T`. If the type is not specified, the channel can hold objects of any type. `sz` refers - to the maximum number of elements that can be held in the channel at any time. For example, `Channel(32)` - creates a channel that can hold a maximum of 32 objects of any type. A `Channel{MyType}(64)` can - hold up to 64 objects of `MyType` at any time. - * If a [`Channel`](@ref) is empty, readers (on a [`take!`](@ref) call) will block until data is available. - * If a [`Channel`](@ref) is full, writers (on a [`put!`](@ref) call) will block until space becomes available. - * [`isready`](@ref) tests for the presence of any object in the channel, while [`wait`](@ref) - waits for an object to become available. - * A [`Channel`](@ref) is in an open state initially. This means that it can be read from and written to - freely via [`take!`](@ref) and [`put!`](@ref) calls. [`close`](@ref) closes a [`Channel`](@ref). - On a closed [`Channel`](@ref), [`put!`](@ref) will fail. For example: - -```julia-repl -julia> c = Channel(2); - -julia> put!(c, 1) # `put!` on an open channel succeeds -1 - -julia> close(c); - -julia> put!(c, 2) # `put!` on a closed channel throws an exception. -ERROR: InvalidStateException("Channel is closed.",:closed) -Stacktrace: -[...] -``` - - * [`take!`](@ref) and [`fetch`](@ref) (which retrieves but does not remove the value) on a closed - channel successfully return any existing values until it is emptied. Continuing the above example: - -```julia-repl -julia> fetch(c) # Any number of `fetch` calls succeed. -1 - -julia> fetch(c) -1 - -julia> take!(c) # The first `take!` removes the value. -1 - -julia> take!(c) # No more data available on a closed channel. -ERROR: InvalidStateException("Channel is closed.",:closed) -Stacktrace: -[...] -``` - -A `Channel` can be used as an iterable object in a `for` loop, in which case the loop runs as -long as the `Channel` has data or is open. The loop variable takes on all values added to the -`Channel`. The `for` loop is terminated once the `Channel` is closed and emptied. - -For example, the following would cause the `for` loop to wait for more data: - -```julia-repl -julia> c = Channel{Int}(10); - -julia> foreach(i->put!(c, i), 1:3) # add a few entries - -julia> data = [i for i in c] -``` - -while this will return after reading all data: - -```julia-repl -julia> c = Channel{Int}(10); - -julia> foreach(i->put!(c, i), 1:3); # add a few entries - -julia> close(c); # `for` loops can exit - -julia> data = [i for i in c] -3-element Array{Int64,1}: - 1 - 2 - 3 -``` - -Consider a simple example using channels for inter-task communication. We start 4 tasks to process -data from a single `jobs` channel. Jobs, identified by an id (`job_id`), are written to the channel. -Each task in this simulation reads a `job_id`, waits for a random amount of time and writes back -a tuple of `job_id` and the simulated time to the results channel. Finally all the `results` are -printed out. - -```julia-repl -julia> const jobs = Channel{Int}(32); - -julia> const results = Channel{Tuple}(32); - -julia> function do_work() - for job_id in jobs - exec_time = rand() - sleep(exec_time) # simulates elapsed time doing actual work - # typically performed externally. - put!(results, (job_id, exec_time)) - end - end; - -julia> function make_jobs(n) - for i in 1:n - put!(jobs, i) - end - end; - -julia> n = 12; - -julia> @async make_jobs(n); # feed the jobs channel with "n" jobs - -julia> for i in 1:4 # start 4 tasks to process requests in parallel - @async do_work() - end - -julia> @elapsed while n > 0 # print out results - job_id, exec_time = take!(results) - println("$job_id finished in $(round(exec_time,2)) seconds") - n = n - 1 - end -4 finished in 0.22 seconds -3 finished in 0.45 seconds -1 finished in 0.5 seconds -7 finished in 0.14 seconds -2 finished in 0.78 seconds -5 finished in 0.9 seconds -9 finished in 0.36 seconds -6 finished in 0.87 seconds -8 finished in 0.79 seconds -10 finished in 0.64 seconds -12 finished in 0.5 seconds -11 finished in 0.97 seconds -0.029772311 +As you could see, the reduction operator can be omitted if it is not needed. In that case, the +loop executes asynchronously, i.e. it spawns independent tasks on all available workers and returns +an array of [`Future`](@ref) immediately without waiting for completion. The caller can wait for +the [`Future`](@ref) completions at a later point by calling [`fetch`](@ref) on them, or wait +for completion at the end of the loop by prefixing it with [`@sync`](@ref), like `@sync @distributed for`. + +In some cases no reduction operator is needed, and we merely wish to apply a function to all integers +in some range (or, more generally, to all elements in some collection). This is another useful +operation called *parallel map*, implemented in Julia as the [`pmap`](@ref) function. For example, +we could compute the singular values of several large random matrices in parallel as follows: + +```julia-repl +julia> M = Matrix{Float64}[rand(1000,1000) for i = 1:10]; + +julia> pmap(svdvals, M); ``` -The current version of Julia multiplexes all tasks onto a single OS thread. Thus, while tasks -involving I/O operations benefit from parallel execution, compute bound tasks are effectively -executed sequentially on a single OS thread. Future versions of Julia may support scheduling of -tasks on multiple threads, in which case compute bound tasks will see benefits of parallel execution -too. +Julia's [`pmap`](@ref) is designed for the case where each function call does a large amount +of work. In contrast, `@distributed for` can handle situations where each iteration is tiny, perhaps +merely summing two numbers. Only worker processes are used by both [`pmap`](@ref) and `@distributed for` +for the parallel computation. In case of `@distributed for`, the final reduction is done on the calling +process. ## Remote References and AbstractChannels @@ -750,20 +1028,21 @@ A simple example of this is provided in `dictchannel.jl` in the [Examples repository](https://github.com/JuliaArchive/Examples), which uses a dictionary as its remote store. + ## Channels and RemoteChannels - * A [`Channel`](@ref) is local to a process. Worker 2 cannot directly refer to a `Channel` on worker 3 and + * A [`Channel`](@ref) is local to a process. Worker 2 cannot directly refer to a [`Channel`](@ref) on worker 3 and vice-versa. A [`RemoteChannel`](@ref), however, can put and take values across workers. - * A [`RemoteChannel`](@ref) can be thought of as a *handle* to a `Channel`. + * A [`RemoteChannel`](@ref) can be thought of as a *handle* to a [`Channel`](@ref). * The process id, `pid`, associated with a [`RemoteChannel`](@ref) identifies the process where - the backing store, i.e., the backing `Channel` exists. + the backing store, i.e., the backing [`Channel`](@ref) exists. * Any process with a reference to a [`RemoteChannel`](@ref) can put and take items from the channel. Data is automatically sent to (or retrieved from) the process a [`RemoteChannel`](@ref) is associated with. - * Serializing a `Channel` also serializes any data present in the channel. Deserializing it therefore + * Serializing a [`Channel`](@ref) also serializes any data present in the channel. Deserializing it therefore effectively makes a copy of the original object. * On the other hand, serializing a [`RemoteChannel`](@ref) only involves the serialization of an - identifier that identifies the location and instance of `Channel` referred to by the handle. A + identifier that identifies the location and instance of [`Channel`](@ref) referred to by the handle. A deserialized [`RemoteChannel`](@ref) object (on any worker), therefore also points to the same backing store as the original. @@ -825,7 +1104,7 @@ julia> @elapsed while n > 0 # print out results 0.055971741 ``` -## Remote References and Distributed Garbage Collection +### Remote References and Distributed Garbage Collection Objects referred to by remote references can be freed only when *all* held references in the cluster are deleted. @@ -1063,7 +1342,7 @@ julia> @time advection_shared!(q,u); The biggest advantage of `advection_shared!` is that it minimizes traffic among the workers, allowing each to compute for an extended time on the assigned piece. -## Shared Arrays and Distributed Garbage Collection +### Shared Arrays and Distributed Garbage Collection Like remote references, shared arrays are also dependent on garbage collection on the creating node to release references from all participating workers. Code which creates many short lived @@ -1234,7 +1513,7 @@ times during the worker's lifetime with appropriate `op` values: appropriate worker with an interrupt signal. * with `:finalize` for cleanup purposes. -## Cluster Managers with Custom Transports +### Cluster Managers with Custom Transports Replacing the default TCP/IP all-to-all socket connections with a custom transport layer is a little more involved. Each Julia process has as many communication tasks as the workers it is @@ -1292,7 +1571,7 @@ The default implementation simply executes an `exit()` call on the specified rem The Examples folder `clustermanager/simple` is an example that shows a simple implementation using UNIX domain sockets for cluster setup. -## Network Requirements for LocalManager and SSHManager +### Network Requirements for LocalManager and SSHManager Julia clusters are designed to be executed on already secured environments on infrastructure such as local laptops, departmental clusters, or even the cloud. This section covers network security @@ -1325,7 +1604,7 @@ requirements for the inbuilt `LocalManager` and `SSHManager`: Securing and encrypting all worker-worker traffic (via SSH) or encrypting individual messages can be done via a custom `ClusterManager`. -## [Cluster Cookie](@id man-cluster-cookie) +### [Cluster Cookie](@id man-cluster-cookie) All processes in a cluster share the same cookie which, by default, is a randomly generated string on the master process: @@ -1365,293 +1644,158 @@ Currently, sending a message between unconnected workers results in an error. Th as with the functionality and interface, should be considered experimental in nature and may change in future releases. -## Multi-Threading (Experimental) +## Noteworthy external packages -In addition to tasks, remote calls, and remote references, Julia from `v0.5` forwards natively -supports multi-threading. Note that this section is experimental and the interfaces may change -in the future. +Outside of Julia parallelism there are plenty of external packages that should be mentioned. +For example [MPI.jl](https://github.com/JuliaParallel/MPI.jl) is a Julia wrapper for the `MPI` protocol, or +[DistributedArrays.jl](https://github.com/JuliaParallel/Distributedarrays.jl), as presented in [Shared Arrays](@ref). +A mention must be done to the Julia's GPU programming ecosystem, which includes : -### Setup - -By default, Julia starts up with a single thread of execution. This can be verified by using the -command [`Threads.nthreads()`](@ref): +1. Low-level (C kernel) based operations [OpenCL.jl](https://github.com/JuliaGPU/OpenCL.jl) and [CUDAdrv.jl](https://github.com/JuliaGPU/CUDAdrv.jl) which are respectively an OpenCL interface and a CUDA wrapper. -```julia-repl -julia> Threads.nthreads() -1 -``` +2. Low-level (Julia Kernel) interfaces like [CUDAnative.jl](https://github.com/JuliaGPU/CUDAnative.jl) which is a Julia native CUDA implementation. -The number of threads Julia starts up with is controlled by an environment variable called `JULIA_NUM_THREADS`. -Now, let's start up Julia with 4 threads: +3. High-level vendor specific abstractions like [CuArrays.jl](https://github.com/JuliaGPU/CuArrays.jl) and [CLArrays.jl](https://github.com/JuliaGPU/CLArrays.jl) -```bash -export JULIA_NUM_THREADS=4 -``` +4. High-level libraries like [ArrayFire.jl](https://github.com/JuliaComputing/ArrayFire.jl) and [GPUArrays.jl](https://github.com/JuliaGPU/GPUArrays.jl) -(The above command works on bourne shells on Linux and OSX. Note that if you're using a C shell -on these platforms, you should use the keyword `set` instead of `export`. If you're on Windows, -start up the command line in the location of `julia.exe` and use `set` instead of `export`.) -Let's verify there are 4 threads at our disposal. +In the following example we will use both `DistributedArrays.jl` and `CuArrays.jl` to distribute an array across multiple +processes by first casting it through `distribute()` and `CuArray()`. -```julia-repl -julia> Threads.nthreads() -4 -``` +Remember when importing `DistributedArrays.jl` to import it across all processes using [`@everywhere`](@ref) -But we are currently on the master thread. To check, we use the function [`Threads.threadid`](@ref) ```julia-repl -julia> Threads.threadid() -1 -``` - -### The `@threads` Macro - -Let's work a simple example using our native threads. Let us create an array of zeros: - -```jldoctest -julia> a = zeros(10) -10-element Array{Float64,1}: - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 -``` +$ ./julia -p 4 -Let us operate on this array simultaneously using 4 threads. We'll have each thread write its -thread ID into each location. - -Julia supports parallel loops using the [`Threads.@threads`](@ref) macro. This macro is affixed -in front of a `for` loop to indicate to Julia that the loop is a multi-threaded region: +julia> addprocs() -```julia-repl -julia> Threads.@threads for i = 1:10 - a[i] = Threads.threadid() - end -``` +julia> @everywhere using DistributedArrays -The iteration space is split amongst the threads, after which each thread writes its thread ID -to its assigned locations: +julia> using CuArrays -```julia-repl -julia> a -10-element Array{Float64,1}: - 1.0 - 1.0 - 1.0 - 2.0 - 2.0 - 2.0 - 3.0 - 3.0 - 4.0 - 4.0 -``` +julia> B = ones(10_000) ./ 2; -Note that [`Threads.@threads`](@ref) does not have an optional reduction parameter like [`@distributed`](@ref). +julia> A = ones(10_000) .* π; -Julia supports accessing and modifying values *atomically*, that is, in a thread-safe way to avoid -[race conditions](https://en.wikipedia.org/wiki/Race_condition). A value (which must be of a primitive -type) can be wrapped as [`Threads.Atomic`](@ref) to indicate it must be accessed in this way. -Here we can see an example: +julia> C = 2 .* A ./ B; -```julia-repl -julia> i = Threads.Atomic{Int}(0); +julia> all(C .≈ 4*π) +true -julia> ids = zeros(4); +julia> typeof(C) +Array{Float64,1} -julia> old_is = zeros(4); +julia> dB = distribute(B); -julia> Threads.@threads for id in 1:4 - old_is[id] = Threads.atomic_add!(i, id) - ids[id] = id - end +julia> dA = distribute(A); -julia> old_is -4-element Array{Float64,1}: - 0.0 - 1.0 - 7.0 - 3.0 +julia> dC = 2 .* dA ./ dB; -julia> ids -4-element Array{Float64,1}: - 1.0 - 2.0 - 3.0 - 4.0 -``` +julia> all(dC .≈ 4*π) +true -Had we tried to do the addition without the atomic tag, we might have gotten the -wrong answer due to a race condition. An example of what would happen if we didn't -avoid the race: +julia> typeof(dC) +DistributedArrays.DArray{Float64,1,Array{Float64,1}} -```julia-repl -julia> using Base.Threads +julia> cuB = CuArray(B); -julia> nthreads() -4 +julia> cuA = CuArray(A); -julia> acc = Ref(0) -Base.RefValue{Int64}(0) +julia> cuC = 2 .* cuA ./ cuB; -julia> @threads for i in 1:1000 - acc[] += 1 - end +julia> all(cuC .≈ 4*π); +true -julia> acc[] -926 +julia> typeof(cuC) +CuArray{Float64,1} +``` +Keep in mind that some Julia features are not currently supported by CUDAnative.jl [^2] , especially some functions like `sin` will need to be replaced with `CUDAnative.sin`(cc: @maleadt). -julia> acc = Atomic{Int64}(0) -Atomic{Int64}(0) +In the following example we will use both `DistributedArrays.jl` and `CuArrays.jl` to distribute an array across multiple +processes and call a generic function on it. -julia> @threads for i in 1:1000 - atomic_add!(acc, 1) - end +```julia +function power_method(M, v) + for i in 1:100 + v = M*v + v /= norm(v) + end -julia> acc[] -1000 + return v, norm(M*v) / norm(v) # or (M*v) ./ v +end ``` -!!! note - Not *all* primitive types can be wrapped in an `Atomic` tag. Supported types - are `Int8`, `Int16`, `Int32`, `Int64`, `Int128`, `UInt8`, `UInt16`, `UInt32`, - `UInt64`, `UInt128`, `Float16`, `Float32`, and `Float64`. Additionally, - `Int128` and `UInt128` are not supported on AAarch32 and ppc64le. - -When using multi-threading we have to be careful when using functions that are not -[pure](https://en.wikipedia.org/wiki/Pure_function) as we might get a wrong answer. -For instance functions that have their -[name ending with `!`](https://docs.julialang.org/en/latest/manual/style-guide/#Append-!-to-names-of-functions-that-modify-their-arguments-1) -by convention modify their arguments and thus are not pure. However, there are -functions that have side effects and their name does not end with `!`. For -instance [`findfirst(regex, str)`](@ref) mutates its `regex` argument or -[`rand()`](@ref) changes `Base.GLOBAL_RNG` : +`power_method` repeteavely creates a new vector and normalizes it. We have not specified any type signature in +function declaration, let's see if it works with the aforementioned datatypes: ```julia-repl -julia> using Base.Threads +julia> M = [2. 1; 1 1]; -julia> nthreads() -4 - -julia> function f() - s = repeat(["123", "213", "231"], outer=1000) - x = similar(s, Int) - rx = r"1" - @threads for i in 1:3000 - x[i] = findfirst(rx, s[i]).start - end - count(v -> v == 1, x) - end -f (generic function with 1 method) - -julia> f() # the correct result is 1000 -1017 +julia> v = rand(2) +2-element Array{Float64,1}: +0.40395 +0.445877 -julia> function g() - a = zeros(1000) - @threads for i in 1:1000 - a[i] = rand() - end - length(unique(a)) - end -g (generic function with 1 method) +julia> power_method(M,v) +([0.850651, 0.525731], 2.618033988749895) -julia> srand(1); g() # the result for a single thread is 1000 -781 -``` - -In such cases one should redesign the code to avoid the possibility of a race condition or use -[synchronization primitives](https://docs.julialang.org/en/latest/base/multi-threading/#Synchronization-Primitives-1). - -For example in order to fix `findfirst` example above one needs to have a -separate copy of `rx` variable for each thread: +julia> cuM = CuArray(M); -```julia-repl -julia> function f_fix() - s = repeat(["123", "213", "231"], outer=1000) - x = similar(s, Int) - rx = [Regex("1") for i in 1:nthreads()] - @threads for i in 1:3000 - x[i] = findfirst(rx[threadid()], s[i]).start - end - count(v -> v == 1, x) - end -f_fix (generic function with 1 method) +julia> cuv = CuArray(v); -julia> f_fix() -1000 -``` +julia> curesult = power_method(cuM, cuv); -We now use `Regex("1")` instead of `r"1"` to make sure that Julia -creates separate instances of `Regex` object for each entry of `rx` vector. +julia> typeof(curesult) +CuArray{Float64,1} -The case of `rand` is a bit more complex as we have to ensure that each thread -uses non-overlapping pseudorandom number sequences. This can be simply ensured -by using the `Future.randjump` function: +julia> dM = distribute(M); +julia> dv = distribute(v); -```julia-repl -julia> using Random; import Future +julia> dC = power_method(dM, dv); -julia> function g_fix(r) - a = zeros(1000) - @threads for i in 1:1000 - a[i] = rand(r[threadid()]) - end - length(unique(a)) - end -g_fix (generic function with 1 method) +julia> typeof(dC) +Tuple{DistributedArrays.DArray{Float64,1,Array{Float64,1}},Float64} +``` -julia> r = let m = MersenneTwister(1) - [m; accumulate(Future.randjump, m, fill(big(10)^20, nthreads()-1))] - end; +To end this short exposure to external packages, we can consider `MPI.jl`, a Julia wrapper +of the MPI protocol. As it would take too long to consider every inner function, it would be better +to simply appreciate the approach used to implement the protocol. -julia> g_fix(r) -1000 -``` +Consider this toy script which simply calls each subprocess, instantiate its rank and when the master +process is reached, performs the ranks' sum -We pass `r` vector to `g_fix` as generating several RGNs is an expensive -operation so we do not want to repeat it every time we run the function. +```julia +import MPI -## @threadcall (Experimental) +MPI.Init() -All I/O tasks, timers, REPL commands, etc are multiplexed onto a single OS thread via an event -loop. A patched version of libuv ([http://docs.libuv.org/en/v1.x/](http://docs.libuv.org/en/v1.x/)) -provides this functionality. Yield points provide for co-operatively scheduling multiple tasks -onto the same OS thread. I/O tasks and timers yield implicitly while waiting for the event to -occur. Calling [`yield`](@ref) explicitly allows for other tasks to be scheduled. +comm = MPI.COMM_WORLD +MPI.Barrier(comm) -Thus, a task executing a [`ccall`](@ref) effectively prevents the Julia scheduler from executing any other -tasks till the call returns. This is true for all calls into external libraries. Exceptions are -calls into custom C code that call back into Julia (which may then yield) or C code that calls -`jl_yield()` (C equivalent of [`yield`](@ref)). +root = 0 +r = MPI.Comm_rank(comm) -Note that while Julia code runs on a single thread (by default), libraries used by Julia may launch -their own internal threads. For example, the BLAS library may start as many threads as there are -cores on a machine. +sr = MPI.Reduce(r, MPI.SUM, root, comm) -The [`@threadcall`](@ref) macro addresses scenarios where we do not want a [`ccall`](@ref) to block the main Julia -event loop. It schedules a C function for execution in a separate thread. A threadpool with a -default size of 4 is used for this. The size of the threadpool is controlled via environment variable -`UV_THREADPOOL_SIZE`. While waiting for a free thread, and during function execution once a thread -is available, the requesting task (on the main Julia event loop) yields to other tasks. Note that -`@threadcall` does not return till the execution is complete. From a user point of view, it is -therefore a blocking call like other Julia APIs. +if(MPI.Comm_rank(comm) == root) + @printf("sum of ranks: %s\n", sr) +end -It is very important that the called function does not call back into Julia. +MPI.Finalize() +``` -`@threadcall` may be removed/changed in future versions of Julia. +``` +mpirun -np 4 ./julia example.jl +``` [^1]: - In this context, MPI refers to the MPI-1 standard. Beginning with MPI-2, the MPI standards committee - introduced a new set of communication mechanisms, collectively referred to as Remote Memory Access - (RMA). The motivation for adding RMA to the MPI standard was to facilitate one-sided communication - patterns. For additional information on the latest MPI standard, see [http://mpi-forum.org/docs](http://mpi-forum.org/docs/). + in this context, mpi refers to the mpi-1 standard. beginning with mpi-2, the mpi standards committee + introduced a new set of communication mechanisms, collectively referred to as remote memory access + (rma). the motivation for adding rma to the mpi standard was to facilitate one-sided communication + patterns. for additional information on the latest mpi standard, see [http://mpi-forum.org/docs](http://mpi-forum.org/docs/). + +[^2]: + [Julia GPU man pages](http://juliagpu.github.io/CUDAnative.jl/stable/man/usage.html#Julia-support-1) diff --git a/make.jl b/make.jl index 6c921e0..46ef699 100644 --- a/make.jl +++ b/make.jl @@ -113,6 +113,7 @@ const PAGES = [ "devdocs/cartesian.md", "devdocs/meta.md", "devdocs/subarrays.md", + "devdocs/isbitsunionarrays.md", "devdocs/sysimg.md", "devdocs/llvm.md", "devdocs/stdio.md", diff --git a/src/NEWS.md b/src/NEWS.md index e3c475c..a480868 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -509,9 +509,9 @@ This section lists changes that do not have deprecation warnings. This change makes `@schedule` redundant with `@async`, so `@schedule` has been deprecated ([#27164](https://github.com/JuliaLang/julia/issues/27164)). - * `norm(A::AbstractMatrix, p=2)` computes no longer the operator/matrix norm but the `norm` of `A` - as for other iterables, i.e. as if it were a vector. Especially, `norm(A::AbstractMatrix)` is the - Frobenius norm. To compute the operator/matrix norm, use the new function `opnorm` ([#27401](https://github.com/JuliaLang/julia/issues/27401)). + * `norm(A::AbstractMatrix, p=2)` computes no longer the operator/matrix norm but the `norm` of `A` + as for other iterables, i.e. as if it were a vector. Especially, `norm(A::AbstractMatrix)` is the + Frobenius norm. To compute the operator/matrix norm, use the new function `opnorm` ([#27401](https://github.com/JuliaLang/julia/issues/27401)). * `dot(u, v)` now acts recursively. Instead of `sum(u[i]' * v[i] for i in ...)`, it computes `sum(dot(u[i], v[i]) for i in ...)`, similarly to `vecdot` before ([#27401](https://github.com/JuliaLang/julia/issues/27401)). @@ -521,12 +521,16 @@ This section lists changes that do not have deprecation warnings. cores present on the CPU. Similarly, the environment variable `JULIA_CPU_CORES` is deprecated in favor of `JULIA_CPU_THREADS` ([#27856](https://github.com/JuliaLang/julia/issues/27856)). + * `WeakKeyDict` does not convert keys on insertion anymore (#24941). + Library improvements -------------------- * The function `thisind(s::AbstractString, i::Integer)` returns the largest valid index less or equal than `i` in the string `s` or `0` if no such index exists ([#24414](https://github.com/JuliaLang/julia/issues/24414)). + * Support for Unicode 11 ([#28266](https://github.com/JuliaLang/julia/issues/28266)). + * `Char` is now a subtype of `AbstractChar`, and most of the functions that take character arguments now accept any `AbstractChar` ([#26286](https://github.com/JuliaLang/julia/issues/26286)). diff --git a/src/base/base.md b/src/base/base.md index 00ed2db..36e47cc 100644 --- a/src/base/base.md +++ b/src/base/base.md @@ -220,6 +220,8 @@ Base.@goto Base.@label Base.@simd Base.@polly +Base.@generated +Base.@pure ``` ## Missing Values diff --git a/src/base/collections.md b/src/base/collections.md index bc7c6a4..0e1ece3 100644 --- a/src/base/collections.md +++ b/src/base/collections.md @@ -176,6 +176,8 @@ two functions for custom types to override how they are stored in a hash table. [`WeakKeyDict`](@ref) is a hash table implementation where the keys are weak references to objects, and thus may be garbage collected even when referenced in a hash table. +Like `Dict` it uses `hash` for hashing and `isequal` for equality, unlike `Dict` it does +not convert keys on insertion. [`Dict`](@ref)s can be created by passing pair objects constructed with `=>` to a [`Dict`](@ref) constructor: `Dict("A"=>1, "B"=>2)`. This call will attempt to infer type information from the diff --git a/src/base/numbers.md b/src/base/numbers.md index deea1c2..190584b 100644 --- a/src/base/numbers.md +++ b/src/base/numbers.md @@ -109,6 +109,8 @@ Base.trailing_zeros Base.trailing_ones Base.isodd Base.iseven +Base.@int128_str +Base.@uint128_str ``` ## BigFloats @@ -124,4 +126,5 @@ Base.MPFR.BigFloat(x, prec::Int) BigFloat(x::Union{Integer, AbstractFloat, String}, rounding::RoundingMode) Base.MPFR.BigFloat(x, prec::Int, rounding::RoundingMode) Base.MPFR.BigFloat(x::String) +Base.@big_str ``` diff --git a/src/devdocs/init.md b/src/devdocs/init.md index fcd427e..056186d 100644 --- a/src/devdocs/init.md +++ b/src/devdocs/init.md @@ -10,11 +10,11 @@ Execution starts at [`main()` in `ui/repl.c`](https://github.com/JuliaLang/julia to set the C library locale and to initialize the "ios" library (see [`ios_init_stdstreams()`](https://github.com/JuliaLang/julia/blob/master/src/support/ios.c) and [Legacy `ios.c` library](@ref)). -Next [`parse_opts()`](https://github.com/JuliaLang/julia/blob/master/ui/repl.c) is called to process -command line options. Note that `parse_opts()` only deals with options that affect code generation +Next [`jl_parse_opts()`](https://github.com/JuliaLang/julia/blob/master/src/jloptions.c) is called to process +command line options. Note that `jl_parse_opts()` only deals with options that affect code generation or early initialization. Other options are handled later by [`process_options()` in `base/client.jl`](https://github.com/JuliaLang/julia/blob/master/base/client.jl). -`parse_opts()` stores command line options in the [global `jl_options` struct](https://github.com/JuliaLang/julia/blob/master/src/julia.h). +`jl_parse_opts()` stores command line options in the [global `jl_options` struct](https://github.com/JuliaLang/julia/blob/master/src/julia.h). ## julia_init() diff --git a/src/devdocs/isbitsunionarrays.md b/src/devdocs/isbitsunionarrays.md new file mode 100644 index 0000000..9831998 --- /dev/null +++ b/src/devdocs/isbitsunionarrays.md @@ -0,0 +1,13 @@ +# isbits Union Optimizations + +In Julia, the `Array` type holds both "bits" values as well as heap-allocated "boxed" values. The distinction is whether the value itself is stored inline (in the direct allocated memory of the array), or if the memory of the array is simply a collection of pointers to objects allocated elsewhere. In terms of performance, accessing values inline is clearly an advantage over having to follow a pointer to the actual value. The definition of "isbits" generally means any Julia type with a fixed, determinate size, meaning no "pointer" fields, see `?isbitstype`. + +Julia also supports Union types, quite literally the union of a set of types. Custom Union type definitions can be extremely handy for applications wishing to "cut across" the nominal type system (i.e. explicit subtype relationships) and define methods or functionality on these, otherwise unrelated, set of types. A compiler challenge, however, is in determining how to treat these Union types. The naive approach (and indeed, what Julia itself did pre-0.7), is to simply make a "box" and then a pointer in the box to the actual value, similar to the previously mentioned "boxed" values. This is unfortunate, however, because of the number of small, primitive "bits" types (think `UInt8`, `Int32`, `Float64`, etc.) that would easily fit themselves inline in this "box" without needing any indirection for value access. There are two main ways Julia can take advantage of this optimization as of 0.7: isbits Union fields in types, and isbits Union Arrays. + +## isbits Union Structs + +Julia now includes an optimization wherein "isbits Union" fields in types (`mutable struct`, `struct`, etc.) will be stored inline. This is accomplished by determining the "inline size" of the Union type (e.g. `Union{UInt8, Int16}` will have a size of 16 bytes, which represents the size needed of the largest Union type `Int16`), and in addition, allocating an extra "type tag byte" (`UInt8`), whose value signals the type of the actual value stored inline of the "Union bytes". The type tag byte value is the index of the actual value's type in the Union type's order of types. For example, a type tag value of `0x02` for a field with type `Union{Nothing, UInt8, Int16}` would indicate that an `Int16` value is stored in the 16 bytes of the field in the structure's memory; a `0x01` value would indicate that a `UInt8` value was stored in the first 8 bytes of the 16 bytes of the field's memory. Lastly, a value of `0x00` signals that the `nothing` value will be returned for this field, even though, as a singleton type with a single type instance, it technically has a size of 0. The type tag byte for a type's Union field is stored directly after the field's computed Union memory. + +## isbits Union Arrays + +Julia can now also store "isbits Union" values inline in an Array, as opposed to requiring an indirection box. The optimization is accomplished by storing an extra "type tag array" of bytes, one byte per array element, alongside the bytes of the actual array data. This type tag array serves the same function as the type field case: it's value signals the type of the actual stored Union value in the array. In terms of layout, a Julia Array can include extra "buffer" space before and after it's actual data values, which are tracked in the `a->offset` and `a->maxsize` fields of the `jl_array_t*` type. The "type tag array" is treated exactly as another `jl_array_t*`, but which shares the same `a->offset`, `a->maxsize`, and `a->len` fields. So the formula to access an isbits Union Array's type tag bytes is `a->data + (a->maxsize - a->offset) * a->elsize + a->offset`; i.e. the Array's `a->data` pointer is already shifted by `a->offset`, so correcting for that, we follow the data all the way to the max of what it can hold `a->maxsize`, then adjust by `a->ofset` more bytes to account for any present "front buffering" the array might be doing. This layout in particular allows for very efficient resizing operations as the type tag data only ever has to move when the actual array's data has to move. \ No newline at end of file diff --git a/src/manual/parallel-computing.md b/src/manual/parallel-computing.md index 481c296..a803696 100644 --- a/src/manual/parallel-computing.md +++ b/src/manual/parallel-computing.md @@ -1,12 +1,510 @@ # Parallel Computing -This part of the manual details the following types of parallel programming available in Julia. +For newcomers to multi-threading and parallel computing it can be useful to first appreciate +the different levels of parallelism offered by Julia. We can divide them in three main categories : + +1. Julia Coroutines (Green Threading) +2. Multi-Threading +3. Multi-Core or Distributed Processing + +We will first consider Julia [Tasks (aka Coroutines)](@ref man-tasks) and other modules that rely on the Julia runtime library, that allow to suspend and resume computations with full control of inter-`Tasks` communication without having to manually interface with the operative system's scheduler. +Julia also allows to communicate between `Tasks` through operations like [`wait`](@ref) and [`fetch`](@ref). +Communication and data synchronization is managed through [`Channel`](@ref)s, which are the conduit +that allows inter-`Tasks` communication. + +Julia also supports experimental multi-threading, where execution is forked and an anonymous function is run across all +threads. +Described as a fork-join approach, parallel threads are branched off and they all have to join the Julia main thread to make serial execution continue. +Multi-threading is supported using the `Base.Threads` module that is still considered experimental, as Julia is +not fully thread-safe yet. In particular segfaults seem to emerge for I\O operations and task switching. +As an un up-to-date reference, keep an eye on [the issue tracker](https://github.com/JuliaLang/julia/issues?q=is%3Aopen+is%3Aissue+label%3Amultithreading). +Multi-Threading should only be used if you take into consideration global variables, locks and +atomics, so we will explain it later. + +In the end we will present Julia's way to distributed and parallel computing. With scientific computing +in mind, Julia natively implements interfaces to distribute a process through multiple cores or machines. +Also we will mention useful external packages for distributed programming like `MPI.jl` and `DistributedArrays.jl`. + +# Coroutines + +Julia's parallel programming platform uses [Tasks (aka Coroutines)](@ref man-tasks) to switch among multiple computations. +To express an order of execution between lightweight threads communication primitives are necessary. +Julia offers `Channel(func::Function, ctype=Any, csize=0, taskref=nothing)` that creates a new task from `func`, +binds it to a new channel of type `ctype` and size `csize` and schedule the task. +`Channels` can serve as a way to communicate between tasks, as `Channel{T}(sz::Int)` creates a buffered channel of type `T` and size `sz`. +Whenever code performs a communication operation like [`fetch`](@ref) or [`wait`](@ref), +the current task is suspended and a scheduler picks another task to run. +A task is restarted when the event it is waiting for completes. -1. Distributed memory using multiple processes on one or more nodes -2. Shared memory using multiple processes on a single node -3. Multi-threading +For many problems, it is not necessary to think about tasks directly. However, they can be used +to wait for multiple events at the same time, which provides for *dynamic scheduling*. In dynamic +scheduling, a program decides what to compute or where to compute it based on when other jobs +finish. This is needed for unpredictable or unbalanced workloads, where we want to assign more +work to processes only when they finish their current tasks. + +## Channels + +The section on [`Task`](@ref)s in [Control Flow](@ref) discussed the execution of multiple functions in +a co-operative manner. [`Channel`](@ref)s can be quite useful to pass data between running tasks, particularly +those involving I/O operations. + +Examples of operations involving I/O include reading/writing to files, accessing web services, +executing external programs, etc. In all these cases, overall execution time can be improved if +other tasks can be run while a file is being read, or while waiting for an external service/program +to complete. + +A channel can be visualized as a pipe, i.e., it has a write end and a read end : + + * Multiple writers in different tasks can write to the same channel concurrently via [`put!`](@ref) + calls. + * Multiple readers in different tasks can read data concurrently via [`take!`](@ref) calls. + * As an example: + + ```julia + # Given Channels c1 and c2, + c1 = Channel(32) + c2 = Channel(32) + + # and a function `foo` which reads items from from c1, processes the item read + # and writes a result to c2, + function foo() + while true + data = take!(c1) + [...] # process data + put!(c2, result) # write out result + end + end + + # we can schedule `n` instances of `foo` to be active concurrently. + for _ in 1:n + @schedule foo() + end + ``` +* Channels are created via the `Channel{T}(sz)` constructor. The channel will only hold objects + of type `T`. If the type is not specified, the channel can hold objects of any type. `sz` refers + to the maximum number of elements that can be held in the channel at any time. For example, `Channel(32)` + creates a channel that can hold a maximum of 32 objects of any type. A `Channel{MyType}(64)` can + hold up to 64 objects of `MyType` at any time. +* If a [`Channel`](@ref) is empty, readers (on a [`take!`](@ref) call) will block until data is available. +* If a [`Channel`](@ref) is full, writers (on a [`put!`](@ref) call) will block until space becomes available. +* [`isready`](@ref) tests for the presence of any object in the channel, while [`wait`](@ref) + waits for an object to become available. +* A [`Channel`](@ref) is in an open state initially. This means that it can be read from and written to + freely via [`take!`](@ref) and [`put!`](@ref) calls. [`close`](@ref) closes a [`Channel`](@ref). + On a closed [`Channel`](@ref), [`put!`](@ref) will fail. For example: + +```julia-repl +julia> c = Channel(2); + +julia> put!(c, 1) # `put!` on an open channel succeeds +1 + +julia> close(c); + +julia> put!(c, 2) # `put!` on a closed channel throws an exception. +ERROR: InvalidStateException("Channel is closed.",:closed) +Stacktrace: +[...] +``` + + * [`take!`](@ref) and [`fetch`](@ref) (which retrieves but does not remove the value) on a closed + channel successfully return any existing values until it is emptied. Continuing the above example: + +```julia-repl +julia> fetch(c) # Any number of `fetch` calls succeed. +1 + +julia> fetch(c) +1 + +julia> take!(c) # The first `take!` removes the value. +1 + +julia> take!(c) # No more data available on a closed channel. +ERROR: InvalidStateException("Channel is closed.",:closed) +Stacktrace: +[...] +``` + +A `Channel` can be used as an iterable object in a `for` loop, in which case the loop runs as +long as the `Channel` has data or is open. The loop variable takes on all values added to the +`Channel`. The `for` loop is terminated once the `Channel` is closed and emptied. + +For example, the following would cause the `for` loop to wait for more data: + +```julia-repl +julia> c = Channel{Int}(10); + +julia> foreach(i->put!(c, i), 1:3) # add a few entries + +julia> data = [i for i in c] +``` + +while this will return after reading all data: + +```julia-repl +julia> c = Channel{Int}(10); + +julia> foreach(i->put!(c, i), 1:3); # add a few entries + +julia> close(c); # `for` loops can exit + +julia> data = [i for i in c] +3-element Array{Int64,1}: + 1 + 2 + 3 +``` + +Consider a simple example using channels for inter-task communication. We start 4 tasks to process +data from a single `jobs` channel. Jobs, identified by an id (`job_id`), are written to the channel. +Each task in this simulation reads a `job_id`, waits for a random amout of time and writes back +a tuple of `job_id` and the simulated time to the results channel. Finally all the `results` are +printed out. + +```julia-repl +julia> const jobs = Channel{Int}(32); + +julia> const results = Channel{Tuple}(32); + +julia> function do_work() + for job_id in jobs + exec_time = rand() + sleep(exec_time) # simulates elapsed time doing actual work + # typically performed externally. + put!(results, (job_id, exec_time)) + end + end; + +julia> function make_jobs(n) + for i in 1:n + put!(jobs, i) + end + end; + +julia> n = 12; + +julia> @schedule make_jobs(n); # feed the jobs channel with "n" jobs + +julia> for i in 1:4 # start 4 tasks to process requests in parallel + @schedule do_work() + end + +julia> @elapsed while n > 0 # print out results + job_id, exec_time = take!(results) + println("$job_id finished in $(round(exec_time,2)) seconds") + n = n - 1 + end +4 finished in 0.22 seconds +3 finished in 0.45 seconds +1 finished in 0.5 seconds +7 finished in 0.14 seconds +2 finished in 0.78 seconds +5 finished in 0.9 seconds +9 finished in 0.36 seconds +6 finished in 0.87 seconds +8 finished in 0.79 seconds +10 finished in 0.64 seconds +12 finished in 0.5 seconds +11 finished in 0.97 seconds +0.029772311 +``` + +The current version of Julia multiplexes all tasks onto a single OS thread. Thus, while tasks +involving I/O operations benefit from parallel execution, compute bound tasks are effectively +executed sequentially on a single OS thread. Future versions of Julia may support scheduling of +tasks on multiple threads, in which case compute bound tasks will see benefits of parallel execution +too. + +# Multi-Threading (Experimental) + +In addition to tasks Julia forwards natively supports multi-threading. +Note that this section is experimental and the interfaces may change in the future. + +## Setup + +By default, Julia starts up with a single thread of execution. This can be verified by using the +command [`Threads.nthreads()`](@ref): + +```julia-repl +julia> Threads.nthreads() +1 +``` + +The number of threads Julia starts up with is controlled by an environment variable called `JULIA_NUM_THREADS`. +Now, let's start up Julia with 4 threads: + +```bash +export JULIA_NUM_THREADS=4 +``` + +(The above command works on bourne shells on Linux and OSX. Note that if you're using a C shell +on these platforms, you should use the keyword `set` instead of `export`. If you're on Windows, +start up the command line in the location of `julia.exe` and use `set` instead of `export`.) + +Let's verify there are 4 threads at our disposal. + +```julia-repl +julia> Threads.nthreads() +4 +``` + +But we are currently on the master thread. To check, we use the function [`Threads.threadid`](@ref) + +```julia-repl +julia> Threads.threadid() +1 +``` + +## The `@threads` Macro + +Let's work a simple example using our native threads. Let us create an array of zeros: + +```jldoctest +julia> a = zeros(10) +10-element Array{Float64,1}: + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 +``` + +Let us operate on this array simultaneously using 4 threads. We'll have each thread write its +thread ID into each location. + +Julia supports parallel loops using the [`Threads.@threads`](@ref) macro. This macro is affixed +in front of a `for` loop to indicate to Julia that the loop is a multi-threaded region: + +```julia-repl +julia> Threads.@threads for i = 1:10 + a[i] = Threads.threadid() + end +``` + +The iteration space is split amongst the threads, after which each thread writes its thread ID +to its assigned locations: + +```julia-repl +julia> a +10-element Array{Float64,1}: + 1.0 + 1.0 + 1.0 + 2.0 + 2.0 + 2.0 + 3.0 + 3.0 + 4.0 + 4.0 +``` + +Note that [`Threads.@threads`](@ref) does not have an optional reduction parameter like [`@distributed`](@ref). + +## Atomic Operations + +Julia supports accessing and modifying values *atomically*, that is, in a thread-safe way to avoid +[race conditions](https://en.wikipedia.org/wiki/Race_condition). A value (which must be of a primitive +type) can be wrapped as [`Threads.Atomic`](@ref) to indicate it must be accessed in this way. +Here we can see an example: + +```julia-repl +julia> i = Threads.Atomic{Int}(0); + +julia> ids = zeros(4); + +julia> old_is = zeros(4); + +julia> Threads.@threads for id in 1:4 + old_is[id] = Threads.atomic_add!(i, id) + ids[id] = id + end + +julia> old_is +4-element Array{Float64,1}: + 0.0 + 1.0 + 7.0 + 3.0 + +julia> ids +4-element Array{Float64,1}: + 1.0 + 2.0 + 3.0 + 4.0 +``` + +Had we tried to do the addition without the atomic tag, we might have gotten the +wrong answer due to a race condition. An example of what would happen if we didn't +avoid the race: + +```julia-repl +julia> using Base.Threads + +julia> nthreads() +4 + +julia> acc = Ref(0) +Base.RefValue{Int64}(0) + +julia> @threads for i in 1:1000 + acc[] += 1 + end + +julia> acc[] +926 + +julia> acc = Atomic{Int64}(0) +Atomic{Int64}(0) + +julia> @threads for i in 1:1000 + atomic_add!(acc, 1) + end + +julia> acc[] +1000 +``` + +!!! note + Not *all* primitive types can be wrapped in an `Atomic` tag. Supported types + are `Int8`, `Int16`, `Int32`, `Int64`, `Int128`, `UInt8`, `UInt16`, `UInt32`, + `UInt64`, `UInt128`, `Float16`, `Float32`, and `Float64`. Additionally, + `Int128` and `UInt128` are not supported on AAarch32 and ppc64le. + +## Side effects and mutable function arguments + +When using multi-threading we have to be careful when using functions that are not +[pure](https://en.wikipedia.org/wiki/Pure_function) as we might get a wrong answer. +For instance functions that have their +[name ending with `!`](https://docs.julialang.org/en/latest/manual/style-guide/#Append-!-to-names-of-functions-that-modify-their-arguments-1) +by convention modify their arguments and thus are not pure. However, there are +functions that have side effects and their name does not end with `!`. For +instance [`findfirst(regex, str)`](@ref) mutates its `regex` argument or +[`rand()`](@ref) changes `Base.GLOBAL_RNG` : + +```julia-repl +julia> using Base.Threads + +julia> nthreads() +4 + +julia> function f() + s = repeat(["123", "213", "231"], outer=1000) + x = similar(s, Int) + rx = r"1" + @threads for i in 1:3000 + x[i] = findfirst(rx, s[i]).start + end + count(v -> v == 1, x) + end +f (generic function with 1 method) + +julia> f() # the correct result is 1000 +1017 + +julia> function g() + a = zeros(1000) + @threads for i in 1:1000 + a[i] = rand() + end + length(unique(a)) + end +g (generic function with 1 method) + +julia> srand(1); g() # the result for a single thread is 1000 +781 +``` + +In such cases one should redesign the code to avoid the possibility of a race condition or use +[synchronization primitives](https://docs.julialang.org/en/latest/base/multi-threading/#Synchronization-Primitives-1). + +For example in order to fix `findfirst` example above one needs to have a +separate copy of `rx` variable for each thread: + +```julia-repl +julia> function f_fix() + s = repeat(["123", "213", "231"], outer=1000) + x = similar(s, Int) + rx = [Regex("1") for i in 1:nthreads()] + @threads for i in 1:3000 + x[i] = findfirst(rx[threadid()], s[i]).start + end + count(v -> v == 1, x) + end +f_fix (generic function with 1 method) + +julia> f_fix() +1000 +``` + +We now use `Regex("1")` instead of `r"1"` to make sure that Julia +creates separate instances of `Regex` object for each entry of `rx` vector. + +The case of `rand` is a bit more complex as we have to ensure that each thread +uses non-overlapping pseudorandom number sequences. This can be simply ensured +by using `Future.randjump` function: + + +```julia-repl +julia> using Random; import Future -# Distributed Memory Parallelism +julia> function g_fix(r) + a = zeros(1000) + @threads for i in 1:1000 + a[i] = rand(r[threadid()]) + end + length(unique(a)) + end +g_fix (generic function with 1 method) + +julia> r = let m = MersenneTwister(1) + [m; accumulate(Future.randjump, m, fill(big(10)^20, nthreads()-1))] + end; + +julia> g_fix(r) +1000 +``` + +We pass the `r` vector to `g_fix` as generating several RGNs is an expensive +operation so we do not want to repeat it every time we run the function. + +## @threadcall (Experimental) + +All I/O tasks, timers, REPL commands, etc are multiplexed onto a single OS thread via an event +loop. A patched version of libuv ([http://docs.libuv.org/en/v1.x/](http://docs.libuv.org/en/v1.x/)) +provides this functionality. Yield points provide for co-operatively scheduling multiple tasks +onto the same OS thread. I/O tasks and timers yield implicitly while waiting for the event to +occur. Calling [`yield`](@ref) explicitly allows for other tasks to be scheduled. + +Thus, a task executing a [`ccall`](@ref) effectively prevents the Julia scheduler from executing any other +tasks till the call returns. This is true for all calls into external libraries. Exceptions are +calls into custom C code that call back into Julia (which may then yield) or C code that calls +`jl_yield()` (C equivalent of [`yield`](@ref)). + +Note that while Julia code runs on a single thread (by default), libraries used by Julia may launch +their own internal threads. For example, the BLAS library may start as many threads as there are +cores on a machine. + +The [`@threadcall`](@ref) macro addresses scenarios where we do not want a [`ccall`](@ref) to block the main Julia +event loop. It schedules a C function for execution in a separate thread. A threadpool with a +default size of 4 is used for this. The size of the threadpool is controlled via environment variable +`UV_THREADPOOL_SIZE`. While waiting for a free thread, and during function execution once a thread +is available, the requesting task (on the main Julia event loop) yields to other tasks. Note that +`@threadcall` does not return till the execution is complete. From a user point of view, it is +therefore a blocking call like other Julia APIs. + +It is very important that the called function does not call back into Julia, as it will segfault. + +`@threadcall` may be removed/changed in future versions of Julia. + +# Multi-Core or Distributed Processing An implementation of distributed memory parallel computing is provided by module `Distributed` as part of the standard library shipped with Julia. @@ -121,6 +619,24 @@ An important thing to remember is that, once fetched, a [`Future`](@ref) will ca locally. Further [`fetch`](@ref) calls do not entail a network hop. Once all referencing [`Future`](@ref)s have fetched, the remote stored value is deleted. +[`@async`](@ref) is similar to [`@spawn`](@ref), but only runs tasks on the local process. We +use it to create a "feeder" task for each process. Each task picks the next index that needs to +be computed, then waits for its process to finish, then repeats until we run out of indices. Note +that the feeder tasks do not begin to execute until the main task reaches the end of the [`@sync`](@ref) +block, at which point it surrenders control and waits for all the local tasks to complete before +returning from the function. +As for v0.7 and beyond, the feeder tasks are able to share state via `nextidx` because +they all run on the same process. +Even if `Tasks` are scheduled cooperatively, locking may still be required in some contexts, as in [asynchronous I\O](https://docs.julialang.org/en/stable/manual/faq/#Asynchronous-IO-and-concurrent-synchronous-writes-1). +This means context switches only occur at well-defined points: in this case, +when [`remotecall_fetch`](@ref) is called. This is the current state of implementation (dev v0.7) and it may change +for future Julia versions, as it is intended to make it possible to run up to N `Tasks` on M `Process`, aka +[M:N Threading](https://en.wikipedia.org/wiki/Thread_(computing)#Models). Then a lock acquiring\releasing +model for `nextidx` will be needed, as it is not safe to let multiple processes read-write a resource at +the same time. + + + ## Code Availability and Loading Packages Your code must be available on any process that runs it. For example, type the following into @@ -295,7 +811,7 @@ and `fetch(Bref)`, it might be better to eliminate the parallelism altogether. O is replaced with a more expensive operation. Then it might make sense to add another [`@spawn`](@ref) statement just for this step. -# Global variables +## Global variables Expressions executed remotely via `@spawn`, or closures specified for remote execution using `remotecall` may refer to global variables. Global bindings under module `Main` are treated a little differently compared to global bindings in other modules. Consider the following code @@ -462,266 +978,28 @@ end Here each iteration applies `f` to a randomly-chosen sample from a vector `a` shared by all processes. -As you could see, the reduction operator can be omitted if it is not needed. In that case, the -loop executes asynchronously, i.e. it spawns independent tasks on all available workers and returns -an array of [`Future`](@ref) immediately without waiting for completion. The caller can wait for -the [`Future`](@ref) completions at a later point by calling [`fetch`](@ref) on them, or wait -for completion at the end of the loop by prefixing it with [`@sync`](@ref), like `@sync @distributed for`. - -In some cases no reduction operator is needed, and we merely wish to apply a function to all integers -in some range (or, more generally, to all elements in some collection). This is another useful -operation called *parallel map*, implemented in Julia as the [`pmap`](@ref) function. For example, -we could compute the singular values of several large random matrices in parallel as follows: - -```julia-repl -julia> M = Matrix{Float64}[rand(1000,1000) for i = 1:10]; - -julia> pmap(svdvals, M); -``` - -Julia's [`pmap`](@ref) is designed for the case where each function call does a large amount -of work. In contrast, `@distributed for` can handle situations where each iteration is tiny, perhaps -merely summing two numbers. Only worker processes are used by both [`pmap`](@ref) and `@distributed for` -for the parallel computation. In case of `@distributed for`, the final reduction is done on the calling -process. - -## Synchronization With Remote References - -## Scheduling - -Julia's parallel programming platform uses [Tasks (aka Coroutines)](@ref man-tasks) to switch among multiple -computations. Whenever code performs a communication operation like [`fetch`](@ref) or [`wait`](@ref), -the current task is suspended and a scheduler picks another task to run. A task is restarted when -the event it is waiting for completes. - -For many problems, it is not necessary to think about tasks directly. However, they can be used -to wait for multiple events at the same time, which provides for *dynamic scheduling*. In dynamic -scheduling, a program decides what to compute or where to compute it based on when other jobs -finish. This is needed for unpredictable or unbalanced workloads, where we want to assign more -work to processes only when they finish their current tasks. - -As an example, consider computing the singular values of matrices of different sizes: - -```julia-repl -julia> M = Matrix{Float64}[rand(800,800), rand(600,600), rand(800,800), rand(600,600)]; - -julia> pmap(svdvals, M); -``` - -If one process handles both 800×800 matrices and another handles both 600×600 matrices, we will -not get as much scalability as we could. The solution is to make a local task to "feed" work to -each process when it completes its current task. For example, consider a simple [`pmap`](@ref) -implementation: - -```julia -function pmap(f, lst) - np = nprocs() # determine the number of processes available - n = length(lst) - results = Vector{Any}(n) - i = 1 - # function to produce the next work item from the queue. - # in this case it's just an index. - nextidx() = (global i; idx=i; i+=1; idx) - @sync begin - for p=1:np - if p != myid() || np == 1 - @async begin - while true - idx = nextidx() - idx > n && break - results[idx] = remotecall_fetch(f, p, lst[idx]) - end - end - end - end - end - results -end -``` - -[`@async`](@ref) is similar to [`@spawn`](@ref), but only runs tasks on the local process. We -use it to create a "feeder" task for each process. Each task picks the next index that needs to -be computed, then waits for its process to finish, then repeats until we run out of indices. Note -that the feeder tasks do not begin to execute until the main task reaches the end of the [`@sync`](@ref) -block, at which point it surrenders control and waits for all the local tasks to complete before -returning from the function. The feeder tasks are able to share state via `nextidx` because -they all run on the same process. No locking is required, since the threads are scheduled cooperatively -and not preemptively. This means context switches only occur at well-defined points: in this case, -when [`remotecall_fetch`](@ref) is called. - -## Channels - -The section on [`Task`](@ref)s in [Control Flow](@ref) discussed the execution of multiple functions in -a co-operative manner. [`Channel`](@ref)s can be quite useful to pass data between running tasks, particularly -those involving I/O operations. - -Examples of operations involving I/O include reading/writing to files, accessing web services, -executing external programs, etc. In all these cases, overall execution time can be improved if -other tasks can be run while a file is being read, or while waiting for an external service/program -to complete. - -A channel can be visualized as a pipe, i.e., it has a write end and read end. - - * Multiple writers in different tasks can write to the same channel concurrently via [`put!`](@ref) - calls. - * Multiple readers in different tasks can read data concurrently via [`take!`](@ref) calls. - * As an example: - - ```julia - # Given Channels c1 and c2, - c1 = Channel(32) - c2 = Channel(32) - - # and a function `foo` which reads items from from c1, processes the item read - # and writes a result to c2, - function foo() - while true - data = take!(c1) - [...] # process data - put!(c2, result) # write out result - end - end - - # we can schedule `n` instances of `foo` to be active concurrently. - for _ in 1:n - @async foo() - end - ``` - * Channels are created via the `Channel{T}(sz)` constructor. The channel will only hold objects - of type `T`. If the type is not specified, the channel can hold objects of any type. `sz` refers - to the maximum number of elements that can be held in the channel at any time. For example, `Channel(32)` - creates a channel that can hold a maximum of 32 objects of any type. A `Channel{MyType}(64)` can - hold up to 64 objects of `MyType` at any time. - * If a [`Channel`](@ref) is empty, readers (on a [`take!`](@ref) call) will block until data is available. - * If a [`Channel`](@ref) is full, writers (on a [`put!`](@ref) call) will block until space becomes available. - * [`isready`](@ref) tests for the presence of any object in the channel, while [`wait`](@ref) - waits for an object to become available. - * A [`Channel`](@ref) is in an open state initially. This means that it can be read from and written to - freely via [`take!`](@ref) and [`put!`](@ref) calls. [`close`](@ref) closes a [`Channel`](@ref). - On a closed [`Channel`](@ref), [`put!`](@ref) will fail. For example: - -```julia-repl -julia> c = Channel(2); - -julia> put!(c, 1) # `put!` on an open channel succeeds -1 - -julia> close(c); - -julia> put!(c, 2) # `put!` on a closed channel throws an exception. -ERROR: InvalidStateException("Channel is closed.",:closed) -Stacktrace: -[...] -``` - - * [`take!`](@ref) and [`fetch`](@ref) (which retrieves but does not remove the value) on a closed - channel successfully return any existing values until it is emptied. Continuing the above example: - -```julia-repl -julia> fetch(c) # Any number of `fetch` calls succeed. -1 - -julia> fetch(c) -1 - -julia> take!(c) # The first `take!` removes the value. -1 - -julia> take!(c) # No more data available on a closed channel. -ERROR: InvalidStateException("Channel is closed.",:closed) -Stacktrace: -[...] -``` - -A `Channel` can be used as an iterable object in a `for` loop, in which case the loop runs as -long as the `Channel` has data or is open. The loop variable takes on all values added to the -`Channel`. The `for` loop is terminated once the `Channel` is closed and emptied. - -For example, the following would cause the `for` loop to wait for more data: - -```julia-repl -julia> c = Channel{Int}(10); - -julia> foreach(i->put!(c, i), 1:3) # add a few entries - -julia> data = [i for i in c] -``` - -while this will return after reading all data: - -```julia-repl -julia> c = Channel{Int}(10); - -julia> foreach(i->put!(c, i), 1:3); # add a few entries - -julia> close(c); # `for` loops can exit - -julia> data = [i for i in c] -3-element Array{Int64,1}: - 1 - 2 - 3 -``` - -Consider a simple example using channels for inter-task communication. We start 4 tasks to process -data from a single `jobs` channel. Jobs, identified by an id (`job_id`), are written to the channel. -Each task in this simulation reads a `job_id`, waits for a random amount of time and writes back -a tuple of `job_id` and the simulated time to the results channel. Finally all the `results` are -printed out. - -```julia-repl -julia> const jobs = Channel{Int}(32); - -julia> const results = Channel{Tuple}(32); - -julia> function do_work() - for job_id in jobs - exec_time = rand() - sleep(exec_time) # simulates elapsed time doing actual work - # typically performed externally. - put!(results, (job_id, exec_time)) - end - end; - -julia> function make_jobs(n) - for i in 1:n - put!(jobs, i) - end - end; - -julia> n = 12; - -julia> @async make_jobs(n); # feed the jobs channel with "n" jobs - -julia> for i in 1:4 # start 4 tasks to process requests in parallel - @async do_work() - end - -julia> @elapsed while n > 0 # print out results - job_id, exec_time = take!(results) - println("$job_id finished in $(round(exec_time,2)) seconds") - n = n - 1 - end -4 finished in 0.22 seconds -3 finished in 0.45 seconds -1 finished in 0.5 seconds -7 finished in 0.14 seconds -2 finished in 0.78 seconds -5 finished in 0.9 seconds -9 finished in 0.36 seconds -6 finished in 0.87 seconds -8 finished in 0.79 seconds -10 finished in 0.64 seconds -12 finished in 0.5 seconds -11 finished in 0.97 seconds -0.029772311 +As you could see, the reduction operator can be omitted if it is not needed. In that case, the +loop executes asynchronously, i.e. it spawns independent tasks on all available workers and returns +an array of [`Future`](@ref) immediately without waiting for completion. The caller can wait for +the [`Future`](@ref) completions at a later point by calling [`fetch`](@ref) on them, or wait +for completion at the end of the loop by prefixing it with [`@sync`](@ref), like `@sync @distributed for`. + +In some cases no reduction operator is needed, and we merely wish to apply a function to all integers +in some range (or, more generally, to all elements in some collection). This is another useful +operation called *parallel map*, implemented in Julia as the [`pmap`](@ref) function. For example, +we could compute the singular values of several large random matrices in parallel as follows: + +```julia-repl +julia> M = Matrix{Float64}[rand(1000,1000) for i = 1:10]; + +julia> pmap(svdvals, M); ``` -The current version of Julia multiplexes all tasks onto a single OS thread. Thus, while tasks -involving I/O operations benefit from parallel execution, compute bound tasks are effectively -executed sequentially on a single OS thread. Future versions of Julia may support scheduling of -tasks on multiple threads, in which case compute bound tasks will see benefits of parallel execution -too. +Julia's [`pmap`](@ref) is designed for the case where each function call does a large amount +of work. In contrast, `@distributed for` can handle situations where each iteration is tiny, perhaps +merely summing two numbers. Only worker processes are used by both [`pmap`](@ref) and `@distributed for` +for the parallel computation. In case of `@distributed for`, the final reduction is done on the calling +process. ## Remote References and AbstractChannels @@ -750,20 +1028,21 @@ A simple example of this is provided in `dictchannel.jl` in the [Examples repository](https://github.com/JuliaArchive/Examples), which uses a dictionary as its remote store. + ## Channels and RemoteChannels - * A [`Channel`](@ref) is local to a process. Worker 2 cannot directly refer to a `Channel` on worker 3 and + * A [`Channel`](@ref) is local to a process. Worker 2 cannot directly refer to a [`Channel`](@ref) on worker 3 and vice-versa. A [`RemoteChannel`](@ref), however, can put and take values across workers. - * A [`RemoteChannel`](@ref) can be thought of as a *handle* to a `Channel`. + * A [`RemoteChannel`](@ref) can be thought of as a *handle* to a [`Channel`](@ref). * The process id, `pid`, associated with a [`RemoteChannel`](@ref) identifies the process where - the backing store, i.e., the backing `Channel` exists. + the backing store, i.e., the backing [`Channel`](@ref) exists. * Any process with a reference to a [`RemoteChannel`](@ref) can put and take items from the channel. Data is automatically sent to (or retrieved from) the process a [`RemoteChannel`](@ref) is associated with. - * Serializing a `Channel` also serializes any data present in the channel. Deserializing it therefore + * Serializing a [`Channel`](@ref) also serializes any data present in the channel. Deserializing it therefore effectively makes a copy of the original object. * On the other hand, serializing a [`RemoteChannel`](@ref) only involves the serialization of an - identifier that identifies the location and instance of `Channel` referred to by the handle. A + identifier that identifies the location and instance of [`Channel`](@ref) referred to by the handle. A deserialized [`RemoteChannel`](@ref) object (on any worker), therefore also points to the same backing store as the original. @@ -825,7 +1104,7 @@ julia> @elapsed while n > 0 # print out results 0.055971741 ``` -## Remote References and Distributed Garbage Collection +### Remote References and Distributed Garbage Collection Objects referred to by remote references can be freed only when *all* held references in the cluster are deleted. @@ -1063,7 +1342,7 @@ julia> @time advection_shared!(q,u); The biggest advantage of `advection_shared!` is that it minimizes traffic among the workers, allowing each to compute for an extended time on the assigned piece. -## Shared Arrays and Distributed Garbage Collection +### Shared Arrays and Distributed Garbage Collection Like remote references, shared arrays are also dependent on garbage collection on the creating node to release references from all participating workers. Code which creates many short lived @@ -1234,7 +1513,7 @@ times during the worker's lifetime with appropriate `op` values: appropriate worker with an interrupt signal. * with `:finalize` for cleanup purposes. -## Cluster Managers with Custom Transports +### Cluster Managers with Custom Transports Replacing the default TCP/IP all-to-all socket connections with a custom transport layer is a little more involved. Each Julia process has as many communication tasks as the workers it is @@ -1292,7 +1571,7 @@ The default implementation simply executes an `exit()` call on the specified rem The Examples folder `clustermanager/simple` is an example that shows a simple implementation using UNIX domain sockets for cluster setup. -## Network Requirements for LocalManager and SSHManager +### Network Requirements for LocalManager and SSHManager Julia clusters are designed to be executed on already secured environments on infrastructure such as local laptops, departmental clusters, or even the cloud. This section covers network security @@ -1325,7 +1604,7 @@ requirements for the inbuilt `LocalManager` and `SSHManager`: Securing and encrypting all worker-worker traffic (via SSH) or encrypting individual messages can be done via a custom `ClusterManager`. -## [Cluster Cookie](@id man-cluster-cookie) +### [Cluster Cookie](@id man-cluster-cookie) All processes in a cluster share the same cookie which, by default, is a randomly generated string on the master process: @@ -1365,293 +1644,158 @@ Currently, sending a message between unconnected workers results in an error. Th as with the functionality and interface, should be considered experimental in nature and may change in future releases. -## Multi-Threading (Experimental) +## Noteworthy external packages -In addition to tasks, remote calls, and remote references, Julia from `v0.5` forwards natively -supports multi-threading. Note that this section is experimental and the interfaces may change -in the future. +Outside of Julia parallelism there are plenty of external packages that should be mentioned. +For example [MPI.jl](https://github.com/JuliaParallel/MPI.jl) is a Julia wrapper for the `MPI` protocol, or +[DistributedArrays.jl](https://github.com/JuliaParallel/Distributedarrays.jl), as presented in [Shared Arrays](@ref). +A mention must be done to the Julia's GPU programming ecosystem, which includes : -### Setup - -By default, Julia starts up with a single thread of execution. This can be verified by using the -command [`Threads.nthreads()`](@ref): +1. Low-level (C kernel) based operations [OpenCL.jl](https://github.com/JuliaGPU/OpenCL.jl) and [CUDAdrv.jl](https://github.com/JuliaGPU/CUDAdrv.jl) which are respectively an OpenCL interface and a CUDA wrapper. -```julia-repl -julia> Threads.nthreads() -1 -``` +2. Low-level (Julia Kernel) interfaces like [CUDAnative.jl](https://github.com/JuliaGPU/CUDAnative.jl) which is a Julia native CUDA implementation. -The number of threads Julia starts up with is controlled by an environment variable called `JULIA_NUM_THREADS`. -Now, let's start up Julia with 4 threads: +3. High-level vendor specific abstractions like [CuArrays.jl](https://github.com/JuliaGPU/CuArrays.jl) and [CLArrays.jl](https://github.com/JuliaGPU/CLArrays.jl) -```bash -export JULIA_NUM_THREADS=4 -``` +4. High-level libraries like [ArrayFire.jl](https://github.com/JuliaComputing/ArrayFire.jl) and [GPUArrays.jl](https://github.com/JuliaGPU/GPUArrays.jl) -(The above command works on bourne shells on Linux and OSX. Note that if you're using a C shell -on these platforms, you should use the keyword `set` instead of `export`. If you're on Windows, -start up the command line in the location of `julia.exe` and use `set` instead of `export`.) -Let's verify there are 4 threads at our disposal. +In the following example we will use both `DistributedArrays.jl` and `CuArrays.jl` to distribute an array across multiple +processes by first casting it through `distribute()` and `CuArray()`. -```julia-repl -julia> Threads.nthreads() -4 -``` +Remember when importing `DistributedArrays.jl` to import it across all processes using [`@everywhere`](@ref) -But we are currently on the master thread. To check, we use the function [`Threads.threadid`](@ref) ```julia-repl -julia> Threads.threadid() -1 -``` - -### The `@threads` Macro - -Let's work a simple example using our native threads. Let us create an array of zeros: - -```jldoctest -julia> a = zeros(10) -10-element Array{Float64,1}: - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 -``` +$ ./julia -p 4 -Let us operate on this array simultaneously using 4 threads. We'll have each thread write its -thread ID into each location. - -Julia supports parallel loops using the [`Threads.@threads`](@ref) macro. This macro is affixed -in front of a `for` loop to indicate to Julia that the loop is a multi-threaded region: +julia> addprocs() -```julia-repl -julia> Threads.@threads for i = 1:10 - a[i] = Threads.threadid() - end -``` +julia> @everywhere using DistributedArrays -The iteration space is split amongst the threads, after which each thread writes its thread ID -to its assigned locations: +julia> using CuArrays -```julia-repl -julia> a -10-element Array{Float64,1}: - 1.0 - 1.0 - 1.0 - 2.0 - 2.0 - 2.0 - 3.0 - 3.0 - 4.0 - 4.0 -``` +julia> B = ones(10_000) ./ 2; -Note that [`Threads.@threads`](@ref) does not have an optional reduction parameter like [`@distributed`](@ref). +julia> A = ones(10_000) .* π; -Julia supports accessing and modifying values *atomically*, that is, in a thread-safe way to avoid -[race conditions](https://en.wikipedia.org/wiki/Race_condition). A value (which must be of a primitive -type) can be wrapped as [`Threads.Atomic`](@ref) to indicate it must be accessed in this way. -Here we can see an example: +julia> C = 2 .* A ./ B; -```julia-repl -julia> i = Threads.Atomic{Int}(0); +julia> all(C .≈ 4*π) +true -julia> ids = zeros(4); +julia> typeof(C) +Array{Float64,1} -julia> old_is = zeros(4); +julia> dB = distribute(B); -julia> Threads.@threads for id in 1:4 - old_is[id] = Threads.atomic_add!(i, id) - ids[id] = id - end +julia> dA = distribute(A); -julia> old_is -4-element Array{Float64,1}: - 0.0 - 1.0 - 7.0 - 3.0 +julia> dC = 2 .* dA ./ dB; -julia> ids -4-element Array{Float64,1}: - 1.0 - 2.0 - 3.0 - 4.0 -``` +julia> all(dC .≈ 4*π) +true -Had we tried to do the addition without the atomic tag, we might have gotten the -wrong answer due to a race condition. An example of what would happen if we didn't -avoid the race: +julia> typeof(dC) +DistributedArrays.DArray{Float64,1,Array{Float64,1}} -```julia-repl -julia> using Base.Threads +julia> cuB = CuArray(B); -julia> nthreads() -4 +julia> cuA = CuArray(A); -julia> acc = Ref(0) -Base.RefValue{Int64}(0) +julia> cuC = 2 .* cuA ./ cuB; -julia> @threads for i in 1:1000 - acc[] += 1 - end +julia> all(cuC .≈ 4*π); +true -julia> acc[] -926 +julia> typeof(cuC) +CuArray{Float64,1} +``` +Keep in mind that some Julia features are not currently supported by CUDAnative.jl [^2] , especially some functions like `sin` will need to be replaced with `CUDAnative.sin`(cc: @maleadt). -julia> acc = Atomic{Int64}(0) -Atomic{Int64}(0) +In the following example we will use both `DistributedArrays.jl` and `CuArrays.jl` to distribute an array across multiple +processes and call a generic function on it. -julia> @threads for i in 1:1000 - atomic_add!(acc, 1) - end +```julia +function power_method(M, v) + for i in 1:100 + v = M*v + v /= norm(v) + end -julia> acc[] -1000 + return v, norm(M*v) / norm(v) # or (M*v) ./ v +end ``` -!!! note - Not *all* primitive types can be wrapped in an `Atomic` tag. Supported types - are `Int8`, `Int16`, `Int32`, `Int64`, `Int128`, `UInt8`, `UInt16`, `UInt32`, - `UInt64`, `UInt128`, `Float16`, `Float32`, and `Float64`. Additionally, - `Int128` and `UInt128` are not supported on AAarch32 and ppc64le. - -When using multi-threading we have to be careful when using functions that are not -[pure](https://en.wikipedia.org/wiki/Pure_function) as we might get a wrong answer. -For instance functions that have their -[name ending with `!`](https://docs.julialang.org/en/latest/manual/style-guide/#Append-!-to-names-of-functions-that-modify-their-arguments-1) -by convention modify their arguments and thus are not pure. However, there are -functions that have side effects and their name does not end with `!`. For -instance [`findfirst(regex, str)`](@ref) mutates its `regex` argument or -[`rand()`](@ref) changes `Base.GLOBAL_RNG` : +`power_method` repeteavely creates a new vector and normalizes it. We have not specified any type signature in +function declaration, let's see if it works with the aforementioned datatypes: ```julia-repl -julia> using Base.Threads +julia> M = [2. 1; 1 1]; -julia> nthreads() -4 - -julia> function f() - s = repeat(["123", "213", "231"], outer=1000) - x = similar(s, Int) - rx = r"1" - @threads for i in 1:3000 - x[i] = findfirst(rx, s[i]).start - end - count(v -> v == 1, x) - end -f (generic function with 1 method) - -julia> f() # the correct result is 1000 -1017 +julia> v = rand(2) +2-element Array{Float64,1}: +0.40395 +0.445877 -julia> function g() - a = zeros(1000) - @threads for i in 1:1000 - a[i] = rand() - end - length(unique(a)) - end -g (generic function with 1 method) +julia> power_method(M,v) +([0.850651, 0.525731], 2.618033988749895) -julia> srand(1); g() # the result for a single thread is 1000 -781 -``` - -In such cases one should redesign the code to avoid the possibility of a race condition or use -[synchronization primitives](https://docs.julialang.org/en/latest/base/multi-threading/#Synchronization-Primitives-1). - -For example in order to fix `findfirst` example above one needs to have a -separate copy of `rx` variable for each thread: +julia> cuM = CuArray(M); -```julia-repl -julia> function f_fix() - s = repeat(["123", "213", "231"], outer=1000) - x = similar(s, Int) - rx = [Regex("1") for i in 1:nthreads()] - @threads for i in 1:3000 - x[i] = findfirst(rx[threadid()], s[i]).start - end - count(v -> v == 1, x) - end -f_fix (generic function with 1 method) +julia> cuv = CuArray(v); -julia> f_fix() -1000 -``` +julia> curesult = power_method(cuM, cuv); -We now use `Regex("1")` instead of `r"1"` to make sure that Julia -creates separate instances of `Regex` object for each entry of `rx` vector. +julia> typeof(curesult) +CuArray{Float64,1} -The case of `rand` is a bit more complex as we have to ensure that each thread -uses non-overlapping pseudorandom number sequences. This can be simply ensured -by using the `Future.randjump` function: +julia> dM = distribute(M); +julia> dv = distribute(v); -```julia-repl -julia> using Random; import Future +julia> dC = power_method(dM, dv); -julia> function g_fix(r) - a = zeros(1000) - @threads for i in 1:1000 - a[i] = rand(r[threadid()]) - end - length(unique(a)) - end -g_fix (generic function with 1 method) +julia> typeof(dC) +Tuple{DistributedArrays.DArray{Float64,1,Array{Float64,1}},Float64} +``` -julia> r = let m = MersenneTwister(1) - [m; accumulate(Future.randjump, m, fill(big(10)^20, nthreads()-1))] - end; +To end this short exposure to external packages, we can consider `MPI.jl`, a Julia wrapper +of the MPI protocol. As it would take too long to consider every inner function, it would be better +to simply appreciate the approach used to implement the protocol. -julia> g_fix(r) -1000 -``` +Consider this toy script which simply calls each subprocess, instantiate its rank and when the master +process is reached, performs the ranks' sum -We pass `r` vector to `g_fix` as generating several RGNs is an expensive -operation so we do not want to repeat it every time we run the function. +```julia +import MPI -## @threadcall (Experimental) +MPI.Init() -All I/O tasks, timers, REPL commands, etc are multiplexed onto a single OS thread via an event -loop. A patched version of libuv ([http://docs.libuv.org/en/v1.x/](http://docs.libuv.org/en/v1.x/)) -provides this functionality. Yield points provide for co-operatively scheduling multiple tasks -onto the same OS thread. I/O tasks and timers yield implicitly while waiting for the event to -occur. Calling [`yield`](@ref) explicitly allows for other tasks to be scheduled. +comm = MPI.COMM_WORLD +MPI.Barrier(comm) -Thus, a task executing a [`ccall`](@ref) effectively prevents the Julia scheduler from executing any other -tasks till the call returns. This is true for all calls into external libraries. Exceptions are -calls into custom C code that call back into Julia (which may then yield) or C code that calls -`jl_yield()` (C equivalent of [`yield`](@ref)). +root = 0 +r = MPI.Comm_rank(comm) -Note that while Julia code runs on a single thread (by default), libraries used by Julia may launch -their own internal threads. For example, the BLAS library may start as many threads as there are -cores on a machine. +sr = MPI.Reduce(r, MPI.SUM, root, comm) -The [`@threadcall`](@ref) macro addresses scenarios where we do not want a [`ccall`](@ref) to block the main Julia -event loop. It schedules a C function for execution in a separate thread. A threadpool with a -default size of 4 is used for this. The size of the threadpool is controlled via environment variable -`UV_THREADPOOL_SIZE`. While waiting for a free thread, and during function execution once a thread -is available, the requesting task (on the main Julia event loop) yields to other tasks. Note that -`@threadcall` does not return till the execution is complete. From a user point of view, it is -therefore a blocking call like other Julia APIs. +if(MPI.Comm_rank(comm) == root) + @printf("sum of ranks: %s\n", sr) +end -It is very important that the called function does not call back into Julia. +MPI.Finalize() +``` -`@threadcall` may be removed/changed in future versions of Julia. +``` +mpirun -np 4 ./julia example.jl +``` [^1]: - In this context, MPI refers to the MPI-1 standard. Beginning with MPI-2, the MPI standards committee - introduced a new set of communication mechanisms, collectively referred to as Remote Memory Access - (RMA). The motivation for adding RMA to the MPI standard was to facilitate one-sided communication - patterns. For additional information on the latest MPI standard, see [http://mpi-forum.org/docs](http://mpi-forum.org/docs/). + in this context, mpi refers to the mpi-1 standard. beginning with mpi-2, the mpi standards committee + introduced a new set of communication mechanisms, collectively referred to as remote memory access + (rma). the motivation for adding rma to the mpi standard was to facilitate one-sided communication + patterns. for additional information on the latest mpi standard, see [http://mpi-forum.org/docs](http://mpi-forum.org/docs/). + +[^2]: + [Julia GPU man pages](http://juliagpu.github.io/CUDAnative.jl/stable/man/usage.html#Julia-support-1) From e90732bcb36d8abccc3e82ccd8bd70cb0f39fdc5 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Sat, 28 Jul 2018 09:14:02 +0900 Subject: [PATCH 047/153] update Julia Commit cdf3d8f8d2 --- codex/manual/calling-c-and-fortran-code.md | 2 +- codex/manual/constructors.md | 4 +- codex/manual/faq.md | 2 +- codex/manual/noteworthy-differences.md | 2 +- codex/stdlib/Random.md | 239 ++++++++++++++++++++- src/manual/calling-c-and-fortran-code.md | 2 +- src/manual/constructors.md | 4 +- src/manual/faq.md | 2 +- src/manual/noteworthy-differences.md | 2 +- src/stdlib/Random.md | 239 ++++++++++++++++++++- 10 files changed, 476 insertions(+), 22 deletions(-) diff --git a/codex/manual/calling-c-and-fortran-code.md b/codex/manual/calling-c-and-fortran-code.md index 2077876..44668ba 100644 --- a/codex/manual/calling-c-and-fortran-code.md +++ b/codex/manual/calling-c-and-fortran-code.md @@ -734,7 +734,7 @@ end ``` The meaning of prefix `&` is not quite the same as in C. In particular, any changes to the referenced -variables will not be visible in Julia unless the type is mutable (declared via `type`). However, +variables will not be visible in Julia unless the type is mutable (declared via `mutable struct`). However, even for immutable structs it will not cause any harm for called functions to attempt such modifications (that is, writing through the passed pointers). Moreover, `&` may be used with any expression, such as `&0` or `&f(x)`. diff --git a/codex/manual/constructors.md b/codex/manual/constructors.md index 8ee79ea..287ff21 100644 --- a/codex/manual/constructors.md +++ b/codex/manual/constructors.md @@ -338,7 +338,7 @@ julia> Point(x::T, y::T) where {T<:Real} = Point{T}(x,y); Notice that each definition looks like the form of constructor call that it handles. The call `Point{Int64}(1,2)` will invoke the definition `Point{T}(x,y)` inside the -`type` block. +`struct` block. The outer constructor declaration, on the other hand, defines a method for the general `Point` constructor which only applies to pairs of values of the same real type. This declaration makes constructor calls without explicit type parameters, like `Point(1,2)` @@ -534,7 +534,7 @@ The problem is that we want `S` to be a larger type than `T`, so that we can sum with less information loss. For example, when `T` is [`Int32`](@ref), we would like `S` to be [`Int64`](@ref). Therefore we want to avoid an interface that allows the user to construct instances of the type `SummedArray{Int32,Int32}`. One way to do this is to provide a -constructor only for `SummedArray`, but inside the `type` definition block to suppress +constructor only for `SummedArray`, but inside the `struct` definition block to suppress generation of default constructors: ```jldoctest diff --git a/codex/manual/faq.md b/codex/manual/faq.md index 80b1751..192aa28 100644 --- a/codex/manual/faq.md +++ b/codex/manual/faq.md @@ -575,7 +575,7 @@ Main Module gvar_self 13 bytes String ``` -This does not apply to `function` or `type` declarations. However, anonymous functions bound to global +This does not apply to `function` or `struct` declarations. However, anonymous functions bound to global variables are serialized as can be seen below. ```julia-repl diff --git a/codex/manual/noteworthy-differences.md b/codex/manual/noteworthy-differences.md index 2c61066..9aff0df 100644 --- a/codex/manual/noteworthy-differences.md +++ b/codex/manual/noteworthy-differences.md @@ -69,7 +69,7 @@ may trip up Julia users accustomed to MATLAB: * In both Julia and MATLAB, the variable `ans` is set to the value of the last expression issued in an interactive session. In Julia, unlike MATLAB, `ans` is not set when Julia code is run in non-interactive mode. - * Julia's `type`s do not support dynamically adding fields at runtime, unlike MATLAB's `class`es. + * Julia's `struct`s do not support dynamically adding fields at runtime, unlike MATLAB's `class`es. Instead, use a [`Dict`](@ref). * In Julia each module has its own global scope/namespace, whereas in MATLAB there is just one global scope. diff --git a/codex/stdlib/Random.md b/codex/stdlib/Random.md index 54abfc2..a26e0bb 100644 --- a/codex/stdlib/Random.md +++ b/codex/stdlib/Random.md @@ -10,12 +10,12 @@ can be plugged in by inheriting the `AbstractRNG` type; they can then be used to streams of random numbers. Besides `MersenneTwister`, Julia also provides the `RandomDevice` RNG type, which is a wrapper over the OS provided entropy. -Most functions related to random generation accept an optional `AbstractRNG` as the first argument, -`rng` , which defaults to the global one if not provided. Moreover, some of them accept optionally +Most functions related to random generation accept an optional `AbstractRNG` object as first argument, +which defaults to the global one if not provided. Moreover, some of them accept optionally dimension specifications `dims...` (which can be given as a tuple) to generate arrays of random values. -A `MersenneTwister` or `RandomDevice` RNG can generate random numbers of the following types: +A `MersenneTwister` or `RandomDevice` RNG can generate uniformly random numbers of the following types: [`Float16`](@ref), [`Float32`](@ref), [`Float64`](@ref), [`BigFloat`](@ref), [`Bool`](@ref), [`Int8`](@ref), [`UInt8`](@ref), [`Int16`](@ref), [`UInt16`](@ref), [`Int32`](@ref), [`UInt32`](@ref), [`Int64`](@ref), [`UInt64`](@ref), [`Int128`](@ref), [`UInt128`](@ref), @@ -23,10 +23,13 @@ A `MersenneTwister` or `RandomDevice` RNG can generate random numbers of the fol Random floating point numbers are generated uniformly in ``[0, 1)``. As `BigInt` represents unbounded integers, the interval must be specified (e.g. `rand(big.(1:6))`). +Additionally, normal and exponential distributions are implemented for some `AbstractFloat` and +`Complex` types, see [`randn`](@ref) and [`randexp`](@ref) for details. + + +## Random generation functions + ```@docs -Random.srand -Random.MersenneTwister -Random.RandomDevice Random.rand Random.rand! Random.bitrand @@ -35,6 +38,11 @@ Random.randn! Random.randexp Random.randexp! Random.randstring +``` + +## Subsequences, permutations and shuffling + +```@docs Random.randsubseq Random.randsubseq! Random.randperm @@ -45,6 +53,225 @@ Random.shuffle Random.shuffle! ``` +## Generators (creation and seeding) + +```@docs +Random.srand +Random.MersenneTwister +Random.RandomDevice +``` + +## Hooking into the `Random` API + +There are two mostly orthogonal ways to extend `Random` functionalities: +1) generating random values of custom types +2) creating new generators + +The API for 1) is quite functional, but is relatively recent so it may still have to evolve in subsequent releases of the `Random` module. +For example, it's typically sufficient to implement one `rand` method in order to have all other usual methods work automatically. + +The API for 2) is still rudimentary, and may require more work than strictly necessary from the implementor, +in order to support usual types of generated values. + +### Generating random values of custom types + +There are two categories: generating values from a type (e.g. `rand(Int)`), or from a collection (e.g. `rand(1:3)`). +The simple cases are explained first, and more advanced usage is presented later. +We assume here that the choice of algorithm is independent of the RNG, so we use `AbstractRNG` in our signatures. + +#### Generating values from a type + +Given a type `T`, it's currently assumed that if `rand(T)` is defined, an object of type `T` will be produced. +In order to define random generation of values of type `T`, the following method can be defined: +`rand(rng::AbstractRNG, ::Random.SamplerType{T})` (this should return what `rand(rng, T)` is expected to return). + +Let's take the following example: we implement a `Die` type, with a variable number `n` of sides, numbered from `1` to `n`. +We want `rand(Die)` to produce a die with a random number of up to 20 sides (and at least 4): + +```jldoctest Die +struct Die + nsides::Int # number of sides +end + +Random.rand(rng::AbstractRNG, ::Random.SamplerType{Die}) = Die(rand(rng, 4:20)) + +# output + +``` + +Scalar and array methods for `Die` now work as expected: + +```jldoctest Die; setup = :(srand(1)) +julia> rand(Die) +Die(18) + +julia> rand(MersenneTwister(0), Die) +Die(4) + +julia> rand(Die, 3) +3-element Array{Die,1}: + Die(6) + Die(11) + Die(5) + +julia> a = Vector{Die}(undef, 3); rand!(a) +3-element Array{Die,1}: + Die(18) + Die(6) + Die(8) +``` + +#### Generating values from a collection + +Given a collection type `S`, it's currently assumed that if `rand(::S)` is defined, an object of type `eltype(S)` will be produced. +In order to define random generation out of objects of type `S`, the following method can be defined: +`rand(rng::AbstractRNG, sp::Random.SamplerTrivial{S})`. Here, `sp` simply wraps an object of type `S`, which can be accessed via `sp[]`. +Continuing the `Die` example, we want now to define `rand(d::Die)` to produce an `Int` corresponding to one of `d`'s sides: + +```jldoctest Die; setup = :(srand(1)) +julia> Random.rand(rng::AbstractRNG, d::Random.SamplerTrivial{Die}) = rand(rng, 1:d[].nsides); + +julia> rand(Die(4)) +3 + +julia> rand(Die(4), 3) +3-element Array{Any,1}: + 3 + 4 + 2 +``` + +In the last example, a `Vector{Any}` is produced; the reason is that `eltype(Die) == Any`. The remedy is to define +`Base.eltype(::Type{Die}) = Int`. + + +#### Generating values for an `AbstractFloat` type + +`AbstractFloat` types are special-cased, because by default random values are not produced in the whole type domain, but rather +in `[0,1)`. The following method should be implemented for `T <: AbstractFloat`: +`Random.rand(::AbstractRNG, ::Random.SamplerTrivial{Random.CloseOpen01{T}})` + + +#### Optimizing generation with cached computation between calls + +When repeatedly generating random values (with the same `rand` parameters), it happens for some types +that the result of a computation is used for each call. In this case, the computation can be decoupled +from actually generating the values. This is the case for example with the default implementation for +`AbstractArray`. Assume that `rand(rng, 1:20)` has to be called repeatedly in a loop: the way to take advantage +of this decoupling is as follows: + +```julia +rng = MersenneTwister() +sp = Random.Sampler(rng, 1:20) # or Random.Sampler(MersenneTwister,1:20) +for x in X + n = rand(rng, sp) # similar to n = rand(rng, 1:20) + # use n +end +``` + +This mechanism is of course used by the default implementation of random array generation (like in `rand(1:20, 10)`). +In order to implement this decoupling for a custom type, a helper type can be used. +Going back to our `Die` example: `rand(::Die)` uses random generation from a range, so +there is an opportunity for this optimization: + +```julia +import Random: Sampler, rand + +struct SamplerDie <: Sampler{Int} # generates values of type Int + die::Die + sp::Sampler{Int} # this is an abstract type, so this could be improved +end + +Sampler(RNG::Type{<:AbstractRNG}, die::Die, r::Random.Repetition) = + SamplerDie(die, Sampler(RNG, 1:die.nsides, r)) +# the `r` parameter will be explained later on + +rand(rng::AbstractRNG, sp::SamplerDie) = rand(rng, sp.sp) +``` + +It's now possible to get a sampler with `sp = Sampler(rng, die)`, and use `sp` instead of `die` in any `rand` call involving `rng`. +In the simplistic example above, `die` doesn't need to be stored in `SamplerDie` but this is often the case in practice. + +This pattern is so frequent that a helper type named `Random.SamplerSimple` is available, +saving us the definition of `SamplerDie`: we could have implemented our decoupling with: + +```julia +Sampler(RNG::Type{<:AbstractRNG}, die::Die, r::Random.Repetition) = + SamplerSimple(die, Sampler(RNG, 1:die.nsides, r)) + +rand(rng::AbstractRNG, sp::SamplerSimple{Die}) = rand(rng, sp.data) +``` + +Here, `sp.data` refers to the second parameter in the call to the `SamplerSimple` constructor +(in this case equal to `Sampler(rng, 1:die.nsides, r)`), while the `Die` object can be accessed +via `sp[]`. + +Another helper type is currently available for other cases, `Random.SamplerTag`, but is +considered as internal API, and can break at any time without proper deprecations. + + +#### Using distinct algorithms for scalar or array generation + +In some cases, whether one wants to generate only a handful of values or a large number of values +will have an impact on the choice of algorithm. This is handled with the third parameter of the +`Sampler` constructor. Let's assume we defined two helper types for `Die`, say `SamplerDie1` +which should be used to generate only few random values, and `SamplerDieMany` for many values. +We can use those types as follows: + +```julia +Sampler(RNG::Type{<:AbstractRNG}, die::Die, ::Val{1}) = SamplerDie1(...) +Sampler(RNG::Type{<:AbstractRNG}, die::Die, ::Val{Inf}) = SamplerDieMany(...) +``` + +Of course, `rand` must also be defined on those types (i.e. `rand(::AbstractRNG, ::SamplerDie1)` +and `rand(::AbstractRNG, ::SamplerDieMany)`). + +Note: `Sampler(rng, x)` is simply a shorthand for `Sampler(rng, x, Val(Inf))`, and +`Random.Repetition` is an alias for `Union{Val{1}, Val{Inf}}`. + + +### Creating new generators + +The API is not clearly defined yet, but as a rule of thumb: +1) any `rand` method producing "basic" types (`isbitstype` integer and floating types in `Base`) + should be defined for this specific RNG, if they are needed; +2) other documented `rand` methods accepting an `AbstractRNG` should work out of the box, + (provided the methods from 1) what are relied on are implemented), + but can of course be specialized for this RNG if there is room for optimization. + +Concerning 1), a `rand` method may happen to work automatically, but it's not officially +supported and may break without warnings in a subsequent release. + +To define a new `rand` method for an hypothetical `MyRNG` generator, and a value specification `s` +(e.g. `s == Int`, or `s == 1:10`) of type `S==typeof(s)` or `S==Type{s}` if `s` is a type, +the same two methods as we saw before must be defined: + +1) `Sampler(::Type{MyRNG}, ::S, ::Repetition)`, which returns an object of type say `SamplerS` +2) `rand(rng::MyRNG, sp::SamplerS)` + +It can happen that `Sampler(rng::AbstractRNG, ::S, ::Repetition)` is +already defined in the `Random` module. It would then be possible to +skip step 1) in practice (if one wants to specialize generation for +this particular RNG type), but the corresponding `SamplerS` type is +considered as internal detail, and may be changed without warning. + + +#### Specializing array generation + +In some cases, for a given RNG type, generating an array of random +values can be more efficient with a specialized method than by merely +using the decoupling technique explained before. This is for example +the case for `MersenneTwister`, which natively writes random values in +an array. + +To implement this specialization for `MyRNG` +and for a specification `s`, producing elements of type `S`, +the following method can be defined: +`rand!(rng::MyRNG, a::AbstractArray{S}, ::SamplerS)`, +where `SamplerS` is the type of the sampler returned by `Sampler(MyRNG, s, Val(Inf))`. +Instead of `AbstractArray`, it's possible to implement the functionality only for a subtype, e.g. `Array{S}`. +The non-mutating array method of `rand` will automatically call this specialization internally. + ```@meta DocTestSetup = nothing ``` diff --git a/src/manual/calling-c-and-fortran-code.md b/src/manual/calling-c-and-fortran-code.md index 2077876..44668ba 100644 --- a/src/manual/calling-c-and-fortran-code.md +++ b/src/manual/calling-c-and-fortran-code.md @@ -734,7 +734,7 @@ end ``` The meaning of prefix `&` is not quite the same as in C. In particular, any changes to the referenced -variables will not be visible in Julia unless the type is mutable (declared via `type`). However, +variables will not be visible in Julia unless the type is mutable (declared via `mutable struct`). However, even for immutable structs it will not cause any harm for called functions to attempt such modifications (that is, writing through the passed pointers). Moreover, `&` may be used with any expression, such as `&0` or `&f(x)`. diff --git a/src/manual/constructors.md b/src/manual/constructors.md index 8ee79ea..287ff21 100644 --- a/src/manual/constructors.md +++ b/src/manual/constructors.md @@ -338,7 +338,7 @@ julia> Point(x::T, y::T) where {T<:Real} = Point{T}(x,y); Notice that each definition looks like the form of constructor call that it handles. The call `Point{Int64}(1,2)` will invoke the definition `Point{T}(x,y)` inside the -`type` block. +`struct` block. The outer constructor declaration, on the other hand, defines a method for the general `Point` constructor which only applies to pairs of values of the same real type. This declaration makes constructor calls without explicit type parameters, like `Point(1,2)` @@ -534,7 +534,7 @@ The problem is that we want `S` to be a larger type than `T`, so that we can sum with less information loss. For example, when `T` is [`Int32`](@ref), we would like `S` to be [`Int64`](@ref). Therefore we want to avoid an interface that allows the user to construct instances of the type `SummedArray{Int32,Int32}`. One way to do this is to provide a -constructor only for `SummedArray`, but inside the `type` definition block to suppress +constructor only for `SummedArray`, but inside the `struct` definition block to suppress generation of default constructors: ```jldoctest diff --git a/src/manual/faq.md b/src/manual/faq.md index 80b1751..192aa28 100644 --- a/src/manual/faq.md +++ b/src/manual/faq.md @@ -575,7 +575,7 @@ Main Module gvar_self 13 bytes String ``` -This does not apply to `function` or `type` declarations. However, anonymous functions bound to global +This does not apply to `function` or `struct` declarations. However, anonymous functions bound to global variables are serialized as can be seen below. ```julia-repl diff --git a/src/manual/noteworthy-differences.md b/src/manual/noteworthy-differences.md index 2c61066..9aff0df 100644 --- a/src/manual/noteworthy-differences.md +++ b/src/manual/noteworthy-differences.md @@ -69,7 +69,7 @@ may trip up Julia users accustomed to MATLAB: * In both Julia and MATLAB, the variable `ans` is set to the value of the last expression issued in an interactive session. In Julia, unlike MATLAB, `ans` is not set when Julia code is run in non-interactive mode. - * Julia's `type`s do not support dynamically adding fields at runtime, unlike MATLAB's `class`es. + * Julia's `struct`s do not support dynamically adding fields at runtime, unlike MATLAB's `class`es. Instead, use a [`Dict`](@ref). * In Julia each module has its own global scope/namespace, whereas in MATLAB there is just one global scope. diff --git a/src/stdlib/Random.md b/src/stdlib/Random.md index 54abfc2..a26e0bb 100644 --- a/src/stdlib/Random.md +++ b/src/stdlib/Random.md @@ -10,12 +10,12 @@ can be plugged in by inheriting the `AbstractRNG` type; they can then be used to streams of random numbers. Besides `MersenneTwister`, Julia also provides the `RandomDevice` RNG type, which is a wrapper over the OS provided entropy. -Most functions related to random generation accept an optional `AbstractRNG` as the first argument, -`rng` , which defaults to the global one if not provided. Moreover, some of them accept optionally +Most functions related to random generation accept an optional `AbstractRNG` object as first argument, +which defaults to the global one if not provided. Moreover, some of them accept optionally dimension specifications `dims...` (which can be given as a tuple) to generate arrays of random values. -A `MersenneTwister` or `RandomDevice` RNG can generate random numbers of the following types: +A `MersenneTwister` or `RandomDevice` RNG can generate uniformly random numbers of the following types: [`Float16`](@ref), [`Float32`](@ref), [`Float64`](@ref), [`BigFloat`](@ref), [`Bool`](@ref), [`Int8`](@ref), [`UInt8`](@ref), [`Int16`](@ref), [`UInt16`](@ref), [`Int32`](@ref), [`UInt32`](@ref), [`Int64`](@ref), [`UInt64`](@ref), [`Int128`](@ref), [`UInt128`](@ref), @@ -23,10 +23,13 @@ A `MersenneTwister` or `RandomDevice` RNG can generate random numbers of the fol Random floating point numbers are generated uniformly in ``[0, 1)``. As `BigInt` represents unbounded integers, the interval must be specified (e.g. `rand(big.(1:6))`). +Additionally, normal and exponential distributions are implemented for some `AbstractFloat` and +`Complex` types, see [`randn`](@ref) and [`randexp`](@ref) for details. + + +## Random generation functions + ```@docs -Random.srand -Random.MersenneTwister -Random.RandomDevice Random.rand Random.rand! Random.bitrand @@ -35,6 +38,11 @@ Random.randn! Random.randexp Random.randexp! Random.randstring +``` + +## Subsequences, permutations and shuffling + +```@docs Random.randsubseq Random.randsubseq! Random.randperm @@ -45,6 +53,225 @@ Random.shuffle Random.shuffle! ``` +## Generators (creation and seeding) + +```@docs +Random.srand +Random.MersenneTwister +Random.RandomDevice +``` + +## Hooking into the `Random` API + +There are two mostly orthogonal ways to extend `Random` functionalities: +1) generating random values of custom types +2) creating new generators + +The API for 1) is quite functional, but is relatively recent so it may still have to evolve in subsequent releases of the `Random` module. +For example, it's typically sufficient to implement one `rand` method in order to have all other usual methods work automatically. + +The API for 2) is still rudimentary, and may require more work than strictly necessary from the implementor, +in order to support usual types of generated values. + +### Generating random values of custom types + +There are two categories: generating values from a type (e.g. `rand(Int)`), or from a collection (e.g. `rand(1:3)`). +The simple cases are explained first, and more advanced usage is presented later. +We assume here that the choice of algorithm is independent of the RNG, so we use `AbstractRNG` in our signatures. + +#### Generating values from a type + +Given a type `T`, it's currently assumed that if `rand(T)` is defined, an object of type `T` will be produced. +In order to define random generation of values of type `T`, the following method can be defined: +`rand(rng::AbstractRNG, ::Random.SamplerType{T})` (this should return what `rand(rng, T)` is expected to return). + +Let's take the following example: we implement a `Die` type, with a variable number `n` of sides, numbered from `1` to `n`. +We want `rand(Die)` to produce a die with a random number of up to 20 sides (and at least 4): + +```jldoctest Die +struct Die + nsides::Int # number of sides +end + +Random.rand(rng::AbstractRNG, ::Random.SamplerType{Die}) = Die(rand(rng, 4:20)) + +# output + +``` + +Scalar and array methods for `Die` now work as expected: + +```jldoctest Die; setup = :(srand(1)) +julia> rand(Die) +Die(18) + +julia> rand(MersenneTwister(0), Die) +Die(4) + +julia> rand(Die, 3) +3-element Array{Die,1}: + Die(6) + Die(11) + Die(5) + +julia> a = Vector{Die}(undef, 3); rand!(a) +3-element Array{Die,1}: + Die(18) + Die(6) + Die(8) +``` + +#### Generating values from a collection + +Given a collection type `S`, it's currently assumed that if `rand(::S)` is defined, an object of type `eltype(S)` will be produced. +In order to define random generation out of objects of type `S`, the following method can be defined: +`rand(rng::AbstractRNG, sp::Random.SamplerTrivial{S})`. Here, `sp` simply wraps an object of type `S`, which can be accessed via `sp[]`. +Continuing the `Die` example, we want now to define `rand(d::Die)` to produce an `Int` corresponding to one of `d`'s sides: + +```jldoctest Die; setup = :(srand(1)) +julia> Random.rand(rng::AbstractRNG, d::Random.SamplerTrivial{Die}) = rand(rng, 1:d[].nsides); + +julia> rand(Die(4)) +3 + +julia> rand(Die(4), 3) +3-element Array{Any,1}: + 3 + 4 + 2 +``` + +In the last example, a `Vector{Any}` is produced; the reason is that `eltype(Die) == Any`. The remedy is to define +`Base.eltype(::Type{Die}) = Int`. + + +#### Generating values for an `AbstractFloat` type + +`AbstractFloat` types are special-cased, because by default random values are not produced in the whole type domain, but rather +in `[0,1)`. The following method should be implemented for `T <: AbstractFloat`: +`Random.rand(::AbstractRNG, ::Random.SamplerTrivial{Random.CloseOpen01{T}})` + + +#### Optimizing generation with cached computation between calls + +When repeatedly generating random values (with the same `rand` parameters), it happens for some types +that the result of a computation is used for each call. In this case, the computation can be decoupled +from actually generating the values. This is the case for example with the default implementation for +`AbstractArray`. Assume that `rand(rng, 1:20)` has to be called repeatedly in a loop: the way to take advantage +of this decoupling is as follows: + +```julia +rng = MersenneTwister() +sp = Random.Sampler(rng, 1:20) # or Random.Sampler(MersenneTwister,1:20) +for x in X + n = rand(rng, sp) # similar to n = rand(rng, 1:20) + # use n +end +``` + +This mechanism is of course used by the default implementation of random array generation (like in `rand(1:20, 10)`). +In order to implement this decoupling for a custom type, a helper type can be used. +Going back to our `Die` example: `rand(::Die)` uses random generation from a range, so +there is an opportunity for this optimization: + +```julia +import Random: Sampler, rand + +struct SamplerDie <: Sampler{Int} # generates values of type Int + die::Die + sp::Sampler{Int} # this is an abstract type, so this could be improved +end + +Sampler(RNG::Type{<:AbstractRNG}, die::Die, r::Random.Repetition) = + SamplerDie(die, Sampler(RNG, 1:die.nsides, r)) +# the `r` parameter will be explained later on + +rand(rng::AbstractRNG, sp::SamplerDie) = rand(rng, sp.sp) +``` + +It's now possible to get a sampler with `sp = Sampler(rng, die)`, and use `sp` instead of `die` in any `rand` call involving `rng`. +In the simplistic example above, `die` doesn't need to be stored in `SamplerDie` but this is often the case in practice. + +This pattern is so frequent that a helper type named `Random.SamplerSimple` is available, +saving us the definition of `SamplerDie`: we could have implemented our decoupling with: + +```julia +Sampler(RNG::Type{<:AbstractRNG}, die::Die, r::Random.Repetition) = + SamplerSimple(die, Sampler(RNG, 1:die.nsides, r)) + +rand(rng::AbstractRNG, sp::SamplerSimple{Die}) = rand(rng, sp.data) +``` + +Here, `sp.data` refers to the second parameter in the call to the `SamplerSimple` constructor +(in this case equal to `Sampler(rng, 1:die.nsides, r)`), while the `Die` object can be accessed +via `sp[]`. + +Another helper type is currently available for other cases, `Random.SamplerTag`, but is +considered as internal API, and can break at any time without proper deprecations. + + +#### Using distinct algorithms for scalar or array generation + +In some cases, whether one wants to generate only a handful of values or a large number of values +will have an impact on the choice of algorithm. This is handled with the third parameter of the +`Sampler` constructor. Let's assume we defined two helper types for `Die`, say `SamplerDie1` +which should be used to generate only few random values, and `SamplerDieMany` for many values. +We can use those types as follows: + +```julia +Sampler(RNG::Type{<:AbstractRNG}, die::Die, ::Val{1}) = SamplerDie1(...) +Sampler(RNG::Type{<:AbstractRNG}, die::Die, ::Val{Inf}) = SamplerDieMany(...) +``` + +Of course, `rand` must also be defined on those types (i.e. `rand(::AbstractRNG, ::SamplerDie1)` +and `rand(::AbstractRNG, ::SamplerDieMany)`). + +Note: `Sampler(rng, x)` is simply a shorthand for `Sampler(rng, x, Val(Inf))`, and +`Random.Repetition` is an alias for `Union{Val{1}, Val{Inf}}`. + + +### Creating new generators + +The API is not clearly defined yet, but as a rule of thumb: +1) any `rand` method producing "basic" types (`isbitstype` integer and floating types in `Base`) + should be defined for this specific RNG, if they are needed; +2) other documented `rand` methods accepting an `AbstractRNG` should work out of the box, + (provided the methods from 1) what are relied on are implemented), + but can of course be specialized for this RNG if there is room for optimization. + +Concerning 1), a `rand` method may happen to work automatically, but it's not officially +supported and may break without warnings in a subsequent release. + +To define a new `rand` method for an hypothetical `MyRNG` generator, and a value specification `s` +(e.g. `s == Int`, or `s == 1:10`) of type `S==typeof(s)` or `S==Type{s}` if `s` is a type, +the same two methods as we saw before must be defined: + +1) `Sampler(::Type{MyRNG}, ::S, ::Repetition)`, which returns an object of type say `SamplerS` +2) `rand(rng::MyRNG, sp::SamplerS)` + +It can happen that `Sampler(rng::AbstractRNG, ::S, ::Repetition)` is +already defined in the `Random` module. It would then be possible to +skip step 1) in practice (if one wants to specialize generation for +this particular RNG type), but the corresponding `SamplerS` type is +considered as internal detail, and may be changed without warning. + + +#### Specializing array generation + +In some cases, for a given RNG type, generating an array of random +values can be more efficient with a specialized method than by merely +using the decoupling technique explained before. This is for example +the case for `MersenneTwister`, which natively writes random values in +an array. + +To implement this specialization for `MyRNG` +and for a specification `s`, producing elements of type `S`, +the following method can be defined: +`rand!(rng::MyRNG, a::AbstractArray{S}, ::SamplerS)`, +where `SamplerS` is the type of the sampler returned by `Sampler(MyRNG, s, Val(Inf))`. +Instead of `AbstractArray`, it's possible to implement the functionality only for a subtype, e.g. `Array{S}`. +The non-mutating array method of `rand` will automatically call this specialization internally. + ```@meta DocTestSetup = nothing ``` From f5053b5233e93887d1ab1de92d1bb1f4859f5393 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Mon, 30 Jul 2018 12:14:03 +0900 Subject: [PATCH 048/153] update Julia Commit 60b8e23d65 --- codex/NEWS.md | 8 +++++- codex/base/arrays.md | 2 +- codex/base/base.md | 4 +-- codex/base/collections.md | 1 - codex/devdocs/llvm.md | 5 ++++ codex/devdocs/subarrays.md | 2 +- codex/manual/methods.md | 10 +++++-- codex/manual/parallel-computing.md | 2 +- codex/manual/performance-tips.md | 8 +++--- codex/manual/types.md | 4 +-- codex/stdlib/Pkg.md | 44 +++++++++++++++++++++++++++--- codex/stdlib/Random.md | 2 +- src/NEWS.md | 8 +++++- src/base/arrays.md | 2 +- src/base/base.md | 4 +-- src/base/collections.md | 1 - src/devdocs/llvm.md | 5 ++++ src/devdocs/subarrays.md | 2 +- src/manual/methods.md | 9 +++++- src/manual/parallel-computing.md | 2 +- src/manual/performance-tips.md | 8 +++--- src/manual/types.md | 4 +-- src/stdlib/Pkg.md | 44 +++++++++++++++++++++++++++--- src/stdlib/Random.md | 2 +- 24 files changed, 144 insertions(+), 39 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index 30611c5..0e80da5 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -798,7 +798,7 @@ Deprecated or removed `dims` keyword argument. This includes the functions `sum`, `prod`, `maximum`, `minimum`, `all`, `any`, `findmax`, `findmin`, `mean`, `varm`, `std`, `var`, `cov`, `cor`, `median`, `mapreducedim`, `reducedim`, `sort`, `accumulate`, `accumulate!`, - `cumsum`, `cumsum!`, `cumprod`, `cumprod!`, `flipdim`, `squeeze`, and `cat` ([#25501](https://github.com/JuliaLang/julia/issues/25501), [#26660](https://github.com/JuliaLang/julia/issues/26660), [#27100](https://github.com/JuliaLang/julia/issues/27100)). + `cumsum`, `cumsum!`, `cumprod`, `cumprod!`, `flipdim`, `dropdims`, and `cat` ([#25501](https://github.com/JuliaLang/julia/issues/25501), [#26660](https://github.com/JuliaLang/julia/issues/26660), [#27100](https://github.com/JuliaLang/julia/issues/27100)). * `indices(a)` and `indices(a,d)` have been deprecated in favor of `axes(a)` and `axes(a, d)` ([#25057](https://github.com/JuliaLang/julia/issues/25057)). @@ -1321,6 +1321,12 @@ Deprecated or removed * `ndigits(n, b, [pad])` is deprecated in favor of `ndigits(n, base=b, pad=pad)` ([#27908](https://github.com/JuliaLang/julia/issues/27908)). + * `squeeze` is deprecated in favor of `dropdims`. + + * `srand` is deprecated in favor of the unexported `Random.seed!` ([#27726](https://github.com/JuliaLang/julia/issues/27726)). + + * `realmin`/`realmax` are deprecated in favor of `floatmin`/`floatmax` ([#28302](https://github.com/JuliaLang/julia/issues/28302)). + Command-line option changes --------------------------- diff --git a/codex/base/arrays.md b/codex/base/arrays.md index f2bb0b9..421a527 100644 --- a/codex/base/arrays.md +++ b/codex/base/arrays.md @@ -105,7 +105,7 @@ Base.parentindices Base.selectdim Base.reinterpret Base.reshape -Base.squeeze +Base.dropdims Base.vec ``` diff --git a/codex/base/base.md b/codex/base/base.md index 36e47cc..d2a6dd1 100644 --- a/codex/base/base.md +++ b/codex/base/base.md @@ -162,8 +162,8 @@ Base.datatype_pointerfree ```@docs Base.typemin Base.typemax -Base.realmin -Base.realmax +Base.floatmin +Base.floatmax Base.maxintfloat Base.eps(::Type{<:AbstractFloat}) Base.eps(::AbstractFloat) diff --git a/codex/base/collections.md b/codex/base/collections.md index 0e1ece3..c070111 100644 --- a/codex/base/collections.md +++ b/codex/base/collections.md @@ -134,7 +134,6 @@ Base.collect(::Type, ::Any) Base.filter Base.filter! Base.replace(::Any, ::Pair...) -Base.replace(::Base.Callable, ::Any, ::Any) Base.replace(::Base.Callable, ::Any) Base.replace! ``` diff --git a/codex/devdocs/llvm.md b/codex/devdocs/llvm.md index 10af27f..9ed7da7 100644 --- a/codex/devdocs/llvm.md +++ b/codex/devdocs/llvm.md @@ -211,6 +211,11 @@ three different address spaces (their numbers are defined in `src/codegen_shared future), but unlike the other pointers need not be rooted if passed to a call (they do still need to be rooted if they are live across another safepoint between the definition and the call). +- Pointers loaded from tracked object (currently 13): This is used by arrays, + which themselves contain a pointer to the managed data. This data area is owned + by the array, but is not a GC-tracked object by itself. The compiler guarantees + that as long as this pointer is live, the object that this pointer was loaded + from will keep being live. ### Invariants diff --git a/codex/devdocs/subarrays.md b/codex/devdocs/subarrays.md index 657d8a8..6b91083 100644 --- a/codex/devdocs/subarrays.md +++ b/codex/devdocs/subarrays.md @@ -37,7 +37,7 @@ cartesian, rather than linear, indexing. Consider making 2d slices of a 3d array: ```@meta -DocTestSetup = :(import Random; Random.srand(1234)) +DocTestSetup = :(import Random; Random.seed!(1234)) ``` ```jldoctest subarray julia> A = rand(2,3,4); diff --git a/codex/manual/methods.md b/codex/manual/methods.md index 60bd61e..31dea86 100644 --- a/codex/manual/methods.md +++ b/codex/manual/methods.md @@ -851,10 +851,13 @@ julia> function (p::Polynomial)(x) end return v end + +julia> (p::Polynomial)() = p(5) ``` -Notice that the function is specified by type instead of by name. In the function body, `p` will -refer to the object that was called. A `Polynomial` can be used as follows: +Notice that the function is specified by type instead of by name. As with normal functions +there is a terse syntax form. In the function body, `p` will refer to the object that was +called. A `Polynomial` can be used as follows: ```jldoctest polynomial julia> p = Polynomial([1,10,100]) @@ -862,6 +865,9 @@ Polynomial{Int64}([1, 10, 100]) julia> p(3) 931 + +julia> p() +2551 ``` This mechanism is also the key to how type constructors and closures (inner functions that refer diff --git a/codex/manual/parallel-computing.md b/codex/manual/parallel-computing.md index a803696..5f18d97 100644 --- a/codex/manual/parallel-computing.md +++ b/codex/manual/parallel-computing.md @@ -418,7 +418,7 @@ julia> function g() end g (generic function with 1 method) -julia> srand(1); g() # the result for a single thread is 1000 +julia> Random.seed!(1); g() # the result for a single thread is 1000 781 ``` diff --git a/codex/manual/performance-tips.md b/codex/manual/performance-tips.md index c3fbc6f..cd81e9e 100644 --- a/codex/manual/performance-tips.md +++ b/codex/manual/performance-tips.md @@ -58,7 +58,7 @@ so all the performance issues discussed previously apply. A useful tool for measuring performance is the [`@time`](@ref) macro. We here repeat the example with the global variable above, but this time with the type annotation removed: -```jldoctest; setup = :(using Random; srand(1234)), filter = r"[0-9\.]+ seconds \(.*?\)" +```jldoctest; setup = :(using Random; Random.seed!(1234)), filter = r"[0-9\.]+ seconds \(.*?\)" julia> x = rand(1000); julia> function sum_global() @@ -94,7 +94,7 @@ If we instead pass `x` as an argument to the function it no longer allocates mem (the allocation reported below is due to running the `@time` macro in global scope) and is significantly faster after the first call: -```jldoctest sumarg; setup = :(using Random; srand(1234)), filter = r"[0-9\.]+ seconds \(.*?\)" +```jldoctest sumarg; setup = :(using Random; Random.seed!(1234)), filter = r"[0-9\.]+ seconds \(.*?\)" julia> x = rand(1000); julia> function sum_arg(x) @@ -583,7 +583,7 @@ to perform a core computation. Where possible, it is a good idea to put these co in separate functions. For example, the following contrived function returns an array of a randomly-chosen type: -```jldoctest; setup = :(using Random; srand(1234)) +```jldoctest; setup = :(using Random; Random.seed!(1234)) julia> function strange_twos(n) a = Vector{rand(Bool) ? Int64 : Float64}(undef, n) for i = 1:n @@ -601,7 +601,7 @@ julia> strange_twos(3) This should be written as: -```jldoctest; setup = :(using Random; srand(1234)) +```jldoctest; setup = :(using Random; Random.seed!(1234)) julia> function fill_twos!(a) for i = eachindex(a) a[i] = 2 diff --git a/codex/manual/types.md b/codex/manual/types.md index 08de781..138669a 100644 --- a/codex/manual/types.md +++ b/codex/manual/types.md @@ -452,8 +452,8 @@ To recap, two essential properties define immutability in Julia: ## Declared Types -The three kinds of types discussed in the previous three sections are actually all closely related. -They share the same key properties: +The three kinds of types (abstract, primitive, composite) discussed in the previous +sections are actually all closely related. They share the same key properties: * They are explicitly declared. * They have names. diff --git a/codex/stdlib/Pkg.md b/codex/stdlib/Pkg.md index 93cf971..571f4f1 100644 --- a/codex/stdlib/Pkg.md +++ b/codex/stdlib/Pkg.md @@ -193,6 +193,9 @@ Since we haven't created our own project yet, we are in the default project, loc To return to the `julia>` prompt, either press backspace when the input line is empty or press Ctrl+C. Help is available by calling `pkg> help`. +If you are in an environment that does not have access to a REPL you can still use the REPL mode commands using +the string macro `pkg` available after `using Pkg`. The command `pkg"cmd"` would be equivalent to executing `cmd` +in the REPL mode. The documentation here describes using Pkg from the REPL mode. Documentation of using the Pkg API (by calling `Pkg.` functions) is in progress of being written. @@ -356,6 +359,7 @@ Note the info message saying that it is using the existing path. This means that an already developed package. If `dev` is used on a local path, that path to that package is recorded and used when loading that package. +The path will be recorded relative to the project file, unless it is given as an absolute path. To stop tracking a path and use the registered version again, use `free` @@ -689,13 +693,18 @@ Testing... #### Test-specific dependencies -Sometimes one might want to use some packages only at testing time but not enforce a dependency on them when the package is used. -This is possible by adding dependencies to a "test target" to the Project file. Here we add the `Test` standard library as a -test-only dependency by adding the following to the Project file: +Sometimes one might want to use some packages only at testing time but not +enforce a dependency on them when the package is used. This is possible by +adding `[extra]` dependencies and adding a a "test target" to the Project file. +Here we add the `Test` standard library as a test-only dependency by adding the +following to the Project file: ``` -[targets.test.deps] +[extras] Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[targets] +test = ["Test"] ``` We can now use `Test` in the test script and we can see that it gets installed on testing: @@ -826,3 +835,30 @@ Simply clone their project using e.g. `git clone`, `cd` to the project directory If the project contains a manifest, this will install the packages in the same state that is given by that manifest. Otherwise, it will resolve the latest versions of the dependencies compatible with the project. + +## References + +This section describes the "API mode" of interacting with Pkg.jl which is recommended for non-interactive usage, +in i.e. scripts. In the REPL mode packages (with associated version, UUID, URL etc) are parsed from strings, +for example, `"Package#master"`,`"Package@v0.1"`, `"www.mypkg.com/MyPkg#my/feature"`. +It is possible to use strings as arguments for simple commands in the API mode (like `Pkg.add(["PackageA", "PackageB"])`, +more complicated commands, that e.g. specify URLs or version range, uses a more structured format over strings. +This is done by creating an instance of a [`PackageSpec`](@ref) which are passed in to functions. + +```@docs +PackageSpec +PackageMode +UpgradeLevel +Pkg.add +Pkg.develop +Pkg.activate +Pkg.rm +Pkg.update +Pkg.test +Pkg.build +Pkg.pin +Pkg.free +Pkg.instantiate +Pkg.resolve +Pkg.setprotocol! +``` diff --git a/codex/stdlib/Random.md b/codex/stdlib/Random.md index a26e0bb..8e008e1 100644 --- a/codex/stdlib/Random.md +++ b/codex/stdlib/Random.md @@ -56,7 +56,7 @@ Random.shuffle! ## Generators (creation and seeding) ```@docs -Random.srand +Random.seed! Random.MersenneTwister Random.RandomDevice ``` diff --git a/src/NEWS.md b/src/NEWS.md index a480868..73fe8a7 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -787,7 +787,7 @@ Deprecated or removed `dims` keyword argument. This includes the functions `sum`, `prod`, `maximum`, `minimum`, `all`, `any`, `findmax`, `findmin`, `mean`, `varm`, `std`, `var`, `cov`, `cor`, `median`, `mapreducedim`, `reducedim`, `sort`, `accumulate`, `accumulate!`, - `cumsum`, `cumsum!`, `cumprod`, `cumprod!`, `flipdim`, `squeeze`, and `cat` ([#25501](https://github.com/JuliaLang/julia/issues/25501), [#26660](https://github.com/JuliaLang/julia/issues/26660), [#27100](https://github.com/JuliaLang/julia/issues/27100)). + `cumsum`, `cumsum!`, `cumprod`, `cumprod!`, `flipdim`, `dropdims`, and `cat` ([#25501](https://github.com/JuliaLang/julia/issues/25501), [#26660](https://github.com/JuliaLang/julia/issues/26660), [#27100](https://github.com/JuliaLang/julia/issues/27100)). * `indices(a)` and `indices(a,d)` have been deprecated in favor of `axes(a)` and `axes(a, d)` ([#25057](https://github.com/JuliaLang/julia/issues/25057)). @@ -1310,6 +1310,12 @@ Deprecated or removed * `ndigits(n, b, [pad])` is deprecated in favor of `ndigits(n, base=b, pad=pad)` ([#27908](https://github.com/JuliaLang/julia/issues/27908)). + * `squeeze` is deprecated in favor of `dropdims`. + + * `srand` is deprecated in favor of the unexported `Random.seed!` ([#27726](https://github.com/JuliaLang/julia/issues/27726)). + + * `realmin`/`realmax` are deprecated in favor of `floatmin`/`floatmax` ([#28302](https://github.com/JuliaLang/julia/issues/28302)). + Command-line option changes --------------------------- diff --git a/src/base/arrays.md b/src/base/arrays.md index f2bb0b9..421a527 100644 --- a/src/base/arrays.md +++ b/src/base/arrays.md @@ -105,7 +105,7 @@ Base.parentindices Base.selectdim Base.reinterpret Base.reshape -Base.squeeze +Base.dropdims Base.vec ``` diff --git a/src/base/base.md b/src/base/base.md index 36e47cc..d2a6dd1 100644 --- a/src/base/base.md +++ b/src/base/base.md @@ -162,8 +162,8 @@ Base.datatype_pointerfree ```@docs Base.typemin Base.typemax -Base.realmin -Base.realmax +Base.floatmin +Base.floatmax Base.maxintfloat Base.eps(::Type{<:AbstractFloat}) Base.eps(::AbstractFloat) diff --git a/src/base/collections.md b/src/base/collections.md index 0e1ece3..c070111 100644 --- a/src/base/collections.md +++ b/src/base/collections.md @@ -134,7 +134,6 @@ Base.collect(::Type, ::Any) Base.filter Base.filter! Base.replace(::Any, ::Pair...) -Base.replace(::Base.Callable, ::Any, ::Any) Base.replace(::Base.Callable, ::Any) Base.replace! ``` diff --git a/src/devdocs/llvm.md b/src/devdocs/llvm.md index 10af27f..9ed7da7 100644 --- a/src/devdocs/llvm.md +++ b/src/devdocs/llvm.md @@ -211,6 +211,11 @@ three different address spaces (their numbers are defined in `src/codegen_shared future), but unlike the other pointers need not be rooted if passed to a call (they do still need to be rooted if they are live across another safepoint between the definition and the call). +- Pointers loaded from tracked object (currently 13): This is used by arrays, + which themselves contain a pointer to the managed data. This data area is owned + by the array, but is not a GC-tracked object by itself. The compiler guarantees + that as long as this pointer is live, the object that this pointer was loaded + from will keep being live. ### Invariants diff --git a/src/devdocs/subarrays.md b/src/devdocs/subarrays.md index 657d8a8..6b91083 100644 --- a/src/devdocs/subarrays.md +++ b/src/devdocs/subarrays.md @@ -37,7 +37,7 @@ cartesian, rather than linear, indexing. Consider making 2d slices of a 3d array: ```@meta -DocTestSetup = :(import Random; Random.srand(1234)) +DocTestSetup = :(import Random; Random.seed!(1234)) ``` ```jldoctest subarray julia> A = rand(2,3,4); diff --git a/src/manual/methods.md b/src/manual/methods.md index 7e9cf0a..824694b 100644 --- a/src/manual/methods.md +++ b/src/manual/methods.md @@ -754,9 +754,13 @@ julia> function (p::Polynomial)(x) end return v end + +julia> (p::Polynomial)() = p(5) ``` -함수는 이름 대신 형식으로 지정됩니다. 함수 본문에서 `p` 는 호출 된 객체를 나타냅니다. `다항식` 은 다음과 같이 사용할 수 있습니다. +함수는 이름 대신 타입으로 지정됩니다. +As with normal functions there is a terse syntax form. +함수 본문에서 `p` 는 호출 된 객체를 나타냅니다. `다항식` 은 다음과 같이 사용할 수 있습니다: ```jldoctest polynomial julia> p = Polynomial([1,10,100]) @@ -764,6 +768,9 @@ Polynomial{Int64}([1, 10, 100]) julia> p(3) 931 + +julia> p() +2551 ``` 이 메카니즘은 타입 생성자와 클로저 (주변 환경을 참조하는 내부 함수)가 줄리아에서 어떻게 작동 하는지를 결정하는 열쇠이기도합니다. diff --git a/src/manual/parallel-computing.md b/src/manual/parallel-computing.md index a803696..5f18d97 100644 --- a/src/manual/parallel-computing.md +++ b/src/manual/parallel-computing.md @@ -418,7 +418,7 @@ julia> function g() end g (generic function with 1 method) -julia> srand(1); g() # the result for a single thread is 1000 +julia> Random.seed!(1); g() # the result for a single thread is 1000 781 ``` diff --git a/src/manual/performance-tips.md b/src/manual/performance-tips.md index c3fbc6f..cd81e9e 100644 --- a/src/manual/performance-tips.md +++ b/src/manual/performance-tips.md @@ -58,7 +58,7 @@ so all the performance issues discussed previously apply. A useful tool for measuring performance is the [`@time`](@ref) macro. We here repeat the example with the global variable above, but this time with the type annotation removed: -```jldoctest; setup = :(using Random; srand(1234)), filter = r"[0-9\.]+ seconds \(.*?\)" +```jldoctest; setup = :(using Random; Random.seed!(1234)), filter = r"[0-9\.]+ seconds \(.*?\)" julia> x = rand(1000); julia> function sum_global() @@ -94,7 +94,7 @@ If we instead pass `x` as an argument to the function it no longer allocates mem (the allocation reported below is due to running the `@time` macro in global scope) and is significantly faster after the first call: -```jldoctest sumarg; setup = :(using Random; srand(1234)), filter = r"[0-9\.]+ seconds \(.*?\)" +```jldoctest sumarg; setup = :(using Random; Random.seed!(1234)), filter = r"[0-9\.]+ seconds \(.*?\)" julia> x = rand(1000); julia> function sum_arg(x) @@ -583,7 +583,7 @@ to perform a core computation. Where possible, it is a good idea to put these co in separate functions. For example, the following contrived function returns an array of a randomly-chosen type: -```jldoctest; setup = :(using Random; srand(1234)) +```jldoctest; setup = :(using Random; Random.seed!(1234)) julia> function strange_twos(n) a = Vector{rand(Bool) ? Int64 : Float64}(undef, n) for i = 1:n @@ -601,7 +601,7 @@ julia> strange_twos(3) This should be written as: -```jldoctest; setup = :(using Random; srand(1234)) +```jldoctest; setup = :(using Random; Random.seed!(1234)) julia> function fill_twos!(a) for i = eachindex(a) a[i] = 2 diff --git a/src/manual/types.md b/src/manual/types.md index 08de781..138669a 100644 --- a/src/manual/types.md +++ b/src/manual/types.md @@ -452,8 +452,8 @@ To recap, two essential properties define immutability in Julia: ## Declared Types -The three kinds of types discussed in the previous three sections are actually all closely related. -They share the same key properties: +The three kinds of types (abstract, primitive, composite) discussed in the previous +sections are actually all closely related. They share the same key properties: * They are explicitly declared. * They have names. diff --git a/src/stdlib/Pkg.md b/src/stdlib/Pkg.md index 93cf971..571f4f1 100644 --- a/src/stdlib/Pkg.md +++ b/src/stdlib/Pkg.md @@ -193,6 +193,9 @@ Since we haven't created our own project yet, we are in the default project, loc To return to the `julia>` prompt, either press backspace when the input line is empty or press Ctrl+C. Help is available by calling `pkg> help`. +If you are in an environment that does not have access to a REPL you can still use the REPL mode commands using +the string macro `pkg` available after `using Pkg`. The command `pkg"cmd"` would be equivalent to executing `cmd` +in the REPL mode. The documentation here describes using Pkg from the REPL mode. Documentation of using the Pkg API (by calling `Pkg.` functions) is in progress of being written. @@ -356,6 +359,7 @@ Note the info message saying that it is using the existing path. This means that an already developed package. If `dev` is used on a local path, that path to that package is recorded and used when loading that package. +The path will be recorded relative to the project file, unless it is given as an absolute path. To stop tracking a path and use the registered version again, use `free` @@ -689,13 +693,18 @@ Testing... #### Test-specific dependencies -Sometimes one might want to use some packages only at testing time but not enforce a dependency on them when the package is used. -This is possible by adding dependencies to a "test target" to the Project file. Here we add the `Test` standard library as a -test-only dependency by adding the following to the Project file: +Sometimes one might want to use some packages only at testing time but not +enforce a dependency on them when the package is used. This is possible by +adding `[extra]` dependencies and adding a a "test target" to the Project file. +Here we add the `Test` standard library as a test-only dependency by adding the +following to the Project file: ``` -[targets.test.deps] +[extras] Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[targets] +test = ["Test"] ``` We can now use `Test` in the test script and we can see that it gets installed on testing: @@ -826,3 +835,30 @@ Simply clone their project using e.g. `git clone`, `cd` to the project directory If the project contains a manifest, this will install the packages in the same state that is given by that manifest. Otherwise, it will resolve the latest versions of the dependencies compatible with the project. + +## References + +This section describes the "API mode" of interacting with Pkg.jl which is recommended for non-interactive usage, +in i.e. scripts. In the REPL mode packages (with associated version, UUID, URL etc) are parsed from strings, +for example, `"Package#master"`,`"Package@v0.1"`, `"www.mypkg.com/MyPkg#my/feature"`. +It is possible to use strings as arguments for simple commands in the API mode (like `Pkg.add(["PackageA", "PackageB"])`, +more complicated commands, that e.g. specify URLs or version range, uses a more structured format over strings. +This is done by creating an instance of a [`PackageSpec`](@ref) which are passed in to functions. + +```@docs +PackageSpec +PackageMode +UpgradeLevel +Pkg.add +Pkg.develop +Pkg.activate +Pkg.rm +Pkg.update +Pkg.test +Pkg.build +Pkg.pin +Pkg.free +Pkg.instantiate +Pkg.resolve +Pkg.setprotocol! +``` diff --git a/src/stdlib/Random.md b/src/stdlib/Random.md index a26e0bb..8e008e1 100644 --- a/src/stdlib/Random.md +++ b/src/stdlib/Random.md @@ -56,7 +56,7 @@ Random.shuffle! ## Generators (creation and seeding) ```@docs -Random.srand +Random.seed! Random.MersenneTwister Random.RandomDevice ``` From 40d0dd338f1a43e1671cf07b3e84fc55b14a9a82 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Wed, 1 Aug 2018 22:09:00 +0900 Subject: [PATCH 049/153] update Julia Commit 0ef882679f --- codex/NEWS.md | 40 +++++++++++++++++++- codex/base/base.md | 1 + codex/base/math.md | 2 - codex/base/sort.md | 3 +- codex/devdocs/functions.md | 77 ++++++++++++++++++++------------------ codex/manual/modules.md | 45 +++++++++++----------- codex/stdlib/Random.md | 4 +- src/NEWS.md | 40 +++++++++++++++++++- src/base/base.md | 1 + src/base/math.md | 2 - src/base/sort.md | 3 +- src/devdocs/functions.md | 77 ++++++++++++++++++++------------------ src/manual/modules.md | 45 +++++++++++----------- src/stdlib/Random.md | 4 +- 14 files changed, 212 insertions(+), 132 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index 0e80da5..3e96e47 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -233,6 +233,10 @@ Language changes `size`, `length`, and `@inbounds`. To optionally enforce conventional indices, you can `@assert !has_offset_axes(A)`. + * Module pre-compilation is now the default for code loading. Adding a + `__precompile__()` declaration is no longer necessary, although + `__precompile__(false)` can still be used to opt-out ([#26991](https://github.com/JuliaLang/julia/issues/26991)). + Breaking changes ---------------- @@ -545,6 +549,8 @@ Library improvements * `Char` is now a subtype of `AbstractChar`, and most of the functions that take character arguments now accept any `AbstractChar` ([#26286](https://github.com/JuliaLang/julia/issues/26286)). + * `pathof(module)` returns the path a module was imported from ([#28310](https://github.com/JuliaLang/julia/issues/28310)). + * `bytes2hex` now accepts an optional `io` argument to output to a hexadecimal stream without allocating a `String` first ([#27121](https://github.com/JuliaLang/julia/issues/27121)). @@ -602,6 +608,10 @@ Library improvements * The function `rand` can now pick up random elements from strings, associatives and sets ([#22228](https://github.com/JuliaLang/julia/issues/22228), [#21960](https://github.com/JuliaLang/julia/issues/21960), [#18155](https://github.com/JuliaLang/julia/issues/18155), [#22224](https://github.com/JuliaLang/julia/issues/22224)). + * It's now possible to specify the characters to pick from in the `randstring` function ([#22222](https://github.com/JuliaLang/julia/issues/22222)). + + * Allow multidimensional arrays in `shuffle` and `shuffle!` functions ([#22226](https://github.com/JuliaLang/julia/issues/22226)). + * Method lists are now printed as a numbered list. In addition, the source code of a method can be opened in an editor by entering the corresponding number in the REPL and pressing `^Q` ([#22007](https://github.com/JuliaLang/julia/issues/22007)). @@ -648,6 +658,10 @@ Library improvements * `BigFloat` random numbers can now be generated ([#22720](https://github.com/JuliaLang/julia/issues/22720)). + * The efficiency of random generation for MersenneTwister RNGs has been improved for + integers, `Float64` and ranges; as a result, given a seed, the produced stream of numbers + has changed ([#27560](https://github.com/JuliaLang/julia/issues/27560), [#25277](https://github.com/JuliaLang/julia/issues/25277), [#25197](https://github.com/JuliaLang/julia/issues/25197), [#25058](https://github.com/JuliaLang/julia/issues/25058), [#25047](https://github.com/JuliaLang/julia/issues/25047)). + * REPL Undo via Ctrl-/ and Ctrl-_ * `diagm` now accepts several diagonal index/vector `Pair`s ([#24047](https://github.com/JuliaLang/julia/issues/24047)). @@ -682,8 +696,8 @@ Library improvements `permutedims(v::AbstractVector)` will create a row matrix ([#24839](https://github.com/JuliaLang/julia/issues/24839)). * A new `replace(A, old=>new)` function is introduced to replace `old` by `new` in - collection `A`. There are also two other methods with a different API, and - a mutating variant, `replace!` ([#22324](https://github.com/JuliaLang/julia/issues/22324)). + collection `A`. There is also another method with a different API, and + a mutating variant, `replace!` ([#22324](https://github.com/JuliaLang/julia/issues/22324), [#25697](https://github.com/JuliaLang/julia/issues/25697), [#26206](https://github.com/JuliaLang/julia/issues/26206), [#27944](https://github.com/JuliaLang/julia/issues/27944)). * Adding integers to `CartesianIndex` objects is now deprecated. Instead of `i::Int + x::CartesianIndex`, use `i*one(x) + x` ([#26284](https://github.com/JuliaLang/julia/issues/26284)). @@ -734,6 +748,13 @@ Library improvements * Added an optimized method of `kron` for taking the tensor product of two `Diagonal` matrices. ([27581]) + * An official API for extending `rand` is now defined ([#23964](https://github.com/JuliaLang/julia/issues/23964), [#25002](https://github.com/JuliaLang/julia/issues/25002)). + + * The constructor `MersenneTwister()` is re-enabled, producing a randomly initialized RNG + (similar to `Random.seed!(MersenneTwister(0))`) ([#21909](https://github.com/JuliaLang/julia/issues/21909)). + + * `BitSet` can now store any `Int` (instead of only positive ones) ([#25029](https://github.com/JuliaLang/julia/issues/25029)). + * The initial element `v0` in `reduce(op, v0, itr)` has been replaced with an `init` optional keyword argument, as in `reduce(op, itr; init=v0)`. Similarly for `foldl`, `foldr`, `mapreduce`, `mapfoldl`, `mapfoldr`, `accumulate` and `accumulate!`. @@ -755,6 +776,9 @@ Compiler/Runtime improvements * Inference now propagates constants inter-procedurally, and can compute various constants expressions at compile-time ([#24362](https://github.com/JuliaLang/julia/issues/24362)). + * The LLVM SLP Vectorizer optimization pass is now enabled at the default + optimization level. + Deprecated or removed --------------------- @@ -789,6 +813,14 @@ Deprecated or removed (`vals, vecs = eigen(A, B)`), or as a `GeneralizedEigen` object (`X = eigen(A, B)`) ([#26997](https://github.com/JuliaLang/julia/issues/26997), [#27159](https://github.com/JuliaLang/julia/issues/27159), [#27212](https://github.com/JuliaLang/julia/issues/27212)). + * `ordschur(T::StridedMatrix{Ty}, Z::StridedMatrix{Ty}, select::Union{Vector{Bool},BitVector})` + and `ordschur(S::StridedMatrix{Ty}, T::StridedMatrix{Ty}, Q::StridedMatrix{Ty}, + Z::StridedMatrix{Ty}, select::Union{Vector{Bool},BitVector})` and their respective + inplace versions have been deprecated. + Use `ordschur(schur::Schur, select::Union{Vector{Bool},BitVector})` and + `ordschur(gschur::GeneralizedSchur, select::Union{Vector{Bool},BitVector})` instead + ([#28155](https://github.com/JuliaLang/julia/issues/28155)). + * Indexing into multidimensional arrays with more than one index but fewer indices than there are dimensions is no longer permitted when those trailing dimensions have lengths greater than 1. Instead, reshape the array or add trailing indices so the dimensionality and number of indices @@ -1327,6 +1359,10 @@ Deprecated or removed * `realmin`/`realmax` are deprecated in favor of `floatmin`/`floatmax` ([#28302](https://github.com/JuliaLang/julia/issues/28302)). + * `sortrows`/`sortcols` have been deprecated in favor of the more general `sortslices`. + + * `nextpow2`/`prevpow2` have been deprecated in favor of the more general `nextpow`/`prevpow` functions. + Command-line option changes --------------------------- diff --git a/codex/base/base.md b/codex/base/base.md index d2a6dd1..3355492 100644 --- a/codex/base/base.md +++ b/codex/base/base.md @@ -332,6 +332,7 @@ Base.AsyncCondition(::Function) ```@docs Base.nameof(::Module) Base.parentmodule +Base.pathof(::Module) Base.moduleroot Base.@__MODULE__ Base.fullname diff --git a/codex/base/math.md b/codex/base/math.md index 0fa973d..57c1b5e 100644 --- a/codex/base/math.md +++ b/codex/base/math.md @@ -165,8 +165,6 @@ Base.gcd Base.lcm Base.gcdx Base.ispow2 -Base.nextpow2 -Base.prevpow2 Base.nextpow Base.prevpow Base.nextprod diff --git a/codex/base/sort.md b/codex/base/sort.md index ffb4725..a3c3b7c 100644 --- a/codex/base/sort.md +++ b/codex/base/sort.md @@ -111,8 +111,7 @@ Base.sort! Base.sort Base.sortperm Base.Sort.sortperm! -Base.Sort.sortrows -Base.Sort.sortcols +Base.Sort.sortslices ``` ## Order-Related Functions diff --git a/codex/devdocs/functions.md b/codex/devdocs/functions.md index d20db2f..0273f22 100644 --- a/codex/devdocs/functions.md +++ b/codex/devdocs/functions.md @@ -93,17 +93,9 @@ end ## Constructors -A constructor call is just a call to a type. The type of most types is `DataType`, so the method -table for `DataType` contains most constructor definitions. One wrinkle is the fallback definition -that makes all types callable via `convert`: - -```julia -(::Type{T})(args...) where {T} = convert(T, args...)::T -``` - -In this definition the function type is abstract, which is not normally supported. To make this -work, all subtypes of `Type` (`Type`, `UnionAll`, `Union`, and `DataType`) currently share -a method table via special arrangement. +A constructor call is just a call to a type. The method table for `Type` contains all +constructor definitions. All subtypes of `Type` (`Type`, `UnionAll`, `Union`, and `DataType`) +currently share a method table via special arrangement. ## Builtins @@ -133,11 +125,11 @@ Keyword arguments work by associating a special, hidden function object with eac that has definitions with keyword arguments. This function is called the "keyword argument sorter" or "keyword sorter", or "kwsorter", and is stored in the `kwsorter` field of `MethodTable` objects. Every definition in the kwsorter function has the same arguments as some definition in the normal -method table, except with a single `Array` argument prepended. This array contains alternating -symbols and values that represent the passed keyword arguments. The kwsorter's job is to move -keyword arguments into their canonical positions based on name, plus evaluate and substitute any -needed default value expressions. The result is a normal positional argument list, which is then -passed to yet another function. +method table, except with a single `NamedTuple` argument prepended, which gives +the names and values of passed keyword arguments. The kwsorter's job is to move keyword arguments +into their canonical positions based on name, plus evaluate and substitute any needed default value +expressions. The result is a normal positional argument list, which is then passed to yet another +compiler-generated function. The easiest way to understand the process is to look at how a keyword argument method definition is lowered. The code: @@ -149,8 +141,8 @@ end ``` actually produces *three* method definitions. The first is a function that accepts all arguments -(including keywords) as positional arguments, and includes the code for the method body. It has -an auto-generated name: +(including keyword arguments) as positional arguments, and includes the code for the method body. +It has an auto-generated name: ```julia function #circle#1(color, fill::Bool, options, circle, center, radius) @@ -163,27 +155,38 @@ the case where no keyword arguments are passed: ```julia function circle(center, radius) - #circle#1(black, true, Any[], circle, center, radius) + #circle#1(black, true, pairs(NamedTuple()), circle, center, radius) end ``` -This simply dispatches to the first method, passing along default values. Finally there is the -kwsorter definition: +This simply dispatches to the first method, passing along default values. +`pairs` is applied to the named tuple of rest arguments to provide key-value pair iteration. +Note that if the method doesn't accept rest keyword arguments then this argument +is absent. + +Finally there is the kwsorter definition: ``` -function (::Core.kwftype(typeof(circle)))(kw::Array, circle, center, radius) - options = Any[] - color = arg associated with :color, or black if not found - fill = arg associated with :fill, or true if not found - # push remaining elements of kw into options array - #circle#1(color, fill, options, circle, center, radius) +function (::Core.kwftype(typeof(circle)))(kws, circle, center, radius) + if haskey(kws, :color) + color = kws.color + else + color = black + end + # etc. + + # put remaining kwargs in `options` + options = structdiff(kws, NamedTuple{(:color, :fill)}) + + # if the method doesn't accept rest keywords, throw an error + # unless `options` is empty + + #circle#1(color, fill, pairs(options), circle, center, radius) end ``` -The front end generates code to loop over the `kw` array and pick out arguments in the right order, -evaluating default expressions when an argument is not found. - -The function `Core.kwftype(t)` fetches (and creates, if necessary) the field `t.name.mt.kwsorter`. +The function `Core.kwftype(t)` creates the field `t.name.mt.kwsorter` (if it hasn't been created +yet), and returns the type of that function. This design has the feature that call sites that don't use keyword arguments require no special handling; everything works as if they were not part of the language at all. Call sites that do @@ -197,13 +200,15 @@ circle((0,0), 1.0, color = red; other...) is lowered to: ```julia -kwfunc(circle)(Any[:color,red,other...], circle, (0,0), 1.0) +kwfunc(circle)(merge((color = red,), other), circle, (0,0), 1.0) ``` -The unpacking procedure represented here as `other...` actually further unpacks each *element* -of `other`, expecting each one to contain two values (a symbol and a value). `kwfunc` (also in -`Core`) fetches the kwsorter for the called function. Notice that the original `circle` function -is passed through, to handle closures. + `kwfunc` (also in`Core`) fetches the kwsorter for the called function. +The keyword splatting operation (written as `other...`) calls the named tuple `merge` function. +This function further unpacks each *element* of `other`, expecting each one to contain two values +(a symbol and a value). +Naturally, a more efficient implementation is available if all splatted arguments are named tuples. +Notice that the original `circle` function is passed through, to handle closures. ## Compiler efficiency issues diff --git a/codex/manual/modules.md b/codex/manual/modules.md index c6c6840..7406560 100644 --- a/codex/manual/modules.md +++ b/codex/manual/modules.md @@ -217,14 +217,14 @@ This prevents name conflicts for globals initialized after load time. ### Module initialization and precompilation Large modules can take several seconds to load because executing all of the statements in a module -often involves compiling a large amount of code. Julia provides the ability to create precompiled -versions of modules to reduce this time. +often involves compiling a large amount of code. +Julia creates precompiled caches of the module to reduce this time. -To create an incremental precompiled module file, add `__precompile__()` at the top of your module -file (before the `module` starts). This will cause it to be automatically compiled the first time +The incremental precompiled module file are created and used automatically when using `import` +or `using` to load a module. This will cause it to be automatically compiled the first time it is imported. Alternatively, you can manually call `Base.compilecache(modulename)`. The resulting cache files will be stored in `DEPOT_PATH[1]/compiled/`. Subsequently, the module is automatically -recompiled upon `import` whenever any of its dependencies change; dependencies are modules it +recompiled upon `using` or `import` whenever any of its dependencies change; dependencies are modules it imports, the Julia build, files it includes, or explicit dependencies declared by `include_dependency(path)` in the module file(s). @@ -240,20 +240,22 @@ incompatibilities between the running system and the precompile cache. If you wa to the source reflected in the running system, you should call `reload("Module")` on the module you changed, and any module that depended on it in which you want to see the change reflected. -Precompiling a module also recursively precompiles any modules that are imported therein. If you -know that it is *not* safe to precompile your module (for the reasons described below), you should -put `__precompile__(false)` in the module file to cause `Base.compilecache` to throw an error -(and thereby prevent the module from being imported by any other precompiled module). - -`__precompile__()` should *not* be used in a module unless all of its dependencies are also using -`__precompile__()`. Failure to do so can result in a runtime error when loading the module. - -In order to make your module work with precompilation, however, you may need to change your module -to explicitly separate any initialization steps that must occur at *runtime* from steps that can -occur at *compile time*. For this purpose, Julia allows you to define an `__init__()` function -in your module that executes any initialization steps that must occur at runtime. This function -will not be called during compilation (`--output-*` or `__precompile__()`). You may, of course, -call it manually if necessary, but the default is to assume this function deals with computing +If you know that a module is *not* safe to precompile your module +(for example, for one of the reasons described below), you should +put `__precompile__(false)` in the module file (typically placed at the top). +This will cause `Base.compilecache` to throw an error, and will cause `using` / `import` to load it +directly into the current process and skip the precompile and caching. +This also thereby prevents the module from being imported by any other precompiled module. + +You may need to be aware of certain behaviors inherent in the creation of incremental shared libraries +which may require care when writing your module. For example, external state is not preserved. +To accommodate this, explicitly separate any initialization steps that must occur at *runtime* +from steps that can occur at *compile time*. +For this purpose, Julia allows you to define an `__init__()` function in your module that executes +any initialization steps that must occur at runtime. +This function will not be called during compilation (`--output-*`). +Effectively, you can assume it will be run exactly once in the lifetime of the code. +You may, of course, call it manually if necessary, but the default is to assume this function deals with computing state for the local machine, which does not need to be – or even should not be – captured in the compiled image. It will be called after the module is loaded into a process, including if it is being loaded into an incremental compile (`--output-incremental=yes`), but not if it @@ -382,6 +384,5 @@ It is sometimes helpful during module development to turn off incremental precom command line flag `--compiled-modules={yes|no}` enables you to toggle module precompilation on and off. When Julia is started with `--compiled-modules=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, -updating, and explicitly building packages. +manually. The state of this command line flag is passed to `Pkg.build` to disable automatic +precompilation triggering when installing, updating, and explicitly building packages. diff --git a/codex/stdlib/Random.md b/codex/stdlib/Random.md index 8e008e1..d150b53 100644 --- a/codex/stdlib/Random.md +++ b/codex/stdlib/Random.md @@ -101,7 +101,7 @@ Random.rand(rng::AbstractRNG, ::Random.SamplerType{Die}) = Die(rand(rng, 4:20)) Scalar and array methods for `Die` now work as expected: -```jldoctest Die; setup = :(srand(1)) +```jldoctest Die; setup = :(Random.seed!(1)) julia> rand(Die) Die(18) @@ -128,7 +128,7 @@ In order to define random generation out of objects of type `S`, the following m `rand(rng::AbstractRNG, sp::Random.SamplerTrivial{S})`. Here, `sp` simply wraps an object of type `S`, which can be accessed via `sp[]`. Continuing the `Die` example, we want now to define `rand(d::Die)` to produce an `Int` corresponding to one of `d`'s sides: -```jldoctest Die; setup = :(srand(1)) +```jldoctest Die; setup = :(Random.seed!(1)) julia> Random.rand(rng::AbstractRNG, d::Random.SamplerTrivial{Die}) = rand(rng, 1:d[].nsides); julia> rand(Die(4)) diff --git a/src/NEWS.md b/src/NEWS.md index 73fe8a7..740f802 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -221,6 +221,10 @@ Language changes `size`, `length`, and `@inbounds`. To optionally enforce conventional indices, you can `@assert !has_offset_axes(A)`. + * Module pre-compilation is now the default for code loading. Adding a + `__precompile__()` declaration is no longer necessary, although + `__precompile__(false)` can still be used to opt-out ([#26991](https://github.com/JuliaLang/julia/issues/26991)). + Breaking changes ---------------- @@ -534,6 +538,8 @@ Library improvements * `Char` is now a subtype of `AbstractChar`, and most of the functions that take character arguments now accept any `AbstractChar` ([#26286](https://github.com/JuliaLang/julia/issues/26286)). + * `pathof(module)` returns the path a module was imported from ([#28310](https://github.com/JuliaLang/julia/issues/28310)). + * `bytes2hex` now accepts an optional `io` argument to output to a hexadecimal stream without allocating a `String` first ([#27121](https://github.com/JuliaLang/julia/issues/27121)). @@ -591,6 +597,10 @@ Library improvements * The function `rand` can now pick up random elements from strings, associatives and sets ([#22228](https://github.com/JuliaLang/julia/issues/22228), [#21960](https://github.com/JuliaLang/julia/issues/21960), [#18155](https://github.com/JuliaLang/julia/issues/18155), [#22224](https://github.com/JuliaLang/julia/issues/22224)). + * It's now possible to specify the characters to pick from in the `randstring` function ([#22222](https://github.com/JuliaLang/julia/issues/22222)). + + * Allow multidimensional arrays in `shuffle` and `shuffle!` functions ([#22226](https://github.com/JuliaLang/julia/issues/22226)). + * Method lists are now printed as a numbered list. In addition, the source code of a method can be opened in an editor by entering the corresponding number in the REPL and pressing `^Q` ([#22007](https://github.com/JuliaLang/julia/issues/22007)). @@ -637,6 +647,10 @@ Library improvements * `BigFloat` random numbers can now be generated ([#22720](https://github.com/JuliaLang/julia/issues/22720)). + * The efficiency of random generation for MersenneTwister RNGs has been improved for + integers, `Float64` and ranges; as a result, given a seed, the produced stream of numbers + has changed ([#27560](https://github.com/JuliaLang/julia/issues/27560), [#25277](https://github.com/JuliaLang/julia/issues/25277), [#25197](https://github.com/JuliaLang/julia/issues/25197), [#25058](https://github.com/JuliaLang/julia/issues/25058), [#25047](https://github.com/JuliaLang/julia/issues/25047)). + * REPL Undo via Ctrl-/ and Ctrl-_ * `diagm` now accepts several diagonal index/vector `Pair`s ([#24047](https://github.com/JuliaLang/julia/issues/24047)). @@ -671,8 +685,8 @@ Library improvements `permutedims(v::AbstractVector)` will create a row matrix ([#24839](https://github.com/JuliaLang/julia/issues/24839)). * A new `replace(A, old=>new)` function is introduced to replace `old` by `new` in - collection `A`. There are also two other methods with a different API, and - a mutating variant, `replace!` ([#22324](https://github.com/JuliaLang/julia/issues/22324)). + collection `A`. There is also another method with a different API, and + a mutating variant, `replace!` ([#22324](https://github.com/JuliaLang/julia/issues/22324), [#25697](https://github.com/JuliaLang/julia/issues/25697), [#26206](https://github.com/JuliaLang/julia/issues/26206), [#27944](https://github.com/JuliaLang/julia/issues/27944)). * Adding integers to `CartesianIndex` objects is now deprecated. Instead of `i::Int + x::CartesianIndex`, use `i*one(x) + x` ([#26284](https://github.com/JuliaLang/julia/issues/26284)). @@ -723,6 +737,13 @@ Library improvements * Added an optimized method of `kron` for taking the tensor product of two `Diagonal` matrices. ([27581]) + * An official API for extending `rand` is now defined ([#23964](https://github.com/JuliaLang/julia/issues/23964), [#25002](https://github.com/JuliaLang/julia/issues/25002)). + + * The constructor `MersenneTwister()` is re-enabled, producing a randomly initialized RNG + (similar to `Random.seed!(MersenneTwister(0))`) ([#21909](https://github.com/JuliaLang/julia/issues/21909)). + + * `BitSet` can now store any `Int` (instead of only positive ones) ([#25029](https://github.com/JuliaLang/julia/issues/25029)). + * The initial element `v0` in `reduce(op, v0, itr)` has been replaced with an `init` optional keyword argument, as in `reduce(op, itr; init=v0)`. Similarly for `foldl`, `foldr`, `mapreduce`, `mapfoldl`, `mapfoldr`, `accumulate` and `accumulate!`. @@ -744,6 +765,9 @@ Compiler/Runtime improvements * Inference now propagates constants inter-procedurally, and can compute various constants expressions at compile-time ([#24362](https://github.com/JuliaLang/julia/issues/24362)). + * The LLVM SLP Vectorizer optimization pass is now enabled at the default + optimization level. + Deprecated or removed --------------------- @@ -778,6 +802,14 @@ Deprecated or removed (`vals, vecs = eigen(A, B)`), or as a `GeneralizedEigen` object (`X = eigen(A, B)`) ([#26997](https://github.com/JuliaLang/julia/issues/26997), [#27159](https://github.com/JuliaLang/julia/issues/27159), [#27212](https://github.com/JuliaLang/julia/issues/27212)). + * `ordschur(T::StridedMatrix{Ty}, Z::StridedMatrix{Ty}, select::Union{Vector{Bool},BitVector})` + and `ordschur(S::StridedMatrix{Ty}, T::StridedMatrix{Ty}, Q::StridedMatrix{Ty}, + Z::StridedMatrix{Ty}, select::Union{Vector{Bool},BitVector})` and their respective + inplace versions have been deprecated. + Use `ordschur(schur::Schur, select::Union{Vector{Bool},BitVector})` and + `ordschur(gschur::GeneralizedSchur, select::Union{Vector{Bool},BitVector})` instead + ([#28155](https://github.com/JuliaLang/julia/issues/28155)). + * Indexing into multidimensional arrays with more than one index but fewer indices than there are dimensions is no longer permitted when those trailing dimensions have lengths greater than 1. Instead, reshape the array or add trailing indices so the dimensionality and number of indices @@ -1316,6 +1348,10 @@ Deprecated or removed * `realmin`/`realmax` are deprecated in favor of `floatmin`/`floatmax` ([#28302](https://github.com/JuliaLang/julia/issues/28302)). + * `sortrows`/`sortcols` have been deprecated in favor of the more general `sortslices`. + + * `nextpow2`/`prevpow2` have been deprecated in favor of the more general `nextpow`/`prevpow` functions. + Command-line option changes --------------------------- diff --git a/src/base/base.md b/src/base/base.md index d2a6dd1..3355492 100644 --- a/src/base/base.md +++ b/src/base/base.md @@ -332,6 +332,7 @@ Base.AsyncCondition(::Function) ```@docs Base.nameof(::Module) Base.parentmodule +Base.pathof(::Module) Base.moduleroot Base.@__MODULE__ Base.fullname diff --git a/src/base/math.md b/src/base/math.md index 0fa973d..57c1b5e 100644 --- a/src/base/math.md +++ b/src/base/math.md @@ -165,8 +165,6 @@ Base.gcd Base.lcm Base.gcdx Base.ispow2 -Base.nextpow2 -Base.prevpow2 Base.nextpow Base.prevpow Base.nextprod diff --git a/src/base/sort.md b/src/base/sort.md index ffb4725..a3c3b7c 100644 --- a/src/base/sort.md +++ b/src/base/sort.md @@ -111,8 +111,7 @@ Base.sort! Base.sort Base.sortperm Base.Sort.sortperm! -Base.Sort.sortrows -Base.Sort.sortcols +Base.Sort.sortslices ``` ## Order-Related Functions diff --git a/src/devdocs/functions.md b/src/devdocs/functions.md index d20db2f..0273f22 100644 --- a/src/devdocs/functions.md +++ b/src/devdocs/functions.md @@ -93,17 +93,9 @@ end ## Constructors -A constructor call is just a call to a type. The type of most types is `DataType`, so the method -table for `DataType` contains most constructor definitions. One wrinkle is the fallback definition -that makes all types callable via `convert`: - -```julia -(::Type{T})(args...) where {T} = convert(T, args...)::T -``` - -In this definition the function type is abstract, which is not normally supported. To make this -work, all subtypes of `Type` (`Type`, `UnionAll`, `Union`, and `DataType`) currently share -a method table via special arrangement. +A constructor call is just a call to a type. The method table for `Type` contains all +constructor definitions. All subtypes of `Type` (`Type`, `UnionAll`, `Union`, and `DataType`) +currently share a method table via special arrangement. ## Builtins @@ -133,11 +125,11 @@ Keyword arguments work by associating a special, hidden function object with eac that has definitions with keyword arguments. This function is called the "keyword argument sorter" or "keyword sorter", or "kwsorter", and is stored in the `kwsorter` field of `MethodTable` objects. Every definition in the kwsorter function has the same arguments as some definition in the normal -method table, except with a single `Array` argument prepended. This array contains alternating -symbols and values that represent the passed keyword arguments. The kwsorter's job is to move -keyword arguments into their canonical positions based on name, plus evaluate and substitute any -needed default value expressions. The result is a normal positional argument list, which is then -passed to yet another function. +method table, except with a single `NamedTuple` argument prepended, which gives +the names and values of passed keyword arguments. The kwsorter's job is to move keyword arguments +into their canonical positions based on name, plus evaluate and substitute any needed default value +expressions. The result is a normal positional argument list, which is then passed to yet another +compiler-generated function. The easiest way to understand the process is to look at how a keyword argument method definition is lowered. The code: @@ -149,8 +141,8 @@ end ``` actually produces *three* method definitions. The first is a function that accepts all arguments -(including keywords) as positional arguments, and includes the code for the method body. It has -an auto-generated name: +(including keyword arguments) as positional arguments, and includes the code for the method body. +It has an auto-generated name: ```julia function #circle#1(color, fill::Bool, options, circle, center, radius) @@ -163,27 +155,38 @@ the case where no keyword arguments are passed: ```julia function circle(center, radius) - #circle#1(black, true, Any[], circle, center, radius) + #circle#1(black, true, pairs(NamedTuple()), circle, center, radius) end ``` -This simply dispatches to the first method, passing along default values. Finally there is the -kwsorter definition: +This simply dispatches to the first method, passing along default values. +`pairs` is applied to the named tuple of rest arguments to provide key-value pair iteration. +Note that if the method doesn't accept rest keyword arguments then this argument +is absent. + +Finally there is the kwsorter definition: ``` -function (::Core.kwftype(typeof(circle)))(kw::Array, circle, center, radius) - options = Any[] - color = arg associated with :color, or black if not found - fill = arg associated with :fill, or true if not found - # push remaining elements of kw into options array - #circle#1(color, fill, options, circle, center, radius) +function (::Core.kwftype(typeof(circle)))(kws, circle, center, radius) + if haskey(kws, :color) + color = kws.color + else + color = black + end + # etc. + + # put remaining kwargs in `options` + options = structdiff(kws, NamedTuple{(:color, :fill)}) + + # if the method doesn't accept rest keywords, throw an error + # unless `options` is empty + + #circle#1(color, fill, pairs(options), circle, center, radius) end ``` -The front end generates code to loop over the `kw` array and pick out arguments in the right order, -evaluating default expressions when an argument is not found. - -The function `Core.kwftype(t)` fetches (and creates, if necessary) the field `t.name.mt.kwsorter`. +The function `Core.kwftype(t)` creates the field `t.name.mt.kwsorter` (if it hasn't been created +yet), and returns the type of that function. This design has the feature that call sites that don't use keyword arguments require no special handling; everything works as if they were not part of the language at all. Call sites that do @@ -197,13 +200,15 @@ circle((0,0), 1.0, color = red; other...) is lowered to: ```julia -kwfunc(circle)(Any[:color,red,other...], circle, (0,0), 1.0) +kwfunc(circle)(merge((color = red,), other), circle, (0,0), 1.0) ``` -The unpacking procedure represented here as `other...` actually further unpacks each *element* -of `other`, expecting each one to contain two values (a symbol and a value). `kwfunc` (also in -`Core`) fetches the kwsorter for the called function. Notice that the original `circle` function -is passed through, to handle closures. + `kwfunc` (also in`Core`) fetches the kwsorter for the called function. +The keyword splatting operation (written as `other...`) calls the named tuple `merge` function. +This function further unpacks each *element* of `other`, expecting each one to contain two values +(a symbol and a value). +Naturally, a more efficient implementation is available if all splatted arguments are named tuples. +Notice that the original `circle` function is passed through, to handle closures. ## Compiler efficiency issues diff --git a/src/manual/modules.md b/src/manual/modules.md index c6c6840..7406560 100644 --- a/src/manual/modules.md +++ b/src/manual/modules.md @@ -217,14 +217,14 @@ This prevents name conflicts for globals initialized after load time. ### Module initialization and precompilation Large modules can take several seconds to load because executing all of the statements in a module -often involves compiling a large amount of code. Julia provides the ability to create precompiled -versions of modules to reduce this time. +often involves compiling a large amount of code. +Julia creates precompiled caches of the module to reduce this time. -To create an incremental precompiled module file, add `__precompile__()` at the top of your module -file (before the `module` starts). This will cause it to be automatically compiled the first time +The incremental precompiled module file are created and used automatically when using `import` +or `using` to load a module. This will cause it to be automatically compiled the first time it is imported. Alternatively, you can manually call `Base.compilecache(modulename)`. The resulting cache files will be stored in `DEPOT_PATH[1]/compiled/`. Subsequently, the module is automatically -recompiled upon `import` whenever any of its dependencies change; dependencies are modules it +recompiled upon `using` or `import` whenever any of its dependencies change; dependencies are modules it imports, the Julia build, files it includes, or explicit dependencies declared by `include_dependency(path)` in the module file(s). @@ -240,20 +240,22 @@ incompatibilities between the running system and the precompile cache. If you wa to the source reflected in the running system, you should call `reload("Module")` on the module you changed, and any module that depended on it in which you want to see the change reflected. -Precompiling a module also recursively precompiles any modules that are imported therein. If you -know that it is *not* safe to precompile your module (for the reasons described below), you should -put `__precompile__(false)` in the module file to cause `Base.compilecache` to throw an error -(and thereby prevent the module from being imported by any other precompiled module). - -`__precompile__()` should *not* be used in a module unless all of its dependencies are also using -`__precompile__()`. Failure to do so can result in a runtime error when loading the module. - -In order to make your module work with precompilation, however, you may need to change your module -to explicitly separate any initialization steps that must occur at *runtime* from steps that can -occur at *compile time*. For this purpose, Julia allows you to define an `__init__()` function -in your module that executes any initialization steps that must occur at runtime. This function -will not be called during compilation (`--output-*` or `__precompile__()`). You may, of course, -call it manually if necessary, but the default is to assume this function deals with computing +If you know that a module is *not* safe to precompile your module +(for example, for one of the reasons described below), you should +put `__precompile__(false)` in the module file (typically placed at the top). +This will cause `Base.compilecache` to throw an error, and will cause `using` / `import` to load it +directly into the current process and skip the precompile and caching. +This also thereby prevents the module from being imported by any other precompiled module. + +You may need to be aware of certain behaviors inherent in the creation of incremental shared libraries +which may require care when writing your module. For example, external state is not preserved. +To accommodate this, explicitly separate any initialization steps that must occur at *runtime* +from steps that can occur at *compile time*. +For this purpose, Julia allows you to define an `__init__()` function in your module that executes +any initialization steps that must occur at runtime. +This function will not be called during compilation (`--output-*`). +Effectively, you can assume it will be run exactly once in the lifetime of the code. +You may, of course, call it manually if necessary, but the default is to assume this function deals with computing state for the local machine, which does not need to be – or even should not be – captured in the compiled image. It will be called after the module is loaded into a process, including if it is being loaded into an incremental compile (`--output-incremental=yes`), but not if it @@ -382,6 +384,5 @@ It is sometimes helpful during module development to turn off incremental precom command line flag `--compiled-modules={yes|no}` enables you to toggle module precompilation on and off. When Julia is started with `--compiled-modules=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, -updating, and explicitly building packages. +manually. The state of this command line flag is passed to `Pkg.build` to disable automatic +precompilation triggering when installing, updating, and explicitly building packages. diff --git a/src/stdlib/Random.md b/src/stdlib/Random.md index 8e008e1..d150b53 100644 --- a/src/stdlib/Random.md +++ b/src/stdlib/Random.md @@ -101,7 +101,7 @@ Random.rand(rng::AbstractRNG, ::Random.SamplerType{Die}) = Die(rand(rng, 4:20)) Scalar and array methods for `Die` now work as expected: -```jldoctest Die; setup = :(srand(1)) +```jldoctest Die; setup = :(Random.seed!(1)) julia> rand(Die) Die(18) @@ -128,7 +128,7 @@ In order to define random generation out of objects of type `S`, the following m `rand(rng::AbstractRNG, sp::Random.SamplerTrivial{S})`. Here, `sp` simply wraps an object of type `S`, which can be accessed via `sp[]`. Continuing the `Die` example, we want now to define `rand(d::Die)` to produce an `Int` corresponding to one of `d`'s sides: -```jldoctest Die; setup = :(srand(1)) +```jldoctest Die; setup = :(Random.seed!(1)) julia> Random.rand(rng::AbstractRNG, d::Random.SamplerTrivial{Die}) = rand(rng, 1:d[].nsides); julia> rand(Die(4)) From 186f0981daa8f6568be3fddd7390a82a34eae697 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Tue, 7 Aug 2018 18:33:46 +0900 Subject: [PATCH 050/153] update Julia Commit 60cf688a3d --- codex/base/arrays.md | 4 ++++ codex/base/base.md | 1 - codex/base/c.md | 2 ++ codex/base/file.md | 1 + codex/base/math.md | 1 + codex/manual/arrays.md | 2 +- codex/manual/calling-c-and-fortran-code.md | 6 +++--- codex/manual/environment-variables.md | 5 ----- codex/manual/mathematical-operations.md | 8 ++++---- codex/manual/types.md | 2 +- codex/stdlib/Pkg.md | 11 ++++------- src/base/arrays.md | 4 ++++ src/base/base.md | 1 - src/base/c.md | 2 ++ src/base/file.md | 1 + src/base/math.md | 1 + src/manual/arrays.md | 2 +- src/manual/calling-c-and-fortran-code.md | 6 +++--- src/manual/environment-variables.md | 5 ----- src/manual/mathematical-operations.md | 8 ++++---- src/manual/types.md | 2 +- src/stdlib/Pkg.md | 11 ++++------- 22 files changed, 42 insertions(+), 44 deletions(-) diff --git a/codex/base/arrays.md b/codex/base/arrays.md index 421a527..521cbc2 100644 --- a/codex/base/arrays.md +++ b/codex/base/arrays.md @@ -26,6 +26,10 @@ Core.DenseArray Base.DenseVector Base.DenseMatrix Base.DenseVecOrMat +Base.StridedArray +Base.StridedVector +Base.StridedMatrix +Base.StridedVecOrMat Base.getindex(::Type, ::Any...) Base.zeros Base.ones diff --git a/codex/base/base.md b/codex/base/base.md index 3355492..6ba58b7 100644 --- a/codex/base/base.md +++ b/codex/base/base.md @@ -244,7 +244,6 @@ Base.process_exited Base.kill(::Base.Process, ::Integer) Base.Sys.set_process_title Base.Sys.get_process_title -Base.readandwrite Base.ignorestatus Base.detach Base.Cmd diff --git a/codex/base/c.md b/codex/base/c.md index 7977dd2..df9143b 100644 --- a/codex/base/c.md +++ b/codex/base/c.md @@ -24,6 +24,7 @@ Core.Ref Base.Cchar Base.Cuchar Base.Cshort +Base.Cstring Base.Cushort Base.Cint Base.Cuint @@ -37,6 +38,7 @@ Base.Csize_t Base.Cssize_t Base.Cptrdiff_t Base.Cwchar_t +Base.Cwstring Base.Cfloat Base.Cdouble ``` diff --git a/codex/base/file.md b/codex/base/file.md index 26e9f9d..d2f57e2 100644 --- a/codex/base/file.md +++ b/codex/base/file.md @@ -12,6 +12,7 @@ Base.Filesystem.symlink Base.Filesystem.readlink Base.Filesystem.chmod Base.Filesystem.chown +Base.RawFD Base.stat Base.Filesystem.lstat Base.Filesystem.ctime diff --git a/codex/base/math.md b/codex/base/math.md index 57c1b5e..343c71f 100644 --- a/codex/base/math.md +++ b/codex/base/math.md @@ -119,6 +119,7 @@ Base.Rounding.RoundNearest Base.Rounding.RoundNearestTiesAway Base.Rounding.RoundNearestTiesUp Base.Rounding.RoundToZero +Base.Rounding.RoundFromZero Base.Rounding.RoundUp Base.Rounding.RoundDown Base.round(::Complex{<: AbstractFloat}, ::RoundingMode, ::RoundingMode) diff --git a/codex/manual/arrays.md b/codex/manual/arrays.md index a2f59b6..de54a61 100644 --- a/codex/manual/arrays.md +++ b/codex/manual/arrays.md @@ -835,7 +835,7 @@ provided, the memory layout must correspond in the same way to these strides. `D very specific example of a strided array where the elements are arranged contiguously, thus it provides its subtypes with the approporiate definition of `strides`. More concrete examples can be found within the [interface guide for strided arrays](@ref man-interface-strided-arrays). -`StridedVector` and `StridedMatrix` are convenient aliases for many of the builtin array types that +[`StridedVector`](@ref) and [`StridedMatrix`](@ref) are convenient aliases for many of the builtin array types that are considered strided arrays, allowing them to dispatch to select specialized implementations that call highly tuned and optimized BLAS and LAPACK functions using just the pointer and strides. diff --git a/codex/manual/calling-c-and-fortran-code.md b/codex/manual/calling-c-and-fortran-code.md index 44668ba..dfd82b4 100644 --- a/codex/manual/calling-c-and-fortran-code.md +++ b/codex/manual/calling-c-and-fortran-code.md @@ -287,7 +287,7 @@ First, a review of some relevant Julia type terminology: | `struct ...; end` | `nothing` | "Singleton" :: a Leaf Type or Struct with no fields. | | `(...)` or `tuple(...)` | `(1, 2, 3)` | "Tuple" :: an immutable data-structure similar to an anonymous struct type, or a constant array. Represented as either an array or a struct. | -### Bits Types: +### [Bits Types](@id man-bits-types) There are several special types to be aware of, as no other type can be defined to behave the same: @@ -374,7 +374,7 @@ an `Int` in Julia). | `va_arg` |   |   | Not supported | | `...` (variadic function specification) |   |   | `T...` (where `T` is one of the above types, variadic functions of different argument types are not supported) | -The `Cstring` type is essentially a synonym for `Ptr{UInt8}`, except the conversion to `Cstring` +The [`Cstring`](@ref) type is essentially a synonym for `Ptr{UInt8}`, except the conversion to `Cstring` throws an error if the Julia string contains any embedded NUL characters (which would cause the string to be silently truncated if the C routine treats NUL as the terminator). If you are passing a `char*` to a C routine that does not assume NUL termination (e.g. because you pass an explicit @@ -413,7 +413,7 @@ checks and is only meant to improve readability of the call. (`void`) but do return, use `Cvoid` instead. !!! note - For `wchar_t*` arguments, the Julia type should be `Cwstring` (if the C routine expects a NUL-terminated + For `wchar_t*` arguments, the Julia type should be [`Cwstring`](@ref) (if the C routine expects a NUL-terminated string) or `Ptr{Cwchar_t}` otherwise. Note also that UTF-8 string data in Julia is internally NUL-terminated, so it can be passed to C functions expecting NUL-terminated data without making a copy (but using the `Cwstring` type will cause an error to be thrown if the string itself contains diff --git a/codex/manual/environment-variables.md b/codex/manual/environment-variables.md index 853dd77..b27ff27 100644 --- a/codex/manual/environment-variables.md +++ b/codex/manual/environment-variables.md @@ -121,11 +121,6 @@ over `$EDITOR`. If none of these environment variables is set, then the editor is taken to be `open` on Windows and OS X, or `/etc/alternatives/editor` if it exists, or `emacs` otherwise. -!!! note - - `$JULIA_EDITOR` is *not* used in the determination of the editor for - `OldPkg.edit`: this function checks `$VISUAL` and `$EDITOR` alone. - ## Parallelization ### `JULIA_CPU_THREADS` diff --git a/codex/manual/mathematical-operations.md b/codex/manual/mathematical-operations.md index 456146a..6d451ea 100644 --- a/codex/manual/mathematical-operations.md +++ b/codex/manual/mathematical-operations.md @@ -356,11 +356,11 @@ Julia applies the following order and associativity of operations, from highest |:-------------- |:------------------------------------------------------------------------------------------------- |:-------------------------- | | Syntax | `.` followed by `::` | Left | | Exponentiation | `^` | Right | -| Unary | `+ - √` | Right[^1] | -| Fractions | `//` | Left | -| Multiplication | `* / % & \ ÷` | Left[^2] | +| Unary | `+ - √` | Right[^1] | | Bitshifts | `<< >> >>>` | Left | -| Addition | `+ - \| ⊻` | Left[^2] | +| Fractions | `//` | Left | +| Multiplication | `* / % & \ ÷` | Left[^2] | +| Addition | `+ - \| ⊻` | Left[^2] | | Syntax | `: ..` | Left | | Syntax | `\|>` | Left | | Syntax | `<\|` | Right | diff --git a/codex/manual/types.md b/codex/manual/types.md index 138669a..7cd8c58 100644 --- a/codex/manual/types.md +++ b/codex/manual/types.md @@ -657,7 +657,7 @@ For the default constructor, exactly one argument must be supplied for each fiel ```jldoctest pointtype julia> Point{Float64}(1.0) -ERROR: MethodError: Cannot `convert` an object of type Float64 to an object of type Point{Float64} +ERROR: MethodError: no method matching Point{Float64}(::Float64) [...] julia> Point{Float64}(1.0,2.0,3.0) diff --git a/codex/stdlib/Pkg.md b/codex/stdlib/Pkg.md index 571f4f1..7e01e44 100644 --- a/codex/stdlib/Pkg.md +++ b/codex/stdlib/Pkg.md @@ -1,8 +1,5 @@ # Pkg -!!! warning - This documentation is a work in progress and the information in it might be or become outdated. - ## Introduction Pkg is the standard package manager for Julia 1.0 and newer. Unlike traditional @@ -350,13 +347,13 @@ If we try to `dev` a package at some branch that already exists at `~/.julia/dev For example: ``` -(v0.7) pkg> dev Example#master +(v0.7) pkg> dev Example Updating git-repo `https://github.com/JuliaLang/Example.jl.git` [ Info: Path `/Users/kristoffer/.julia/dev/Example` exists and looks like the correct package, using existing path instead of cloning ``` -Note the info message saying that it is using the existing path. This means that you cannot use `dev` to e.g. change branches of -an already developed package. +Note the info message saying that it is using the existing path. As a general rule, the package manager will +never touch files that are tracking a path. If `dev` is used on a local path, that path to that package is recorded and used when loading that package. The path will be recorded relative to the project file, unless it is given as an absolute path. @@ -695,7 +692,7 @@ Testing... Sometimes one might want to use some packages only at testing time but not enforce a dependency on them when the package is used. This is possible by -adding `[extra]` dependencies and adding a a "test target" to the Project file. +adding dependencies to `[extras]` and a `test` target in `[targets]` to the Project file. Here we add the `Test` standard library as a test-only dependency by adding the following to the Project file: diff --git a/src/base/arrays.md b/src/base/arrays.md index 421a527..521cbc2 100644 --- a/src/base/arrays.md +++ b/src/base/arrays.md @@ -26,6 +26,10 @@ Core.DenseArray Base.DenseVector Base.DenseMatrix Base.DenseVecOrMat +Base.StridedArray +Base.StridedVector +Base.StridedMatrix +Base.StridedVecOrMat Base.getindex(::Type, ::Any...) Base.zeros Base.ones diff --git a/src/base/base.md b/src/base/base.md index 3355492..6ba58b7 100644 --- a/src/base/base.md +++ b/src/base/base.md @@ -244,7 +244,6 @@ Base.process_exited Base.kill(::Base.Process, ::Integer) Base.Sys.set_process_title Base.Sys.get_process_title -Base.readandwrite Base.ignorestatus Base.detach Base.Cmd diff --git a/src/base/c.md b/src/base/c.md index 7977dd2..df9143b 100644 --- a/src/base/c.md +++ b/src/base/c.md @@ -24,6 +24,7 @@ Core.Ref Base.Cchar Base.Cuchar Base.Cshort +Base.Cstring Base.Cushort Base.Cint Base.Cuint @@ -37,6 +38,7 @@ Base.Csize_t Base.Cssize_t Base.Cptrdiff_t Base.Cwchar_t +Base.Cwstring Base.Cfloat Base.Cdouble ``` diff --git a/src/base/file.md b/src/base/file.md index 26e9f9d..d2f57e2 100644 --- a/src/base/file.md +++ b/src/base/file.md @@ -12,6 +12,7 @@ Base.Filesystem.symlink Base.Filesystem.readlink Base.Filesystem.chmod Base.Filesystem.chown +Base.RawFD Base.stat Base.Filesystem.lstat Base.Filesystem.ctime diff --git a/src/base/math.md b/src/base/math.md index 57c1b5e..343c71f 100644 --- a/src/base/math.md +++ b/src/base/math.md @@ -119,6 +119,7 @@ Base.Rounding.RoundNearest Base.Rounding.RoundNearestTiesAway Base.Rounding.RoundNearestTiesUp Base.Rounding.RoundToZero +Base.Rounding.RoundFromZero Base.Rounding.RoundUp Base.Rounding.RoundDown Base.round(::Complex{<: AbstractFloat}, ::RoundingMode, ::RoundingMode) diff --git a/src/manual/arrays.md b/src/manual/arrays.md index 3d49470..451879e 100644 --- a/src/manual/arrays.md +++ b/src/manual/arrays.md @@ -780,7 +780,7 @@ provided, the memory layout must correspond in the same way to these strides. `D very specific example of a strided array where the elements are arranged contiguously, thus it provides its subtypes with the approporiate definition of `strides`. More concrete examples can be found within the [interface guide for strided arrays](@ref man-interface-strided-arrays). -`StridedVector` and `StridedMatrix` are convenient aliases for many of the builtin array types that +[`StridedVector`](@ref) and [`StridedMatrix`](@ref) are convenient aliases for many of the builtin array types that are considered strided arrays, allowing them to dispatch to select specialized implementations that call highly tuned and optimized BLAS and LAPACK functions using just the pointer and strides. diff --git a/src/manual/calling-c-and-fortran-code.md b/src/manual/calling-c-and-fortran-code.md index 44668ba..dfd82b4 100644 --- a/src/manual/calling-c-and-fortran-code.md +++ b/src/manual/calling-c-and-fortran-code.md @@ -287,7 +287,7 @@ First, a review of some relevant Julia type terminology: | `struct ...; end` | `nothing` | "Singleton" :: a Leaf Type or Struct with no fields. | | `(...)` or `tuple(...)` | `(1, 2, 3)` | "Tuple" :: an immutable data-structure similar to an anonymous struct type, or a constant array. Represented as either an array or a struct. | -### Bits Types: +### [Bits Types](@id man-bits-types) There are several special types to be aware of, as no other type can be defined to behave the same: @@ -374,7 +374,7 @@ an `Int` in Julia). | `va_arg` |   |   | Not supported | | `...` (variadic function specification) |   |   | `T...` (where `T` is one of the above types, variadic functions of different argument types are not supported) | -The `Cstring` type is essentially a synonym for `Ptr{UInt8}`, except the conversion to `Cstring` +The [`Cstring`](@ref) type is essentially a synonym for `Ptr{UInt8}`, except the conversion to `Cstring` throws an error if the Julia string contains any embedded NUL characters (which would cause the string to be silently truncated if the C routine treats NUL as the terminator). If you are passing a `char*` to a C routine that does not assume NUL termination (e.g. because you pass an explicit @@ -413,7 +413,7 @@ checks and is only meant to improve readability of the call. (`void`) but do return, use `Cvoid` instead. !!! note - For `wchar_t*` arguments, the Julia type should be `Cwstring` (if the C routine expects a NUL-terminated + For `wchar_t*` arguments, the Julia type should be [`Cwstring`](@ref) (if the C routine expects a NUL-terminated string) or `Ptr{Cwchar_t}` otherwise. Note also that UTF-8 string data in Julia is internally NUL-terminated, so it can be passed to C functions expecting NUL-terminated data without making a copy (but using the `Cwstring` type will cause an error to be thrown if the string itself contains diff --git a/src/manual/environment-variables.md b/src/manual/environment-variables.md index 853dd77..b27ff27 100644 --- a/src/manual/environment-variables.md +++ b/src/manual/environment-variables.md @@ -121,11 +121,6 @@ over `$EDITOR`. If none of these environment variables is set, then the editor is taken to be `open` on Windows and OS X, or `/etc/alternatives/editor` if it exists, or `emacs` otherwise. -!!! note - - `$JULIA_EDITOR` is *not* used in the determination of the editor for - `OldPkg.edit`: this function checks `$VISUAL` and `$EDITOR` alone. - ## Parallelization ### `JULIA_CPU_THREADS` diff --git a/src/manual/mathematical-operations.md b/src/manual/mathematical-operations.md index 456146a..6d451ea 100644 --- a/src/manual/mathematical-operations.md +++ b/src/manual/mathematical-operations.md @@ -356,11 +356,11 @@ Julia applies the following order and associativity of operations, from highest |:-------------- |:------------------------------------------------------------------------------------------------- |:-------------------------- | | Syntax | `.` followed by `::` | Left | | Exponentiation | `^` | Right | -| Unary | `+ - √` | Right[^1] | -| Fractions | `//` | Left | -| Multiplication | `* / % & \ ÷` | Left[^2] | +| Unary | `+ - √` | Right[^1] | | Bitshifts | `<< >> >>>` | Left | -| Addition | `+ - \| ⊻` | Left[^2] | +| Fractions | `//` | Left | +| Multiplication | `* / % & \ ÷` | Left[^2] | +| Addition | `+ - \| ⊻` | Left[^2] | | Syntax | `: ..` | Left | | Syntax | `\|>` | Left | | Syntax | `<\|` | Right | diff --git a/src/manual/types.md b/src/manual/types.md index 138669a..7cd8c58 100644 --- a/src/manual/types.md +++ b/src/manual/types.md @@ -657,7 +657,7 @@ For the default constructor, exactly one argument must be supplied for each fiel ```jldoctest pointtype julia> Point{Float64}(1.0) -ERROR: MethodError: Cannot `convert` an object of type Float64 to an object of type Point{Float64} +ERROR: MethodError: no method matching Point{Float64}(::Float64) [...] julia> Point{Float64}(1.0,2.0,3.0) diff --git a/src/stdlib/Pkg.md b/src/stdlib/Pkg.md index 571f4f1..7e01e44 100644 --- a/src/stdlib/Pkg.md +++ b/src/stdlib/Pkg.md @@ -1,8 +1,5 @@ # Pkg -!!! warning - This documentation is a work in progress and the information in it might be or become outdated. - ## Introduction Pkg is the standard package manager for Julia 1.0 and newer. Unlike traditional @@ -350,13 +347,13 @@ If we try to `dev` a package at some branch that already exists at `~/.julia/dev For example: ``` -(v0.7) pkg> dev Example#master +(v0.7) pkg> dev Example Updating git-repo `https://github.com/JuliaLang/Example.jl.git` [ Info: Path `/Users/kristoffer/.julia/dev/Example` exists and looks like the correct package, using existing path instead of cloning ``` -Note the info message saying that it is using the existing path. This means that you cannot use `dev` to e.g. change branches of -an already developed package. +Note the info message saying that it is using the existing path. As a general rule, the package manager will +never touch files that are tracking a path. If `dev` is used on a local path, that path to that package is recorded and used when loading that package. The path will be recorded relative to the project file, unless it is given as an absolute path. @@ -695,7 +692,7 @@ Testing... Sometimes one might want to use some packages only at testing time but not enforce a dependency on them when the package is used. This is possible by -adding `[extra]` dependencies and adding a a "test target" to the Project file. +adding dependencies to `[extras]` and a `test` target in `[targets]` to the Project file. Here we add the `Test` standard library as a test-only dependency by adding the following to the Project file: From 35bffef2c463f05d555cc37e42a22ae55e1fb9a7 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Sun, 12 Aug 2018 04:31:31 +0900 Subject: [PATCH 051/153] update Julia Commit 7cb8531a2b --- codex/NEWS.md | 1359 +-------------------------------------- codex/devdocs/object.md | 2 +- codex/index.md | 10 +- codex/manual/profile.md | 31 + codex/manual/types.md | 2 +- codex/stdlib/REPL.md | 18 +- make.jl | 2 +- src/NEWS.md | 1356 +------------------------------------- src/index.md | 11 +- src/manual/profile.md | 31 + src/manual/types.md | 2 +- src/stdlib/REPL.md | 18 +- tools/check_codex.jl | 2 +- 13 files changed, 105 insertions(+), 2739 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index 3e96e47..b77894e 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -1,1380 +1,27 @@ -Julia v0.7.0 Release Notes +Julia v1.0.0 Release Notes ========================== New language features --------------------- - * Local variables can be tested for being defined - using the new `@isdefined variable` macro ([#22281](https://github.com/JuliaLang/julia/issues/22281)). - - * Destructuring in function arguments: when an expression such as `(x, y)` is used as - a function argument name, the argument is unpacked into local variables `x` and `y` - as in the assignment `(x, y) = arg` ([#6614](https://github.com/JuliaLang/julia/issues/6614)). - - * Named tuples, with the syntax `(a=1, b=2)`. These behave very similarly to tuples, - except components can also be accessed by name using dot syntax `t.a` ([#22194](https://github.com/JuliaLang/julia/issues/22194)). - - * Keyword argument containers (`kw` in `f(; kw...)`) are now based on named tuples. Dictionary - functions like `haskey` and indexing can be used on them, and name-value pairs can be - iterated using `pairs(kw)`. `kw` can no longer contain multiple entries for the same - argument name ([#4916](https://github.com/JuliaLang/julia/issues/4916)). - - * Custom infix operators can now be defined by appending Unicode - combining marks, primes, and sub/superscripts to other operators. - For example, `+̂ₐ″` is parsed as an infix operator with the same - precedence as `+` ([#22089](https://github.com/JuliaLang/julia/issues/22089)). - - * The macro call syntax `@macroname[args]` is now available and is parsed - as `@macroname([args])` ([#23519](https://github.com/JuliaLang/julia/issues/23519)). - - * The construct `if @generated ...; else ...; end` can be used to provide both - `@generated` and normal implementations of part of a function. Surrounding code - will be common to both versions ([#23168](https://github.com/JuliaLang/julia/issues/23168)). - - * Added `⟂` (`\perp`) operator with comparison precedence ([#24404](https://github.com/JuliaLang/julia/issues/24404)). - - * The `missing` singleton object (of type `Missing`) has been added to represent - missing values ([#24653](https://github.com/JuliaLang/julia/issues/24653)). It propagates through standard operators and mathematical functions, - and implements three-valued logic, similar to SQLs `NULL` and R's `NA`. - - * Field access via dot-syntax can now be overloaded by adding methods to - `Base.getproperty` and `Base.setproperty!` ([#1974](https://github.com/JuliaLang/julia/issues/1974)), optionally along with - a corresponding `Base.propertynames` method for reflection ([#25311](https://github.com/JuliaLang/julia/issues/25311)). - - * Values for `Enum`s can now be specified inside of a `begin` block when using the - `@enum` macro ([#25424](https://github.com/JuliaLang/julia/issues/25424)). - - * Keyword arguments can be required: if a default value is omitted, then an - exception is thrown if the caller does not assign the keyword a value ([#25830](https://github.com/JuliaLang/julia/issues/25830)). - - * The pair operator `=>` is now broadcastable as `.=>` which was previously a parsing error ([#27447](https://github.com/JuliaLang/julia/issues/27447)) - Language changes ---------------- - * The syntax for parametric methods, `function f{T}(x::T)`, has been - changed to `function f(x::T) where {T}` ([#11310](https://github.com/JuliaLang/julia/issues/11310)). - - * The fallback constructor that calls `convert` is deprecated. Instead, new types should - prefer to define constructors, and add `convert` methods that call those constructors - only as necessary ([#15120](https://github.com/JuliaLang/julia/issues/15120)). - - * The syntax `1.+2` is deprecated, since it is ambiguous: it could mean either - `1 .+ 2` (the current meaning) or `1. + 2` ([#19089](https://github.com/JuliaLang/julia/issues/19089)). - - * Mutable structs with no fields are no longer singletons; it is now possible to make - multiple instances of them that can be distinguished by `===` ([#25854](https://github.com/JuliaLang/julia/issues/25854)). - Zero-size immutable structs are still singletons. - - * In string and character literals, backslash `\` may no longer - precede unrecognized escape characters ([#22800](https://github.com/JuliaLang/julia/issues/22800)). - - * Juxtaposing binary, octal, and hexadecimal literals is deprecated, since it can lead to - confusing code such as `0xapi == 0xa * pi` ([#16356](https://github.com/JuliaLang/julia/issues/16356)). - - * Numeric literal juxtaposition now has slighty lower precedence than unary operators, - so for example `√2x` parses as `(√2) * x` ([#27641](https://github.com/JuliaLang/julia/issues/27641)). - - * Declaring arguments as `x::ANY` to avoid specialization has been replaced - by `@nospecialize x`. ([#22666](https://github.com/JuliaLang/julia/issues/22666)). - - This can also be used in global scope, to apply to all subsequent method definitions - in the module (until `@specialize`). ([#28065](https://github.com/JuliaLang/julia/issues/28065)) - - * Keyword argument default values are now evaluated in successive scopes --- - the scope for each expression includes only previous keyword arguments, in - left-to-right order ([#17240](https://github.com/JuliaLang/julia/issues/17240)). - - * The parsing of `1<<2*3` as `1<<(2*3)` is deprecated, and will change to - `(1<<2)*3` in a future version ([#13079](https://github.com/JuliaLang/julia/issues/13079)). - - * The parsing of `<|` is now right associative. `|>` remains left associative ([#24153](https://github.com/JuliaLang/julia/issues/24153)). - - * `:` now parses like other operators, as a call to a function named `:`, instead of - calling `colon` ([#25947](https://github.com/JuliaLang/julia/issues/25947)). - - * `{ }` expressions now use `braces` and `bracescat` as expression heads instead - of `cell1d` and `cell2d`, and parse similarly to `vect` and `vcat` ([#8470](https://github.com/JuliaLang/julia/issues/8470)). - - * Nested `if` expressions that arise from the keyword `elseif` now use `elseif` - as their expression head instead of `if` ([#21774](https://github.com/JuliaLang/julia/issues/21774)). - - * `let` blocks now parse the same as `for` loops; the first argument is either an - assignment or `block` of assignments, and the second argument is a block of - statements ([#21774](https://github.com/JuliaLang/julia/issues/21774)). - - * `do` syntax now parses to an expression with head `:do`, instead of as a function - call ([#21774](https://github.com/JuliaLang/julia/issues/21774)). - - * Parsed and lowered forms of type definitions have been synchronized with their - new keywords ([#23157](https://github.com/JuliaLang/julia/issues/23157)). Expression heads are renamed as follows: - - + `type` => `struct` - - + `bitstype` => `primitive` (order of arguments is also reversed, to match syntax) - - + `composite_type` => `struct_type` - - + `bits_type` => `primitive_type` - - * The `global` keyword now only introduces a new binding if one doesn't already exist - in the module. - This means that assignment to a global (`global sin = 3`) may now throw the error: - "cannot assign variable Base.sin from module Main", rather than emitting a warning. - Additionally, the new bindings are now created before the statement is executed. - For example, `f() = (global sin = "gluttony"; nothing)` will now resolve which module - contains `sin` eagerly, rather than delaying that decision until `f` is run. ([#22984](https://github.com/JuliaLang/julia/issues/22984)). - - * `global const` declarations may no longer appear inside functions ([#12010](https://github.com/JuliaLang/julia/issues/12010)). - - * Uninitialized `BitArray` constructors of the form `BitArray[{N}](shape...)` have been - deprecated in favor of equivalents accepting `undef` (an alias for - `UndefInitializer()`) as their first argument, as in - `BitArray[{N}](undef, shape...)`. For example, `BitVector(3)` is now - `BitVector(undef, 3)`, `BitMatrix((2, 4))` is now - `BitMatrix(undef, (2, 4))`, and `BitArray{3}(11, 13, 17)` is now - `BitArray{3}(undef, 11, 14, 17)` ([#24785](https://github.com/JuliaLang/julia/issues/24785)). - - * Dispatch rules have been simplified: - method matching is now determined exclusively by subtyping; - the rule that method type parameters must also be captured has been removed. - Instead, attempting to access the unconstrained parameters will throw an `UndefVarError`. - Linting in package tests is recommended to confirm that the set of methods - which might throw `UndefVarError` when accessing the static parameters - (`need_to_handle_undef_sparam = Set{Any}(m.sig for m in Test.detect_unbound_args(Base, recursive=true))`) - is equal (`==`) to some known set (`expected = Set()`). ([#23117](https://github.com/JuliaLang/julia/issues/23117)) - - * `const` declarations on local variables were previously ignored. They now give a - warning, so that this syntax can be disallowed or given a new meaning in a - future version ([#5148](https://github.com/JuliaLang/julia/issues/5148)). - - * Placing an expression after `catch`, as in `catch f(x)`, is deprecated. - Use `catch; f(x)` instead ([#19987](https://github.com/JuliaLang/julia/issues/19987)). - - * In `for i = ...`, if a local variable `i` already existed it would be overwritten - during the loop. This behavior is deprecated, and in the future `for` loop variables - will always be new variables local to the loop ([#22314](https://github.com/JuliaLang/julia/issues/22314)). - The old behavior of overwriting an existing variable is available via `for outer i = ...`. - - * In `for i in x`, `x` used to be evaluated in a new scope enclosing the `for` loop. - Now it is evaluated in the scope outside the `for` loop. - - * In `for i in x, j in y`, all variables now have fresh bindings on each iteration of the - innermost loop. For example, an assignment to `i` will not be visible on the next `j` - loop iteration ([#330](https://github.com/JuliaLang/julia/issues/330)). - - * Variable bindings local to `while` loop bodies are now freshly allocated on each loop iteration, - matching the behavior of `for` loops. - - * Prefix `&` for by-reference arguments to `ccall` has been deprecated in favor of - `Ref` argument types ([#6080](https://github.com/JuliaLang/julia/issues/6080)). - - * The constructor `Ref(x::T)` now always returns a `Ref{T}` ([#21527](https://github.com/JuliaLang/julia/issues/21527)). - - * All line numbers in ASTs are represented by `LineNumberNode`s; the `:line` expression - head is no longer used. `QuoteNode`s are also consistently used for quoted symbols instead - of the `:quote` expression head (though `:quote` `Expr`s are still used for quoted - expressions) ([#23885](https://github.com/JuliaLang/julia/issues/23885)). - - * The `+` and `-` methods for `Number` and `UniformScaling` are not ambiguous anymore since `+` - and `-` no longer do automatic broadcasting. Hence, the methods for `UniformScaling` and `Number` are - no longer deprecated ([#23923](https://github.com/JuliaLang/julia/issues/23923)). - - * The keyword `importall` is deprecated. Use `using` and/or individual `import` statements - instead ([#22789](https://github.com/JuliaLang/julia/issues/22789)). - - * `reduce(+, [...])` and `reduce(*, [...])` no longer widen the iterated over arguments to - system word size. `sum` and `prod` still preserve this behavior. ([#22825](https://github.com/JuliaLang/julia/issues/22825)) - - * Like `_`, variable names consisting only of underscores can be assigned, - but accessing their values is deprecated ([#24221](https://github.com/JuliaLang/julia/issues/24221)). - - * Raw string literal escaping rules have been changed to make it possible to write all strings. - The rule is that backslashes escape both quotes and other backslashes, but only when a sequence - of backslashes precedes a quote character. Thus, 2n backslashes followed by a quote encodes n - backslashes and the end of the literal while 2n+1 backslashes followed by a quote encodes n - backslashes followed by a quote character ([#22926](https://github.com/JuliaLang/julia/issues/22926)). - - * `reprmime(mime, x)` has been renamed to `repr(mime, x)`, and along with `repr(x)` - and `sprint` it now accepts an optional `context` keyword for `IOContext` attributes. - `stringmime` has been moved to the Base64 stdlib package ([#25990](https://github.com/JuliaLang/julia/issues/25990)). - - * The syntax `(x...)` for constructing a tuple is deprecated; use `(x...,)` instead ([#24452](https://github.com/JuliaLang/julia/issues/24452)). - - * Non-parenthesized interpolated variables in strings, e.g. `"$x"`, must be followed - by a character that will never be an allowed identifier character (currently - operators, space/control characters, or common punctuation characters) ([#25231](https://github.com/JuliaLang/julia/issues/25231)). - - * The syntax `using A.B` can now only be used when `A.B` is a module, and the syntax - `using A: B` can only be used for adding single bindings ([#8000](https://github.com/JuliaLang/julia/issues/8000)). - - * `=>` now has its own precedence level, giving it strictly higher precedence than - `=` and `,` ([#25391](https://github.com/JuliaLang/julia/issues/25391)). - - * The conditions under which unary operators followed by `(` are parsed as prefix function - calls have changed ([#26154](https://github.com/JuliaLang/julia/issues/26154)). - - * `begin` is disallowed inside indexing expressions, in order to enable the syntax - `a[begin]` (for selecting the first element) in the future ([#23354](https://github.com/JuliaLang/julia/issues/23354)). - - * Underscores for `_italics_` and `__bold__` are now supported by the Base Markdown - parser. ([#25564](https://github.com/JuliaLang/julia/issues/25564)) - - * `…` (`\dots`) and `⁝` (`\tricolon`) are now parsed as binary operators ([#26262](https://github.com/JuliaLang/julia/issues/26262)). - - * Assignment syntax (`a=b`) inside square bracket expressions (e.g. `A[...]`, `[x, y]`) - is deprecated. It will likely be reclaimed in a later version for passing keyword - arguments. Note this does not affect updating operators like `+=` ([#25631](https://github.com/JuliaLang/julia/issues/25631)). - - * `try` blocks without `catch` or `finally` are no longer allowed. An explicit empty - `catch` block should be written instead ([#27554](https://github.com/JuliaLang/julia/issues/27554)). - - * `AbstractArray` types that use unconventional (not 1-based) indexing can now support - `size`, `length`, and `@inbounds`. To optionally enforce conventional indices, - you can `@assert !has_offset_axes(A)`. - - * Module pre-compilation is now the default for code loading. Adding a - `__precompile__()` declaration is no longer necessary, although - `__precompile__(false)` can still be used to opt-out ([#26991](https://github.com/JuliaLang/julia/issues/26991)). - Breaking changes ---------------- -This section lists changes that do not have deprecation warnings. - - * The package manager `Pkg` has been replaced with a new one. See the manual entries on - "Code Loading" and "Pkg" for documentation. - - * `replace(s::AbstractString, pat=>repl)` for function `repl` arguments formerly - passed a substring to `repl` in all cases. It now passes substrings for - string patterns `pat`, but a `Char` for character patterns (when `pat` is a - `Char`, collection of `Char`, or a character predicate) ([#25815](https://github.com/JuliaLang/julia/issues/25815)). - - * `readuntil` now does *not* include the delimiter in its result, matching the - behavior of `readline`. Pass `keep=true` to get the old behavior ([#25633](https://github.com/JuliaLang/julia/issues/25633)). - - * `lu` methods now return decomposition objects such as `LU` rather than - tuples of arrays or tuples of numbers ([#26997](https://github.com/JuliaLang/julia/issues/26997), [#27159](https://github.com/JuliaLang/julia/issues/27159), [#27212](https://github.com/JuliaLang/julia/issues/27212)). - - * `schur` methods now return decomposition objects such as `Schur` and - `GeneralizedSchur` rather than tuples of arrays ([#26997](https://github.com/JuliaLang/julia/issues/26997), [#27159](https://github.com/JuliaLang/julia/issues/27159), [#27212](https://github.com/JuliaLang/julia/issues/27212)). - - * `lq` methods now return decomposition objects such as `LQ` - rather than tuples of arrays ([#26997](https://github.com/JuliaLang/julia/issues/26997), [#27159](https://github.com/JuliaLang/julia/issues/27159), [#27212](https://github.com/JuliaLang/julia/issues/27212)). - - * `qr` methods now return decomposition objects such as `QR`, `QRPivoted`, - and `QRCompactWY` rather than tuples of arrays ([#26997](https://github.com/JuliaLang/julia/issues/26997), [#27159](https://github.com/JuliaLang/julia/issues/27159), [#27212](https://github.com/JuliaLang/julia/issues/27212)). - - * `svd` methods now return decomposition objects such as `SVD` and - `GeneralizedSVD` rather than tuples of arrays or tuples of numbers ([#26997](https://github.com/JuliaLang/julia/issues/26997), [#27159](https://github.com/JuliaLang/julia/issues/27159), [#27212](https://github.com/JuliaLang/julia/issues/27212)). - - * `countlines` now always counts the last non-empty line even if it does not - end with EOL, matching the behavior of `eachline` and `readlines` ([#25845](https://github.com/JuliaLang/julia/issues/25845)). - - * `getindex(s::String, r::UnitRange{Int})` now throws `StringIndexError` if `last(r)` - is not a valid index into `s` ([#22572](https://github.com/JuliaLang/julia/issues/22572)). - - * `ntuple(f, n::Integer)` throws `ArgumentError` if `n` is negative. - Previously an empty tuple was returned ([#21697](https://github.com/JuliaLang/julia/issues/21697)). - - * `⋮`, `⋱`, `⋰`, and `⋯` are now parsed as binary operators, not ordinary - identifiers. `≔`, `≕`, and `⩴` now parse with assignment rather than comparison - precedence ([#26262](https://github.com/JuliaLang/julia/issues/26262)). - - * Juxtaposing string literals (e.g. `"x"y`) is now a syntax error ([#20575](https://github.com/JuliaLang/julia/issues/20575)). - - * `finalizer(function, object)` now returns `object` rather than `nothing` ([#24679](https://github.com/JuliaLang/julia/issues/24679)). - - * The constructor of `SubString` now checks if the requested view range - is defined by valid indices in the parent `AbstractString` ([#22511](https://github.com/JuliaLang/julia/issues/22511)). - - * Macro calls with `for` expressions are now parsed as generators inside - function argument lists ([#18650](https://github.com/JuliaLang/julia/issues/18650)). Examples: - - + `sum(@inbounds a[i] for i = 1:n)` used to give a syntax error, but is now - parsed as `sum(@inbounds(a[i]) for i = 1:n)`. - - + `sum(@m x for i = 1:n end)` used to parse the argument to `sum` as a 2-argument - call to macro `@m`, but now parses it as a generator plus a syntax error - for the dangling `end`. - - * `@__DIR__` returns the current working directory rather than `nothing` when not run - from a file ([#21759](https://github.com/JuliaLang/julia/issues/21759)). - - * `@__FILE__` and `@__DIR__` return information relative to the file that it was parsed from, - rather than from the task-local `SOURCE_PATH` global when it was expanded. - - * All macros receive an extra argument `__source__::LineNumberNode` which describes the - parser location in the source file for the `@` of the macro call. - It can be accessed as a normal argument variable in the body of the macro. - This is implemented by inserting an extra leading argument into the - `Expr(:macrocall, :@name, LineNumberNode(...), args...)` - surface syntax. ([#21746](https://github.com/JuliaLang/julia/issues/21746)) - - * Passing the same keyword argument multiple times is now a syntax error ([#16937](https://github.com/JuliaLang/julia/issues/16937)). - - * `getsockname` on a `TCPSocket` now returns the locally bound address and port - of the socket. Previously the address of the remote endpoint was being - returned ([#21825](https://github.com/JuliaLang/julia/issues/21825)). - - * The `~/.juliarc.jl` file has been moved to `~/.julia/config/startup.jl` and - `/etc/julia/juliarc.jl` file has been renamed to `/etc/julia/startup.jl` ([#26161](https://github.com/JuliaLang/julia/issues/26161)). - - * Using `ARGS` within `startup.jl` files or within a .jl file loaded with `--load` will no - longer contain the script name as the first argument. Instead, the script name will be - assigned to `PROGRAM_FILE`. ([#22092](https://github.com/JuliaLang/julia/issues/22092)) - - * The format for a `ClusterManager` specifying the cookie on the command line is now - `--worker=`. `--worker ` will not work as it is now an optional argument. - - * The representation of `CartesianRange` has changed to a - tuple-of-AbstractUnitRanges; the `start` and `stop` fields are no - longer present. Use `first(R)` and `last(R)` to obtain - start/stop. ([#20974](https://github.com/JuliaLang/julia/issues/20974)) - - * The `Diagonal`, `Bidiagonal`, `Tridiagonal` and `SymTridiagonal` type definitions have - changed from `Diagonal{T}`, `Bidiagonal{T}`, `Tridiagonal{T}` and `SymTridiagonal{T}` - to `Diagonal{T,V<:AbstractVector{T}}`, `Bidiagonal{T,V<:AbstractVector{T}}`, - `Tridiagonal{T,V<:AbstractVector{T}}` and `SymTridiagonal{T,V<:AbstractVector{T}}` - respectively ([#22718](https://github.com/JuliaLang/julia/issues/22718), [#22925](https://github.com/JuliaLang/julia/issues/22925), [#23035](https://github.com/JuliaLang/julia/issues/23035), [#23154](https://github.com/JuliaLang/julia/issues/23154)). - - * The immediate supertype of `BitArray` is now simply `AbstractArray`. `BitArray` is no longer - considered a subtype of `DenseArray` and `StridedArray` ([#25858](https://github.com/JuliaLang/julia/issues/25858)). - - * When called with an argument that contains `NaN` elements, `findmin` and `findmax` now return the - first `NaN` found and its corresponding index. Previously, `NaN` elements were ignored. - The new behavior matches that of `min`, `max`, `minimum`, and `maximum`. - - * `isapprox(x,y)` now tests `norm(x-y) <= max(atol, rtol*max(norm(x), norm(y)))` - rather than `norm(x-y) <= atol + ...`, and `rtol` defaults to zero - if an `atol > 0` is specified ([#22742](https://github.com/JuliaLang/julia/issues/22742)). - - * Spaces are no longer allowed between `@` and the name of a macro in a macro call ([#22868](https://github.com/JuliaLang/julia/issues/22868)). - - * Juxtaposition of a non-literal with a macro call (`x@macro`) is no longer valid syntax ([#22868](https://github.com/JuliaLang/julia/issues/22868)). - - * On a cluster, all files are now loaded from the local file system rather than node 1 ([#22588](https://github.com/JuliaLang/julia/issues/22588)). - To load the same file everywhere from node 1, one possible alternative is to broadcast a call to `include_string`: - `@everywhere include_string(Main, $(read("filename", String)), "filename")`. - Improving upon this API is left as an opportunity for packages. - - * `randperm(n)` and `randcycle(n)` now always return a `Vector{Int}` (independent of - the type of `n`). Use the corresponding mutating functions `randperm!` and `randcycle!` - to control the array type ([#22723](https://github.com/JuliaLang/julia/issues/22723)). - - * Hermitian now ignores any imaginary components in the diagonal instead of checking - the diagonal. ([#17367](https://github.com/JuliaLang/julia/issues/17367)) - - * Worker-worker connections are setup lazily for an `:all_to_all` topology. Use keyword - arg `lazy=false` to force all connections to be setup during a `addprocs` call. ([#22814](https://github.com/JuliaLang/julia/issues/22814)) - - * In `joinpath(a, b)` on Windows, if the drive specifications of `a` and `b` do not match, - `joinpath` now returns `b` instead of throwing an `ArgumentError`. `joinpath(path...)` is - defined to be left associative, so if any argument has a drive path which does not match - the drive of the join of the preceding paths, the prior ones are dropped. ([#20912](https://github.com/JuliaLang/julia/issues/20912)) - - * `^(A::AbstractMatrix{<:Integer}, p::Integer)` now throws a `DomainError` - if `p < 0`, unless `A == one(A)` or `A == -one(A)` (same as for - `^(A::Integer, p::Integer)`) ([#23366](https://github.com/JuliaLang/julia/issues/23366)). - - * `^(A::AbstractMatrix{<:Integer}, p::Integer)` now promotes the element type in the same - way as `^(A::Integer, p::Integer)`. This means, for instance, that `[1 1; 0 1]^big(1)` - will return a `Matrix{BigInt}` instead of a `Matrix{Int}` ([#23366](https://github.com/JuliaLang/julia/issues/23366)). - - * The element type of the input is now preserved in `unique`. Previously the element type - of the output was shrunk to fit the union of the type of each element in the input. - ([#22696](https://github.com/JuliaLang/julia/issues/22696)) - - * The `promote` function now raises an error if its arguments are of different types - and if attempting to convert them to a common type fails to change any of their types. - This avoids stack overflows in the common case of definitions like - `f(x, y) = f(promote(x, y)...)` ([#22801](https://github.com/JuliaLang/julia/issues/22801)). - - * `indmin` and `indmax` have been renamed to `argmin` and `argmax`, respectively ([#25654](https://github.com/JuliaLang/julia/issues/25654)). - - * `findmin`, `findmax`, `argmin`, and `argmax` used to always return linear indices. - They now return `CartesianIndex`es for all but 1-d arrays, and in general return - the `keys` of indexed collections (e.g. dictionaries) ([#22907](https://github.com/JuliaLang/julia/issues/22907)). - - * The `openspecfun` library is no longer built and shipped with Julia, as it is no longer - used internally ([#22390](https://github.com/JuliaLang/julia/issues/22390)). - - * All loaded packages used to have bindings in `Main` (e.g. `Main.Package`). This is no - longer the case; now bindings will only exist for packages brought into scope by - typing `using Package` or `import Package` ([#17997](https://github.com/JuliaLang/julia/issues/17997)). - - * The rules for mixed-signedness integer arithmetic (e.g. `Int32(1) + UInt64(1)`) have been - simplified: if the arguments have different sizes (in bits), then the type of the larger - argument is used. If the arguments have the same size, the unsigned type is used ([#9292](https://github.com/JuliaLang/julia/issues/9292)). - - * All command line arguments passed via `-e`, `-E`, and `-L` will be executed in the order - given on the command line ([#23665](https://github.com/JuliaLang/julia/issues/23665)). - - * `I` now yields `UniformScaling{Bool}(true)` rather than `UniformScaling{Int64}(1)` - to better preserve types in operations involving `I` ([#24396](https://github.com/JuliaLang/julia/issues/24396)). - - * The return type of `reinterpret` has changed to `ReinterpretArray`. `reinterpret` on sparse - arrays has been discontinued. - - * `Base.find_in_path` is now `Base.find_package` or `Base.find_source_file` ([#24320](https://github.com/JuliaLang/julia/issues/24320)). - - * `finalizer` now takes functions or pointers as its first argument, and the object being - finalized as its second (rather than the reverse). For the majority of use cases - deprecation warnings will be triggered. However, deprecation warnings will not trigger where - (1) the callable argument is not a subtype of `Function`; or (2) both arguments are - `Function`s or `Ptr{Cvoid}`s ([#24605](https://github.com/JuliaLang/julia/issues/24605)). - - * The `kill` function now throws errors on user error (e.g. on permission - errors), but returns successfully if the process had previously exited. - Its return value has been removed. Use the `process_running` function - to determine if a process has already exited. - - * The logging system has been redesigned - `info` and `warn` are deprecated - and replaced with the logging macros `@info`, `@warn`, `@debug` and - `@error`. The `logging` function is also deprecated and replaced with - `AbstractLogger` and the functions from the new standard `Logging` library. - ([#24490](https://github.com/JuliaLang/julia/issues/24490)) - - * The `RevString` type has been removed from the language; `reverse(::String)` returns - a `String` with code points (or fragments thereof) in reverse order. In general, - `reverse(s)` should return a string of the same type and encoding as `s` with code - points in reverse order; any string type overrides `reverse` to return a different - type of string must also override `reverseind` to compute reversed indices correctly. - - * `eachindex(A, B...)` now requires that all inputs have the same number of elements. - When the chosen indexing is Cartesian, they must have the same axes. - - * `AbstractRange` objects are now considered as equal to other `AbstractArray` objects - by `==` and `isequal` if all of their elements are equal ([#16401](https://github.com/JuliaLang/julia/issues/16401)). - This has required changing the hashing algorithm: ranges now use an O(N) fallback - instead of a O(1) specialized method unless they define the `Base.RangeStepStyle` - trait; see its documentation for details. Types which support subtraction (operator - `-`) must now implement `widen` for hashing to work inside heterogeneous arrays. - - * `findn(x::AbstractArray)` has been deprecated in favor of `findall(!iszero, x)`, which - now returns cartesian indices for multidimensional arrays (see below, [#25532](https://github.com/JuliaLang/julia/issues/25532)). - - * Broadcasting operations are no longer fused into a single operation by Julia's parser. - Instead, a lazy `Broadcasted` object is created to represent the fused expression and - then realized with `copy(bc::Broadcasted)` or `copyto!(dest, bc::Broadcasted)` - to evaluate the wrapper. Consequently, package authors generally need to specialize - `copy` and `copyto!` methods rather than `broadcast` and `broadcast!`. This also allows - for more customization and control of fused broadcasts. See the - [Interfaces chapter](https://docs.julialang.org/en/latest/manual/interfaces/#man-interfaces-broadcasting-1) - for more information. - - * `find` has been renamed to `findall`. `findall`, `findfirst`, `findlast`, `findnext` - now take and/or return the same type of indices as `keys`/`pairs` for `AbstractArray`, - `AbstractDict`, `AbstractString`, `Tuple` and `NamedTuple` objects ([#24774](https://github.com/JuliaLang/julia/issues/24774), [#25545](https://github.com/JuliaLang/julia/issues/25545)). - In particular, this means that they use `CartesianIndex` objects for matrices - and higher-dimensional arrays instead of linear indices as was previously the case. - Use `LinearIndices(a)[findall(f, a)]` and similar constructs to compute linear indices. - - * The `find*` functions, i.e. `findnext`, `findprev`, `findfirst`, - and `findlast`, as well as `indexin`, now return `nothing` when no match is found rather - than `0` or `0:-1` ([#25472](https://github.com/JuliaLang/julia/issues/25472), [#25662](https://github.com/JuliaLang/julia/issues/25662), [#26149](https://github.com/JuliaLang/julia/issues/26149)) - - * The `Base.HasShape` iterator trait has gained a type parameter `N` indicating the - number of dimensions, which must correspond to the length of the tuple returned by - `size` ([#25655](https://github.com/JuliaLang/julia/issues/25655)). - - * `AbstractSet` objects are now considered equal by `==` and `isequal` if all of their - elements are equal ([#25368](https://github.com/JuliaLang/julia/issues/25368)). This has required changing the hashing algorithm - for `BitSet`. - - * the default behavior of `titlecase` is changed in two ways ([#23393](https://github.com/JuliaLang/julia/issues/23393)): - + characters not starting a word are converted to lowercase; - a new keyword argument `strict` is added which - allows to get the old behavior when it's `false`. - + any non-letter character is considered as a word separator; - to get the old behavior (only "space" characters are considered as - word separators), use the keyword `wordsep=isspace`. - - * `writedlm` in the standard library module DelimitedFiles now writes numeric values - using `print` rather than `print_shortest` ([#25745](https://github.com/JuliaLang/julia/issues/25745)). - - * The `tempname` function used to create a file on Windows but not on other - platforms. It now never creates a file ([#9053](https://github.com/JuliaLang/julia/issues/9053)). - - * The `fieldnames` and `propertynames` functions now return a tuple rather than - an array ([#25725](https://github.com/JuliaLang/julia/issues/25725)). - - * `indexin` now returns the first rather than the last matching index ([#25998](https://github.com/JuliaLang/julia/issues/25998)). - - * `parse(::Type, ::Char)` now uses a default base of 10, like other number parsing - methods, instead of 36 ([#26576](https://github.com/JuliaLang/julia/issues/26576)). - - * `isequal` for `Ptr`s now compares element types; `==` still compares only addresses - ([#26858](https://github.com/JuliaLang/julia/issues/26858)). - - * `widen` on 8- and 16-bit integer types now widens to 16- and 32-bit types, respectively. ([#28045](https://github.com/JuliaLang/julia/issues/28045)). - - * `mv`,`cp`, `touch`, `mkdir`, `mkpath`, `chmod` and `chown` now return the path that was created/modified - rather than `nothing` ([#27071](https://github.com/JuliaLang/julia/issues/27071)). - - * Regular expressions now default to UCP mode. Escape sequences such as `\w` - will now match based on unicode character properties, e.g. `r"\w+"` will - match `café` (not just `caf`). Add the `a` modifier (e.g. `r"\w+"a`) to - restore the previous behavior ([#27189](https://github.com/JuliaLang/julia/issues/27189)). - - * `@sync` now waits only for *lexically* enclosed (i.e. visible directly in the source - text of its argument) `@async` expressions. If you need to wait for a task created by - a called function `f`, have `f` return the task and put `@async wait(f(...))` within - the `@sync` block. - This change makes `@schedule` redundant with `@async`, so `@schedule` has been - deprecated ([#27164](https://github.com/JuliaLang/julia/issues/27164)). - - * `norm(A::AbstractMatrix, p=2)` computes no longer the operator/matrix norm but the `norm` of `A` - as for other iterables, i.e. as if it were a vector. Especially, `norm(A::AbstractMatrix)` is the - Frobenius norm. To compute the operator/matrix norm, use the new function `opnorm` ([#27401](https://github.com/JuliaLang/julia/issues/27401)). - - * `dot(u, v)` now acts recursively. Instead of `sum(u[i]' * v[i] for i in ...)`, it computes - `sum(dot(u[i], v[i]) for i in ...)`, similarly to `vecdot` before ([#27401](https://github.com/JuliaLang/julia/issues/27401)). - - * `Sys.CPU_CORES` has been renamed to `Sys.CPU_THREADS`; it still gives the number - of "logical cores" (including hyperthreading) rather than the number of physical - cores present on the CPU. Similarly, the environment variable `JULIA_CPU_CORES` is - deprecated in favor of `JULIA_CPU_THREADS` ([#27856](https://github.com/JuliaLang/julia/issues/27856)). - - * `WeakKeyDict` does not convert keys on insertion anymore (#24941). - Library improvements -------------------- - * The function `thisind(s::AbstractString, i::Integer)` returns the largest valid index - less or equal than `i` in the string `s` or `0` if no such index exists ([#24414](https://github.com/JuliaLang/julia/issues/24414)). - - * Support for Unicode 11 ([#28266](https://github.com/JuliaLang/julia/issues/28266)). - - * `Char` is now a subtype of `AbstractChar`, and most of the functions that - take character arguments now accept any `AbstractChar` ([#26286](https://github.com/JuliaLang/julia/issues/26286)). - - * `pathof(module)` returns the path a module was imported from ([#28310](https://github.com/JuliaLang/julia/issues/28310)). - - * `bytes2hex` now accepts an optional `io` argument to output to a hexadecimal stream - without allocating a `String` first ([#27121](https://github.com/JuliaLang/julia/issues/27121)). - - * `String(array)` now accepts an arbitrary `AbstractVector{UInt8}`. For `Vector` - inputs, it "steals" the memory buffer, leaving them with an empty buffer which - is guaranteed not to be shared with the `String` object. For other types of vectors - (in particular immutable vectors), a copy is made and the input is not truncated ([#26093](https://github.com/JuliaLang/julia/issues/26093)). - - * `Irrational` is now a subtype of `AbstractIrrational` ([#24245](https://github.com/JuliaLang/julia/issues/24245)). - - * Introduced the `empty` function, the functional pair to `empty!` which returns a new, - empty container ([#24390](https://github.com/JuliaLang/julia/issues/24390)). - - * Jump to first/last history entries in the REPL via "Alt-<" and "Alt->" ([#22829](https://github.com/JuliaLang/julia/issues/22829)). - - * REPL LaTeX-like tab completions have been simplified for several Unicode characters, - e.g. `𝔸` is now `\bbA` rather than `\BbbA` ([#25980](https://github.com/JuliaLang/julia/issues/25980)). - - * The function `chop` now accepts two arguments `head` and `tail` allowing to specify - number of characters to remove from the head and tail of the string ([#24126](https://github.com/JuliaLang/julia/issues/24126)). - - * `get(io, :color, false)` can now be used to query whether a stream `io` supports - [ANSI color codes](https://en.wikipedia.org/wiki/ANSI_escape_code) ([#25067](https://github.com/JuliaLang/julia/issues/25067)), - rather than using the undocumented `Base.have_color` global flag. - - * `print_with_color` has been deprecated in favor of - `printstyled([io], xs...; bold=false, color=:normal)` for printing styled text ([#25522](https://github.com/JuliaLang/julia/issues/25522)). - - * Functions `first` and `last` now accept `nchar` argument for `AbstractString`. - If this argument is used they return a string consisting of first/last `nchar` - characters from the original string ([#23960](https://github.com/JuliaLang/julia/issues/23960)). - - * Expressions `x^-n` where `n` is an *integer literal* now correspond to `inv(x)^n`. - For example, `x^-1` is now essentially a synonym for `inv(x)`, and works - in a type-stable way even if `typeof(x) != typeof(inv(x))` ([#24240](https://github.com/JuliaLang/julia/issues/24240)). - - * New `Iterators.reverse(itr)` for reverse-order iteration ([#24187](https://github.com/JuliaLang/julia/issues/24187)). Iterator - types `T` can implement `start` etc. for `Iterators.Reverse{T}` to support this. - - * The functions `nextind` and `prevind` now accept `nchar` argument that indicates - the number of characters to move ([#23805](https://github.com/JuliaLang/julia/issues/23805)). - - * The functions `strip`, `lstrip` and `rstrip` now return `SubString` ([#22496](https://github.com/JuliaLang/julia/issues/22496)). - - * The functions `strwidth` and `charwidth` have been merged into `textwidth`([#20816](https://github.com/JuliaLang/julia/issues/20816)). - - * The functions `base` and `digits` digits now accept a negative - base (like `ndigits` did) ([#21692](https://github.com/JuliaLang/julia/issues/21692)). - - * The function `randn` now accepts complex arguments (`Complex{T <: AbstractFloat}`) - ([#21973](https://github.com/JuliaLang/julia/issues/21973)). - - * `parse(Complex{T}, string)` can parse complex numbers in some common formats ([#24713](https://github.com/JuliaLang/julia/issues/24713)). - - * The function `rand` can now pick up random elements from strings, associatives - and sets ([#22228](https://github.com/JuliaLang/julia/issues/22228), [#21960](https://github.com/JuliaLang/julia/issues/21960), [#18155](https://github.com/JuliaLang/julia/issues/18155), [#22224](https://github.com/JuliaLang/julia/issues/22224)). - - * It's now possible to specify the characters to pick from in the `randstring` function ([#22222](https://github.com/JuliaLang/julia/issues/22222)). - - * Allow multidimensional arrays in `shuffle` and `shuffle!` functions ([#22226](https://github.com/JuliaLang/julia/issues/22226)). - - * Method lists are now printed as a numbered list. In addition, the source code of a - method can be opened in an editor by entering the corresponding number in the REPL - and pressing `^Q` ([#22007](https://github.com/JuliaLang/julia/issues/22007)). - - * `getpeername` on a `TCPSocket` returns the address and port of the remote - endpoint of the TCP connection ([#21825](https://github.com/JuliaLang/julia/issues/21825)). - - * `resize!` and `sizehint!` methods no longer over-reserve memory when the - requested array size is more than double of its current size ([#22038](https://github.com/JuliaLang/julia/issues/22038)). - - * The `crc32c` function for CRC-32c checksums is now exported ([#22274](https://github.com/JuliaLang/julia/issues/22274)). - - * `eye(::Type{Diagonal{T}}, m::Integer)` has been deprecated in favor of - `Diagonal{T}(I, m)` ([#24413](https://github.com/JuliaLang/julia/issues/24413)). - - * The output of `versioninfo` is now controlled with keyword arguments ([#21974](https://github.com/JuliaLang/julia/issues/21974)). - - * The function `LibGit2.set_remote_url` now always sets both the fetch and push URLs for a - git repo. Additionally, the argument order was changed to be consistent with the git - command line tool ([#22062](https://github.com/JuliaLang/julia/issues/22062)). - - * Added `unique!` which is an inplace version of `unique` ([#20549](https://github.com/JuliaLang/julia/issues/20549)). - - * `@test isequal(x, y)` and `@test isapprox(x, y)` now prints an evaluated expression when - the test fails ([#22296](https://github.com/JuliaLang/julia/issues/22296)). - - * Uses of `Val{c}` in `Base` has been replaced with `Val{c}()`, which is now easily - accessible via the efficient constructor `Val(c)`. Functions are defined as - `f(::Val{c}) = ...` and called by `f(Val(c))`. Notable affected functions include: - `ntuple`, `Base.literal_pow`, `sqrtm`, `lufact`, `lufact!`, `qrfact`, `qrfact!`, - `cholfact`, `cholfact!`, `_broadcast!`, `reshape`, `cat` and `cat_t`. - - * A new `@macroexpand1` macro for non recursive macro expansion ([#21662](https://github.com/JuliaLang/julia/issues/21662)). - - * `Char`s can now be concatenated with `String`s and/or other `Char`s using `*` ([#22532](https://github.com/JuliaLang/julia/issues/22532)). - - * `Diagonal`, `Bidiagonal`, `Tridiagonal` and `SymTridiagonal` are now parameterized on - the type of the wrapped vectors, allowing `Diagonal`, `Bidiagonal`, `Tridiagonal` and - `SymTridiagonal` matrices with arbitrary `AbstractVector`s - ([#22718](https://github.com/JuliaLang/julia/issues/22718), [#22925](https://github.com/JuliaLang/julia/issues/22925), [#23035](https://github.com/JuliaLang/julia/issues/23035), [#23154](https://github.com/JuliaLang/julia/issues/23154)). - - * Mutating versions of `randperm` and `randcycle` have been added: - `randperm!` and `randcycle!` ([#22723](https://github.com/JuliaLang/julia/issues/22723)). - - * `BigFloat` random numbers can now be generated ([#22720](https://github.com/JuliaLang/julia/issues/22720)). - - * The efficiency of random generation for MersenneTwister RNGs has been improved for - integers, `Float64` and ranges; as a result, given a seed, the produced stream of numbers - has changed ([#27560](https://github.com/JuliaLang/julia/issues/27560), [#25277](https://github.com/JuliaLang/julia/issues/25277), [#25197](https://github.com/JuliaLang/julia/issues/25197), [#25058](https://github.com/JuliaLang/julia/issues/25058), [#25047](https://github.com/JuliaLang/julia/issues/25047)). - - * REPL Undo via Ctrl-/ and Ctrl-_ - - * `diagm` now accepts several diagonal index/vector `Pair`s ([#24047](https://github.com/JuliaLang/julia/issues/24047)). - - * `isequal`, `==`, and `in` have one argument "curried" forms. For example `isequal(x)` - returns a function that compares its argument to `x` using `isequal` ([#26436](https://github.com/JuliaLang/julia/issues/26436)). - - * `reinterpret` now works on any AbstractArray using the new `ReinterpretArray` type. - This supersedes the old behavior of reinterpret on Arrays. As a result, reinterpreting - arrays with different alignment requirements (removed in 0.6) is once again allowed ([#23750](https://github.com/JuliaLang/julia/issues/23750)). - - * The `keys` of an `Associative` are now an `AbstractSet`. `Base.KeyIterator{<:Associative}` - has been changed to `KeySet{K, <:Associative{K}} <: AbstractSet{K}` ([#24580](https://github.com/JuliaLang/julia/issues/24580)). - - * New function `ncodeunits(s::AbstractString)` gives the number of code units in a string. - The generic definition is constant time but calls `lastindex(s)` which may be inefficient. - Therefore custom string types may want to define direct `ncodeunits` methods. - - * `reverseind(s::AbstractString, i::Integer)` now has an efficient generic fallback, so - custom string types do not need to provide their own efficient definitions. The generic - definition relies on `ncodeunits` however, so for optimal performance you may need to - define a custom method for that function. - - * The global RNG is being re-seeded with its own seed at the beginning of each `@testset`, - and have its original state restored at the end ([#24445](https://github.com/JuliaLang/julia/issues/24445)). This is breaking for testsets - relying implicitly on the global RNG being in a specific state. - - * `permutedims(m::AbstractMatrix)` is now short for `permutedims(m, (2,1))`, and is now a - more convenient way of making a "shallow transpose" of a 2D array. This is the - recommended approach for manipulating arrays of data, rather than the recursively - defined, linear-algebra function `transpose`. Similarly, - `permutedims(v::AbstractVector)` will create a row matrix ([#24839](https://github.com/JuliaLang/julia/issues/24839)). - - * A new `replace(A, old=>new)` function is introduced to replace `old` by `new` in - collection `A`. There is also another method with a different API, and - a mutating variant, `replace!` ([#22324](https://github.com/JuliaLang/julia/issues/22324), [#25697](https://github.com/JuliaLang/julia/issues/25697), [#26206](https://github.com/JuliaLang/julia/issues/26206), [#27944](https://github.com/JuliaLang/julia/issues/27944)). - - * Adding integers to `CartesianIndex` objects is now deprecated. Instead of - `i::Int + x::CartesianIndex`, use `i*one(x) + x` ([#26284](https://github.com/JuliaLang/julia/issues/26284)). - - * `CartesianRange` changes ([#24715](https://github.com/JuliaLang/julia/issues/24715)): - - Inherits from `AbstractArray`, and linear indexing can be used to provide - linear-to-cartesian conversion ([#24715](https://github.com/JuliaLang/julia/issues/24715)) - - It has a new constructor taking an array - - * several missing set-like operations have been added ([#23528](https://github.com/JuliaLang/julia/issues/23528)): - `union`, `intersect`, `symdiff`, `setdiff` are now implemented for - all collections with arbitrary many arguments, as well as the - mutating counterparts (`union!` etc.). The performance is also - much better in many cases. Note that this change is slightly - breaking: all the non-mutating functions always return a new - object even if only one argument is passed. Moreover the semantics - of `intersect` and `symdiff` is changed for vectors: - + `intersect` doesn't preserve the multiplicity anymore (use `filter` for - the old behavior) - + `symdiff` has been made consistent with the corresponding methods for - other containers, by taking the multiplicity of the arguments into account. - Use `unique` to get the old behavior. - - * The `linearindices` function has been deprecated in favor of the new - `LinearIndices` type, which additionally provides conversion from - cartesian indices to linear indices using the normal indexing operation. - ([#24715](https://github.com/JuliaLang/julia/issues/24715), [#26775](https://github.com/JuliaLang/julia/issues/26775)). - - * `IdDict{K,V}` replaces `ObjectIdDict`. It has type parameters - like other `AbstractDict` subtypes and its constructors mirror the - ones of `Dict`. ([#25210](https://github.com/JuliaLang/julia/issues/25210)) - - * `IOBuffer` can take the `sizehint` keyword argument to suggest a capacity of - the buffer ([#25944](https://github.com/JuliaLang/julia/issues/25944)). - - * `lstrip` and `rstrip` now accept a predicate function that defaults to `isspace` - ([#27309](https://github.com/JuliaLang/julia/issues/27309)). - - * `trunc`, `floor`, `ceil`, and `round` specify `digits`, `sigdigits` and `base` using - keyword arguments. ([#26156](https://github.com/JuliaLang/julia/issues/26156), [#26670](https://github.com/JuliaLang/julia/issues/26670)) - - * `Sys.which()` provides a cross-platform method to find executable files, similar to - the Unix `which` command. ([#26559](https://github.com/JuliaLang/julia/issues/26559)) - - * Added an optimized method of `vecdot` for taking the Frobenius inner product - of sparse matrices. ([#27470](https://github.com/JuliaLang/julia/issues/27470)) - - * Added an optimized method of `kron` for taking the tensor product of two - `Diagonal` matrices. ([27581]) - - * An official API for extending `rand` is now defined ([#23964](https://github.com/JuliaLang/julia/issues/23964), [#25002](https://github.com/JuliaLang/julia/issues/25002)). - - * The constructor `MersenneTwister()` is re-enabled, producing a randomly initialized RNG - (similar to `Random.seed!(MersenneTwister(0))`) ([#21909](https://github.com/JuliaLang/julia/issues/21909)). - - * `BitSet` can now store any `Int` (instead of only positive ones) ([#25029](https://github.com/JuliaLang/julia/issues/25029)). - - * The initial element `v0` in `reduce(op, v0, itr)` has been replaced with an `init` - optional keyword argument, as in `reduce(op, itr; init=v0)`. Similarly for `foldl`, - `foldr`, `mapreduce`, `mapfoldl`, `mapfoldr`, `accumulate` and `accumulate!`. - ([#27711](https://github.com/JuliaLang/julia/issues/27711), [#27859](https://github.com/JuliaLang/julia/issues/27859)) - Compiler/Runtime improvements ----------------------------- - * The inlining heuristic now models the approximate runtime cost of - a method (using some strongly-simplifying assumptions). Functions - are inlined unless their estimated runtime cost substantially - exceeds the cost of setting up and issuing a subroutine - call. ([#22210](https://github.com/JuliaLang/julia/issues/22210), [#22732](https://github.com/JuliaLang/julia/issues/22732)) - - * Inference recursion-detection heuristics are now more precise, - allowing them to be triggered less often, but being more aggressive when they - are triggered to drive the inference computation to a solution ([#23912](https://github.com/JuliaLang/julia/issues/23912)). - - * Inference now propagates constants inter-procedurally, and can compute - various constants expressions at compile-time ([#24362](https://github.com/JuliaLang/julia/issues/24362)). - - * The LLVM SLP Vectorizer optimization pass is now enabled at the default - optimization level. - Deprecated or removed --------------------- - * The `JULIA_HOME` environment variable has been renamed to `JULIA_BINDIR` and - `Base.JULIA_HOME` has been moved to `Sys.BINDIR` ([#20899](https://github.com/JuliaLang/julia/issues/20899)). - - * The keyword `immutable` is fully deprecated to `struct`, and - `type` is fully deprecated to `mutable struct` ([#19157](https://github.com/JuliaLang/julia/issues/19157), [#20418](https://github.com/JuliaLang/julia/issues/20418)). - - * `lufact`, `schurfact`, `lqfact`, `qrfact`, `ldltfact`, `svdfact`, - `bkfact`, `hessfact`, `eigfact`, and `cholfact` have respectively been - deprecated to `lu`, `schur`, `lq`, `qr`, `ldlt`, `svd`, `bunchkaufman`, - `hessenberg`, `eigen`, and `cholesky` ([#26997](https://github.com/JuliaLang/julia/issues/26997), [#27159](https://github.com/JuliaLang/julia/issues/27159), [#27212](https://github.com/JuliaLang/julia/issues/27212)). - - * `lufact!`, `schurfact!`, `lqfact!`, `qrfact!`, `ldltfact!`, `svdfact!`, - `bkfact!`, `hessfact!`, and `eigfact!` have respectively been deprecated to - `lu!`, `schur!`, `lq!`, `qr!`, `ldlt!`, `svd!`, `bunchkaufman!`, - `hessenberg!`, and `eigen!` ([#26997](https://github.com/JuliaLang/julia/issues/26997), [#27159](https://github.com/JuliaLang/julia/issues/27159), [#27212](https://github.com/JuliaLang/julia/issues/27212)). - - * `eig(A[, args...])` has been deprecated in favor of `eigen(A[, args...])`. - Whereas the former returns a tuple of arrays, the latter returns an `Eigen` object. - So for a direct replacement, use `(eigen(A[, args...])...,)`. But going forward, - consider using the direct result of `eigen(A[, args...])` instead, either - destructured into its components (`vals, vecs = eigen(A[, args...])`) or - as an `Eigen` object (`X = eigen(A[, args...])`) ([#26997](https://github.com/JuliaLang/julia/issues/26997), [#27159](https://github.com/JuliaLang/julia/issues/27159), [#27212](https://github.com/JuliaLang/julia/issues/27212)). - - * `eig(A::AbstractMatrix, B::AbstractMatrix)` and `eig(A::Number, B::Number)` - have been deprecated in favor of `eigen(A, B)`. Whereas the former each return - a tuple of arrays, the latter returns a `GeneralizedEigen` object. So for a direct - replacement, use `(eigen(A, B)...,)`. But going forward, consider using the - direct result of `eigen(A, B)` instead, either destructured into its components - (`vals, vecs = eigen(A, B)`), or as a `GeneralizedEigen` object - (`X = eigen(A, B)`) ([#26997](https://github.com/JuliaLang/julia/issues/26997), [#27159](https://github.com/JuliaLang/julia/issues/27159), [#27212](https://github.com/JuliaLang/julia/issues/27212)). - - * `ordschur(T::StridedMatrix{Ty}, Z::StridedMatrix{Ty}, select::Union{Vector{Bool},BitVector})` - and `ordschur(S::StridedMatrix{Ty}, T::StridedMatrix{Ty}, Q::StridedMatrix{Ty}, - Z::StridedMatrix{Ty}, select::Union{Vector{Bool},BitVector})` and their respective - inplace versions have been deprecated. - Use `ordschur(schur::Schur, select::Union{Vector{Bool},BitVector})` and - `ordschur(gschur::GeneralizedSchur, select::Union{Vector{Bool},BitVector})` instead - ([#28155](https://github.com/JuliaLang/julia/issues/28155)). - - * Indexing into multidimensional arrays with more than one index but fewer indices than there are - dimensions is no longer permitted when those trailing dimensions have lengths greater than 1. - Instead, reshape the array or add trailing indices so the dimensionality and number of indices - match ([#14770](https://github.com/JuliaLang/julia/issues/14770), [#23628](https://github.com/JuliaLang/julia/issues/23628)). - - * The use of a positional dimension argument has largely been deprecated in favor of a - `dims` keyword argument. This includes the functions `sum`, `prod`, `maximum`, - `minimum`, `all`, `any`, `findmax`, `findmin`, `mean`, `varm`, `std`, `var`, `cov`, - `cor`, `median`, `mapreducedim`, `reducedim`, `sort`, `accumulate`, `accumulate!`, - `cumsum`, `cumsum!`, `cumprod`, `cumprod!`, `flipdim`, `dropdims`, and `cat` ([#25501](https://github.com/JuliaLang/julia/issues/25501), [#26660](https://github.com/JuliaLang/julia/issues/26660), [#27100](https://github.com/JuliaLang/julia/issues/27100)). - - * `indices(a)` and `indices(a,d)` have been deprecated in favor of `axes(a)` and - `axes(a, d)` ([#25057](https://github.com/JuliaLang/julia/issues/25057)). - - * `EnvHash` has been renamed to `EnvDict` ([#24167](https://github.com/JuliaLang/julia/issues/24167)). - - * Uninitialized `Array` constructors of the form - `Array[{T,N}](shape...)` have been deprecated in favor of equivalents - accepting `undef` (an alias for `UndefInitializer()`) as their first argument, - as in `Array[{T,N}](undef, shape...)`. For example, - `Vector(3)` is now `Vector(undef, 3)`, `Matrix{Int}((2, 4))` is now, - `Matrix{Int}(undef, (2, 4))`, and `Array{Float32,3}(11, 13, 17)` is now - `Array{Float32,3}(undef, 11, 13, 17)` ([#24781](https://github.com/JuliaLang/julia/issues/24781)). - - * Previously `setindex!(A, x, I...)` (and the syntax `A[I...] = x`) supported two - different modes of operation when supplied with a set of non-scalar indices `I` - (e.g., at least one index is an `AbstractArray`) depending upon the value of `x` - on the right hand side. If `x` is an `AbstractArray`, its _contents_ are copied - elementwise into the locations in `A` selected by `I` and it must have the same - number of elements as `I` selects locations. Otherwise, if `x` is not an - `AbstractArray`, then its _value_ is implicitly broadcast to all locations to - all locations in `A` selected by `I`. This latter behavior—implicitly broadcasting - "scalar"-like values across many locations—is now deprecated in favor of explicitly - using the broadcasted assignment syntax `A[I...] .= x` or `fill!(view(A, I...), x)` - ([#26347](https://github.com/JuliaLang/julia/issues/26347)). - - * `broadcast_getindex(A, I...)` and `broadcast_setindex!(A, v, I...)` are deprecated in - favor of `getindex.((A,), I...)` and `setindex!.((A,), v, I...)`, respectively ([#27075](https://github.com/JuliaLang/julia/issues/27075)). - - * `LinAlg.fillslots!` has been renamed `LinAlg.fillstored!` ([#25030](https://github.com/JuliaLang/julia/issues/25030)). - - * `fill!(A::Diagonal, x)` and `fill!(A::AbstractTriangular, x)` have been deprecated - in favor of `Base.LinAlg.fillstored!(A, x)` ([#24413](https://github.com/JuliaLang/julia/issues/24413)). - - * `eye` has been deprecated in favor of `I` and `Matrix` constructors. Please see the - deprecation warnings for replacement details ([#24438](https://github.com/JuliaLang/julia/issues/24438)). - - * `zeros(D::Diagonal[, opts...])` has been deprecated ([#24654](https://github.com/JuliaLang/julia/issues/24654)). - - * Using Bool values directly as indices is now deprecated and will be an error in the future. Convert - them to `Int` before indexing if you intend to access index `1` for `true` and `0` for `false`. - - * `slicedim(A, d, i)` has been deprecated in favor of `copy(selectdim(A, d, i))`. The new - `selectdim` function now always returns a view into `A`; in many cases the `copy` is - not necessary. Previously, `slicedim` on a vector `V` over dimension `d=1` and scalar - index `i` would return the just selected element (unless `V` was a `BitVector`). This - has now been made consistent: `selectdim` now always returns a view into the original - array, with a zero-dimensional view in this specific case ([#26009](https://github.com/JuliaLang/julia/issues/26009)). - - * `whos` has been renamed `varinfo`, and now returns a markdown table instead of printing - output ([#12131](https://github.com/JuliaLang/julia/issues/12131)). - - * Uninitialized `RowVector` constructors of the form `RowVector{T}(shape...)` have been - deprecated in favor of equivalents accepting `undef` (an alias for - `UndefInitializer()`) as their first argument, as in - `RowVector{T}(undef, shape...)`. For example, `RowVector{Int}(3)` is now - `RowVector{Int}(undef, 3)`, and `RowVector{Float32}((1, 4))` is now - `RowVector{Float32}(undef, (1, 4))` ([#24786](https://github.com/JuliaLang/julia/issues/24786)). - - * `writecsv(io, a; opts...)` has been deprecated in favor of - `writedlm(io, a, ','; opts...)` ([#23529](https://github.com/JuliaLang/julia/issues/23529)). - - * The method `srand(rng, filename, n=4)` has been deprecated ([#21359](https://github.com/JuliaLang/julia/issues/21359)). - - * `readcsv(io[, T::Type]; opts...)` has been deprecated in favor of - `readdlm(io, ','[, T]; opts...)` ([#23530](https://github.com/JuliaLang/julia/issues/23530)). - - * `sparse(s::UniformScaling, m::Integer)` has been deprecated in favor of the - three-argument equivalent `sparse(s::UniformScaling, m, n)` ([#24472](https://github.com/JuliaLang/julia/issues/24472)). - - * The `cholfact`/`cholfact!` methods that accepted an `uplo` symbol have been deprecated - in favor of using `Hermitian` (or `Symmetric`) views ([#22187](https://github.com/JuliaLang/julia/issues/22187), [#22188](https://github.com/JuliaLang/julia/issues/22188)). - - * The `thin` keyword argument for orthogonal decomposition methods has - been deprecated in favor of `full`, which has the opposite meaning: - `thin == true` if and only if `full == false` ([#24279](https://github.com/JuliaLang/julia/issues/24279)). - - * `isposdef(A::AbstractMatrix, UL::Symbol)` and `isposdef!(A::AbstractMatrix, UL::Symbol)` - have been deprecated in favor of `isposdef(Hermitian(A, UL))` and `isposdef!(Hermitian(A, UL))` - respectively ([#22245](https://github.com/JuliaLang/julia/issues/22245)). - - * The `bkfact`/`bkfact!` methods that accepted `uplo` and `issymmetric` symbols have been deprecated - in favor of using `Hermitian` (or `Symmetric`) views ([#22605](https://github.com/JuliaLang/julia/issues/22605)). - - * The function `current_module` is deprecated and replaced with `@__MODULE__`. - This caused the deprecation of some reflection methods (such as `macroexpand` and - `isconst`), which now require a module argument. And it caused the bugfix of other - default arguments to use the Main module (including `whos`, `which`) ([#22064](https://github.com/JuliaLang/julia/issues/22064)). - - * `expand(ex)` and `expand(module, ex)` have been deprecated in favor of - `Meta.lower(module, ex)` ([#22064](https://github.com/JuliaLang/julia/issues/22064), [#24278](https://github.com/JuliaLang/julia/issues/24278)). - - * `ones(A::AbstractArray[, opts...])` and `zeros(A::AbstractArray[, opts...])` methods - have been deprecated. For `zeros(A)`, consider `zero(A)`. For `ones(A)` or `zeros(A)`, - consider `ones(size(A))`, `zeros(size(A))`, `fill(v, size(A))` for `v` an appropriate - one or zero, `fill!(copy(A), {1|0})`, `fill!(similar(A), {1|0})`, or any of the preceding - with different element type and/or shape depending on `opts...`. Where strictly - necessary, consider `fill!(similar(A[, opts...]), {one(eltype(A)) | zero(eltype(A))})`. - For an algebraic multiplicative identity, consider `one(A)` ([#24656](https://github.com/JuliaLang/julia/issues/24656)). - - * The `similar(dims->f(..., dims...), [T], axes...)` method to add offset array support - to a function `f` that would otherwise create a non-offset array has been deprecated. - Instead, call `f(..., axes...)` directly and, if needed, the offset array implementation - should add offset axis support to the function `f` directly ([#26733](https://github.com/JuliaLang/julia/issues/26733)). - - * The functions `ones` and `zeros` used to accept any objects as dimensional arguments, - implicitly converting them to `Int`s. This is now deprecated; only `Integer`s or - `AbstractUnitRange`s are accepted as arguments. Instead, convert the arguments before - calling `ones` or `zeros` ([#26733](https://github.com/JuliaLang/julia/issues/26733)). - - * The variadic `size(A, dim1, dim2, dims...)` method to return a tuple of multiple - dimension lengths of `A` has been deprecated ([#26862](https://github.com/JuliaLang/julia/issues/26862)). - - * The `Operators` module is deprecated. Instead, import required operators explicitly - from `Base`, e.g. `import Base: +, -, *, /` ([#22251](https://github.com/JuliaLang/julia/issues/22251)). - - * Bindings to the FFTW library have been removed from Base. The DFT framework for building FFT - implementations is now in AbstractFFTs.jl, the bindings to the FFTW library are in FFTW.jl, - and the Base signal processing functions which used FFTs are now in DSP.jl ([#21956](https://github.com/JuliaLang/julia/issues/21956)). - - * The `corrected` positional argument to `cov` has been deprecated in favor of - a keyword argument with the same name ([#21709](https://github.com/JuliaLang/julia/issues/21709)). - - * Omitting spaces around the `?` and the `:` tokens in a ternary expression has been deprecated. - Ternaries must now include some amount of whitespace, e.g. `x ? a : b` rather than - `x?a:b` ([#22523](https://github.com/JuliaLang/julia/issues/22523) and [#22712](https://github.com/JuliaLang/julia/issues/22712)). - - * `?` can no longer be used as an identifier name ([#22712](https://github.com/JuliaLang/julia/issues/22712)) - - * The method `replace(s::AbstractString, pat, r, [count])` is deprecated - in favor of `replace(s::AbstractString, pat => r; [count])` ([#25165](https://github.com/JuliaLang/julia/issues/25165)). - Moreover, `count` cannot be negative anymore (use `typemax(Int)` instead ([#22325](https://github.com/JuliaLang/julia/issues/22325)). - - * `read(io, type, dims)` is deprecated to `read!(io, Array{type}(undef, dims))` ([#21450](https://github.com/JuliaLang/julia/issues/21450)). - - * `read(::IO, ::Ref)` is now a method of `read!`, since it mutates its `Ref` argument ([#21592](https://github.com/JuliaLang/julia/issues/21592)). - - * `nb_available` is now `bytesavailable` ([#25634](https://github.com/JuliaLang/julia/issues/25634)). - - * `skipchars(io::IO, predicate; linecomment=nothing)` is deprecated in favor of - `skipchars(predicate, io::IO; linecomment=nothing)` ([#25667](https://github.com/JuliaLang/julia/issues/25667)). - - * `Bidiagonal` constructors now use a `Symbol` (`:U` or `:L`) for the upper/lower - argument, instead of a `Bool` or a `Char` ([#22703](https://github.com/JuliaLang/julia/issues/22703)). - - * `Bidiagonal`, `Tridiagonal` and `SymTridiagonal` constructors that automatically - converted the input vectors to the same type are deprecated in favor of explicit - conversion ([#22925](https://github.com/JuliaLang/julia/issues/22925), [#23035](https://github.com/JuliaLang/julia/issues/23035), [#23154](https://github.com/JuliaLang/julia/issues/23154). - - * Calling `nfields` on a type to find out how many fields its instances have is deprecated. - Use `fieldcount` instead. Use `nfields` only to get the number of fields in a specific object ([#22350](https://github.com/JuliaLang/julia/issues/22350)). - - * `fieldnames` now operates only on types. To get the names of fields in an object, use - `fieldnames(typeof(x))` ([#22350](https://github.com/JuliaLang/julia/issues/22350)). - - * `InexactError`, `DomainError`, and `OverflowError` now take - arguments. `InexactError(func::Symbol, type, -3)` now prints as - "ERROR: InexactError: func(type, -3)", `DomainError(val, - [msg])` prints as "ERROR: DomainError with val:\nmsg", - and `OverflowError(msg)` prints as "ERROR: OverflowError: msg". - ([#20005](https://github.com/JuliaLang/julia/issues/20005), [#22751](https://github.com/JuliaLang/julia/issues/22751), [#22761](https://github.com/JuliaLang/julia/issues/22761)) - - * The operating system identification functions: `is_linux`, `is_bsd`, `is_apple`, `is_unix`, - and `is_windows`, have been deprecated in favor of `Sys.islinux`, `Sys.isbsd`, `Sys.isapple`, - `Sys.isunix`, and `Sys.iswindows`, respectively ([#22182](https://github.com/JuliaLang/julia/issues/22182)). - - * The forms of `read`, `readstring`, and `eachline` that accepted both a `Cmd` object and an - input stream are deprecated. Use e.g. `read(pipeline(stdin, cmd))` instead ([#22762](https://github.com/JuliaLang/julia/issues/22762)). - - * The unexported type `AbstractIOBuffer` has been renamed to `GenericIOBuffer` ([#17360](https://github.com/JuliaLang/julia/issues/17360) [#22796](https://github.com/JuliaLang/julia/issues/22796)). - - * `IOBuffer(data::AbstractVector{UInt8}, read::Bool, write::Bool, maxsize::Integer)`, - `IOBuffer(read::Bool, write::Bool)`, and `IOBuffer(maxsize::Integer)` are - deprecated in favor of constructors taking keyword arguments ([#25872](https://github.com/JuliaLang/julia/issues/25872)). - - * `Display` has been renamed to `AbstractDisplay` ([#24831](https://github.com/JuliaLang/julia/issues/24831)). - - * Remaining vectorized methods over `SparseVector`s, particularly `floor`, `ceil`, - `trunc`, `round`, and most common transcendental functions such as `exp`, `log`, and - `sin` variants, have been deprecated in favor of dot-syntax ([#22961](https://github.com/JuliaLang/julia/issues/22961)). - - * The method `String(io::IOBuffer)` is deprecated to `String(take!(copy(io)))` ([#21438](https://github.com/JuliaLang/julia/issues/21438)). - - * The function `readstring` is deprecated in favor of `read(io, String)` ([#22793](https://github.com/JuliaLang/julia/issues/22793)) - - * The function `showall` is deprecated. Showing entire values is the default, unless an - `IOContext` specifying `:limit=>true` is in use ([#22847](https://github.com/JuliaLang/julia/issues/22847)). - - * `issubtype` has been deprecated in favor of `<:` (which used to be an alias for `issubtype`). - - * Calling `write` on non-isbits arrays is deprecated in favor of explicit loops or - `serialize` ([#6466](https://github.com/JuliaLang/julia/issues/6466)). - - * The default `startup.jl` file on Windows has been removed. Now must explicitly include the - full path if you need access to executables or libraries in the `Sys.BINDIR` directory, e.g. - `joinpath(Sys.BINDIR, "7z.exe")` for `7z.exe` ([#21540](https://github.com/JuliaLang/julia/issues/21540)). - - * `sqrtm` has been deprecated in favor of `sqrt` ([#23504](https://github.com/JuliaLang/julia/issues/23504)). - - * `expm` has been deprecated in favor of `exp` ([#23233](https://github.com/JuliaLang/julia/issues/23233)). - - * `logm` has been deprecated in favor of `log` ([#23505](https://github.com/JuliaLang/julia/issues/23505)). - - * `full` has been deprecated in favor of more specific, better defined alternatives. - On structured matrices `A`, consider instead `Matrix(A)`, `Array(A)`, - `SparseMatrixCSC(A)`, or `sparse(A)`. On sparse arrays `S`, consider instead - `Vector(S)`, `Matrix(S)`, or `Array(S)` as appropriate. On factorizations `F`, - consider instead `Matrix(F)`, `Array(F)`, `AbstractMatrix(F)`, or `AbstractArray(F)`. - On implicit orthogonal factors `Q`, consider instead `Matrix(Q)` or `Array(Q)`; for - implicit orthogonal factors that can be recovered in square or truncated form, - see the deprecation message for square recovery instructions. On `Symmetric`, - `Hermitian`, or `AbstractTriangular` matrices `A`, consider instead `Matrix(S)`, - `Array(S)`, `SparseMatrixCSC(S)`, or `sparse(S)`. On `Symmetric` matrices `A` - particularly, consider instead `LinAlg.copytri!(copy(parent(A)), A.uplo)`. On - `Hermitian` matrices `A` particularly, consider instead - `LinAlg.copytri!(copy(parent(A)), A.uplo, true)`. On `UpperTriangular` matrices `A` - particularly, consider instead `triu!(copy(parent(A)))`. On `LowerTriangular` matrices - `A` particularly, consider instead `tril!(copy(parent(A)))` ([#24250](https://github.com/JuliaLang/julia/issues/24250)). - - * `speye` has been deprecated in favor of `I`, `sparse`, and `SparseMatrixCSC` - constructor methods ([#24356](https://github.com/JuliaLang/julia/issues/24356)). - - * Calling `union` with no arguments is deprecated; construct an empty set with an appropriate - element type using `Set{T}()` instead ([#23144](https://github.com/JuliaLang/julia/issues/23144)). - - * Vectorized `DateTime`, `Date`, and `format` methods have been deprecated in favor of - dot-syntax ([#23207](https://github.com/JuliaLang/julia/issues/23207)). - - * `Base.cpad` has been removed; use an appropriate combination of `rpad` and `lpad` - instead ([#23187](https://github.com/JuliaLang/julia/issues/23187)). - - * `ctranspose` and `ctranspose!` have been deprecated in favor of `adjoint` and `adjoint!`, - respectively ([#23235](https://github.com/JuliaLang/julia/issues/23235)). - - * `filter` and `filter!` on dictionaries now pass a single `key=>value` pair to the - argument function, instead of two arguments ([#17886](https://github.com/JuliaLang/julia/issues/17886)). - - * `rol`, `rol!`, `ror`, and `ror!` have been deprecated in favor of specialized methods for - `circshift`/`circshift!` ([#23404](https://github.com/JuliaLang/julia/issues/23404)). - - * `Base.SparseArrays.SpDiagIterator` has been removed ([#23261](https://github.com/JuliaLang/julia/issues/23261)). - - * The function `cfunction`, has been deprecated in favor of a macro form `@cfunction`. - Most existing uses can be upgraded simply by adding a `@`. - The new syntax now additionally supports allocating closures at runtime, - for dealing with C APIs that don't provide a separate `void* env`-type callback - argument. ([#26486](https://github.com/JuliaLang/julia/issues/26486)) - - * `diagm(v::AbstractVector, k::Integer=0)` has been deprecated in favor of - `diagm(k => v)` ([#24047](https://github.com/JuliaLang/julia/issues/24047)). - - * `diagm(x::Number)` has been deprecated in favor of `fill(x, 1, 1)` ([#24047](https://github.com/JuliaLang/julia/issues/24047)). - - * `diagm(A::SparseMatrixCSC)` has been deprecated in favor of - `spdiagm(sparsevec(A))` ([#23341](https://github.com/JuliaLang/julia/issues/23341)). - - * `diagm(A::BitMatrix)` has been deprecated, use `diagm(0 => vec(A))` or - `BitMatrix(Diagonal(vec(A)))` instead ([#23373](https://github.com/JuliaLang/julia/issues/23373), [#24047](https://github.com/JuliaLang/julia/issues/24047)). - - * `ℯ` (written as `\mscre` or `\euler`) is now the only (by default) exported - name for Euler's number, and the type has changed from `Irrational{:e}` to - `Irrational{:ℯ}` ([#23427](https://github.com/JuliaLang/julia/issues/23427)). - - * The mathematical constants `π`, `pi`, `ℯ`, `e`, `γ`, `eulergamma`, `catalan`, `φ` and - `golden` have been moved from `Base` to a new module; `Base.MathConstants`. - Only `π`, `pi` and `ℯ` are now exported by default from `Base` ([#23427](https://github.com/JuliaLang/julia/issues/23427)). - - * `eu` (previously an alias for `ℯ`) has been deprecated in favor of `ℯ` (or `MathConstants.e`) ([#23427](https://github.com/JuliaLang/julia/issues/23427)). - - * `GMP.gmp_version()`, `GMP.GMP_VERSION`, `GMP.gmp_bits_per_limb()`, and `GMP.GMP_BITS_PER_LIMB` - have been renamed to `GMP.version()`, `GMP.VERSION`, `GMP.bits_per_limb()`, and `GMP.BITS_PER_LIMB`, - respectively. Similarly, `MPFR.get_version()`, has been renamed to `MPFR.version()` ([#23323](https://github.com/JuliaLang/julia/issues/23323)). Also, - `LinAlg.LAPACK.laver()` has been renamed to `LinAlg.LAPACK.version()` and now returns a `VersionNumber`. - - * `select`, `select!`, `selectperm` and `selectperm!` have been renamed respectively to - `partialsort`, `partialsort!`, `partialsortperm` and `partialsortperm!` ([#23051](https://github.com/JuliaLang/julia/issues/23051)). - - * The `Range` abstract type has been renamed to `AbstractRange` ([#23570](https://github.com/JuliaLang/julia/issues/23570)). - - * `map` on dictionaries previously operated on `key=>value` pairs. This behavior is deprecated, - and in the future `map` will operate only on values ([#5794](https://github.com/JuliaLang/julia/issues/5794)). - - * `map` on sets previously returned a `Set`, possibly changing the order or number of elements. This - behavior is deprecated and in the future `map` will preserve order and number of elements ([#26980](https://github.com/JuliaLang/julia/issues/26980)). - - * Previously, broadcast defaulted to treating its arguments as scalars if they were not - arrays. This behavior is deprecated, and in the future `broadcast` will default to - iterating over all its arguments. Wrap arguments you wish to be treated as scalars with - `Ref()` or a 1-tuple. Package developers can choose to allow a non-iterable type `T` to - always behave as a scalar by implementing `broadcastable(x::T) = Ref(x)` ([#26212](https://github.com/JuliaLang/julia/issues/26212)). - - * Automatically broadcasted `+` and `-` for `array + scalar`, `scalar - array`, and so-on have - been deprecated due to inconsistency with linear algebra. Use `.+` and `.-` for these operations - instead ([#22880](https://github.com/JuliaLang/julia/issues/22880), [#22932](https://github.com/JuliaLang/julia/issues/22932)). - - * `flipbits!(B)` is deprecated in favor of using in-place broadcast to negate each element: - `B .= .!B` ([#27067](https://github.com/JuliaLang/julia/issues/27067)). - - * `isleaftype` is deprecated in favor of the simpler predicates `isconcretetype` and `isdispatchtuple`. - Concrete types are those that might equal `typeof(x)` for some `x`; - `isleaftype` included some types for which this is not true. Those are now categorized more precisely - as "dispatch tuple types" and "!has_free_typevars" (not exported). ([#17086](https://github.com/JuliaLang/julia/issues/17086), [#25496](https://github.com/JuliaLang/julia/issues/25496)) - - * `contains(eq, itr, item)` is deprecated in favor of `any` with a predicate ([#23716](https://github.com/JuliaLang/julia/issues/23716)). - - * `spdiagm(x::AbstractVector)` has been deprecated in favor of `sparse(Diagonal(x))` - alternatively `spdiagm(0 => x)` ([#23757](https://github.com/JuliaLang/julia/issues/23757)). - - * `spdiagm(x::AbstractVector, d::Integer)` and `spdiagm(x::Tuple{<:AbstractVector}, d::Tuple{<:Integer})` - have been deprecated in favor of `spdiagm(d => x)` and `spdiagm(d[1] => x[1], d[2] => x[2], ...)` - respectively. The new `spdiagm` implementation now always returns a square matrix ([#23757](https://github.com/JuliaLang/julia/issues/23757)). - - * `spones(A::AbstractSparseArray)` has been deprecated in favor of - `LinAlg.fillstored!(copy(A), 1)` ([#25037](https://github.com/JuliaLang/julia/issues/25037)). - - * Constructors for `LibGit2.UserPasswordCredentials` and `LibGit2.SSHCredentials` which take a - `prompt_if_incorrect` argument are deprecated. Instead, prompting behavior is controlled using - the `allow_prompt` keyword in the `LibGit2.CredentialPayload` constructor ([#23690](https://github.com/JuliaLang/julia/issues/23690)). - - * `gradient` is deprecated and will be removed in the next release ([#23816](https://github.com/JuliaLang/julia/issues/23816)). - - * The timing functions `tic`, `toc`, and `toq` are deprecated in favor of `@time` and `@elapsed` - ([#17046](https://github.com/JuliaLang/julia/issues/17046)). - - * Methods of `findfirst`, `findnext`, `findlast`, and `findprev` that accept a value to - search for are deprecated in favor of passing a predicate ([#19186](https://github.com/JuliaLang/julia/issues/19186), [#10593](https://github.com/JuliaLang/julia/issues/10593)). - - * `find` functions now operate only on booleans by default. To look for non-zeros, use - `x->x!=0` or `!iszero` ([#23120](https://github.com/JuliaLang/julia/issues/23120)). - - * The ability of `reinterpret` to yield `Array`s of different type than the underlying storage - has been removed. The `reinterpret` function is still available, but now returns a - `ReinterpretArray`. The three argument form of `reinterpret` that implicitly reshapes - has been deprecated ([#23750](https://github.com/JuliaLang/julia/issues/23750)). - - * `bits` has been deprecated in favor of `bitstring` ([#24281](https://github.com/JuliaLang/julia/issues/24281), [#24263](https://github.com/JuliaLang/julia/issues/24263)). - - * `num2hex` and `hex2num` have been deprecated in favor of `reinterpret` combined with `parse`/`hex` ([#22088](https://github.com/JuliaLang/julia/issues/22088)). - - * `copy!` is deprecated for `AbstractSet` and `AbstractDict`, with the intention to re-enable - it with a cleaner meaning in a future version ([#24844](https://github.com/JuliaLang/julia/issues/24844)). - - * `copy!` (resp. `unsafe_copy!`) is deprecated for `AbstractArray` and is renamed `copyto!` - (resp. `unsafe_copyto!`); it will be re-introduced with a different meaning in a future - version ([#24808](https://github.com/JuliaLang/julia/issues/24808)). - - * `a:b` is deprecated for constructing a `StepRange` when `a` and `b` have physical units - (Dates and Times). Use `a:s:b`, where `s = Dates.Day(1)` or `s = Dates.Second(1)`. - - * `trues(A::AbstractArray)` and `falses(A::AbstractArray)` are deprecated in favor of - `trues(size(A))` and `falses(size(A))` respectively ([#24595](https://github.com/JuliaLang/julia/issues/24595)). - - * `workspace` is discontinued, check out [Revise.jl](https://github.com/timholy/Revise.jl) - for an alternative workflow ([#25046](https://github.com/JuliaLang/julia/issues/25046)). - - * `cumsum`, `cumprod`, `accumulate`, their mutating versions, and `diff` all now require a `dim` - argument instead of defaulting to using the first dimension unless there is only - one dimension ([#24684](https://github.com/JuliaLang/julia/issues/24684), [#25457](https://github.com/JuliaLang/julia/issues/25457)). - - * The `sum_kbn` and `cumsum_kbn` functions have been moved to the - [KahanSummation](https://github.com/JuliaMath/KahanSummation.jl) package ([#24869](https://github.com/JuliaLang/julia/issues/24869)). - - * `isnumber` has been renamed to `isnumeric` ([#25021](https://github.com/JuliaLang/julia/issues/25021)). - - * `isalpha` has been renamed to `isletter` ([#26932](https://github.com/JuliaLang/julia/issues/26932)). - - * `is_assigned_char` and `normalize_string` have been renamed to `isassigned` and - `normalize`, and moved to the new `Unicode` standard library module. - `graphemes` has also been moved to that module ([#25021](https://github.com/JuliaLang/julia/issues/25021)). - - * Sparse array functionality has moved to the `SparseArrays` standard library module ([#25249](https://github.com/JuliaLang/julia/issues/25249)). - - * Linear algebra functionality, and specifically the `LinAlg` module has moved to the - `LinearAlgebra` standard library module ([#25571](https://github.com/JuliaLang/julia/issues/25571)). - - * `@printf` and `@sprintf` have been moved to the `Printf` standard library ([#23929](https://github.com/JuliaLang/julia/issues/23929),[#25056](https://github.com/JuliaLang/julia/issues/25056)). - - * The `Libdl` module has moved to the `Libdl` standard library module ([#25459](https://github.com/JuliaLang/julia/issues/25459)). - - * The aliases `Complex32`, `Complex64` and `Complex128` have been deprecated in favor of `ComplexF16`, - `ComplexF32` and `ComplexF64` respectively ([#24647](https://github.com/JuliaLang/julia/issues/24647)). - - * `Base.parentindexes` and `SharedArrays.localindexes` have been renamed to `parentindices` - and `localindices`, respectively. Similarly, the `indexes` field in the `SubArray` type - has been renamed to `indices` without deprecation ([#25088](https://github.com/JuliaLang/julia/issues/25088)). - - * `Associative` has been deprecated in favor of `AbstractDict` ([#25012](https://github.com/JuliaLang/julia/issues/25012)). - - * `Void` has been renamed back to `Nothing` with an alias `Cvoid` for use when calling C - with a return type of `Cvoid` or a return or argument type of `Ptr{Cvoid}` ([#25162](https://github.com/JuliaLang/julia/issues/25162)). - - * `Nullable{T}` has been deprecated and moved to the Nullables package ([#23642](https://github.com/JuliaLang/julia/issues/23642)). Use - `Union{T, Nothing}` instead, or `Union{Some{T}, Nothing}` if `nothing` is a possible - value (i.e. `Nothing <: T`). `isnull(x)` can be replaced with `x === nothing` and - `unsafe_get`/`get` can be dropped or replaced with `coalesce`. - `NullException` has been removed. - - * `unshift!` and `shift!` have been renamed to `pushfirst!` and `popfirst!` ([#23902](https://github.com/JuliaLang/julia/issues/23902)) - - * `ipermute!` has been deprecated in favor of `invpermute!` ([#25168](https://github.com/JuliaLang/julia/issues/25168)). - - * `CartesianRange` has been renamed `CartesianIndices` ([#24715](https://github.com/JuliaLang/julia/issues/24715)). - - * `sub2ind` and `ind2sub` are deprecated in favor of using `CartesianIndices` and `LinearIndices` ([#24715](https://github.com/JuliaLang/julia/issues/24715)). - - * `getindex(F::Factorization, s::Symbol)` (usually seen as e.g. `F[:Q]`) is deprecated - in favor of dot overloading (`getproperty`) so factors should now be accessed as e.g. - `F.Q` instead of `F[:Q]` ([#25184](https://github.com/JuliaLang/julia/issues/25184)). - - * `search` and `rsearch` have been deprecated in favor of `findfirst`/`findnext` and - `findlast`/`findprev` respectively, in combination with curried `isequal` and `in` - predicates for some methods ([#24673](https://github.com/JuliaLang/julia/issues/24673)). - - * `search(buf::IOBuffer, delim::UInt8)` has been deprecated in favor of either `occursin(delim, buf)` - (to test containment) or `readuntil(buf, delim)` (to read data up to `delim`) ([#26600](https://github.com/JuliaLang/julia/issues/26600)). - - * `ismatch(regex, str)` has been deprecated in favor of `contains(str, regex)` ([#24673](https://github.com/JuliaLang/julia/issues/24673)). - - * `matchall` has been deprecated in favor of `collect(m.match for m in eachmatch(r, s))` ([#26071](https://github.com/JuliaLang/julia/issues/26071)). - - * `similar(::Associative)` has been deprecated in favor of `empty(::Associative)`, and - `similar(::Associative, ::Pair{K, V})` has been deprecated in favour of - `empty(::Associative, K, V)` ([#24390](https://github.com/JuliaLang/julia/issues/24390)). - - * `findin(a, b)` has been deprecated in favor of `findall(in(b), a)` ([#24673](https://github.com/JuliaLang/julia/issues/24673)). - - * `module_name` has been deprecated in favor of a new, general `nameof` function. Similarly, - the unexported `Base.function_name` and `Base.datatype_name` have been deprecated in favor - of `nameof` methods ([#25622](https://github.com/JuliaLang/julia/issues/25622)). - - * The module `Random.dSFMT` is renamed `Random.DSFMT` ([#25567](https://github.com/JuliaLang/julia/issues/25567)). - - * `Random.RandomDevice(unlimited::Bool)` (on non-Windows systems) is deprecated in favor of - `Random.RandomDevice(; unlimited=unlimited)` ([#25668](https://github.com/JuliaLang/julia/issues/25668)). - - * The generic implementations of `strides(::AbstractArray)` and `stride(::AbstractArray, ::Int)` - have been deprecated. Subtypes of `AbstractArray` that implement the newly introduced strided - array interface should define their own `strides` method ([#25321](https://github.com/JuliaLang/julia/issues/25321)). - - * `module_parent`, `Base.datatype_module`, and `Base.function_module` have been deprecated - in favor of `parentmodule` ([#TODO]). - - * `rand(t::Tuple{Vararg{Int}})` is deprecated in favor of `rand(Float64, t)` or `rand(t...)`; - `rand(::Tuple)` will have another meaning in the future ([#25429](https://github.com/JuliaLang/julia/issues/25429), [#25278](https://github.com/JuliaLang/julia/issues/25278)). - - * `randjump`, which produced an array, is deprecated in favor of the - scalar version `Future.randjump` used with `accumulate` ([#27746](https://github.com/JuliaLang/julia/issues/27746)). - - * The `assert` function (and `@assert` macro) have been documented that they are not guaranteed to run under various optimization levels and should therefore not be used to e.g. verify passwords. - - * `ObjectIdDict` has been deprecated in favor of `IdDict{Any,Any}` ([#25210](https://github.com/JuliaLang/julia/issues/25210)). - - * `gc` and `gc_enable` have been deprecated in favor of `GC.gc` and `GC.enable` ([#25616](https://github.com/JuliaLang/julia/issues/25616)). - - * `Base.@gc_preserve` has been deprecated in favor of `GC.@preserve` ([#25616](https://github.com/JuliaLang/julia/issues/25616)). - - * `print_shortest` has been discontinued, but is still available in the `Base.Grisu` - submodule ([#25745](https://github.com/JuliaLang/julia/issues/25745)). - - * `scale!` has been deprecated in favor of `mul!`, `lmul!`, and `rmul!` ([#25701](https://github.com/JuliaLang/julia/issues/25701), [#25812](https://github.com/JuliaLang/julia/issues/25812)). - - * The `remove_destination` keyword argument to `cp`, `mv`, and the unexported `cptree` - has been renamed to `force` ([#25979](https://github.com/JuliaLang/julia/issues/25979)). - - * `contains` has been deprecated in favor of a more general `occursin` function, which - takes its arguments in reverse order from `contains` ([#26283](https://github.com/JuliaLang/julia/issues/26283)). - - * `Regex` objects are no longer callable. Use `occursin` instead ([#26283](https://github.com/JuliaLang/julia/issues/26283)). - - * The methods of `range` based on positional arguments have been deprecated in favor of - keyword arguments ([#25896](https://github.com/JuliaLang/julia/issues/25896)). - - * `linspace` has been deprecated in favor of `range` with `stop` and `length` keyword - arguments ([#25896](https://github.com/JuliaLang/julia/issues/25896)). - - * `LinSpace` has been renamed to `LinRange` ([#25896](https://github.com/JuliaLang/julia/issues/25896)). - - * `logspace` has been deprecated to its definition ([#25896](https://github.com/JuliaLang/julia/issues/25896)). - - * `endof(a)` has been renamed to `lastindex(a)`, and the `end` keyword in indexing expressions now - lowers to either `lastindex(a)` (in the case with only one index) or `lastindex(a, d)` (in cases - where there is more than one index and `end` appears at dimension `d`) ([#23554](https://github.com/JuliaLang/julia/issues/23554), [#25763](https://github.com/JuliaLang/julia/issues/25763)). - - * `DateTime()`, `Date()`, and `Time()` have been deprecated, instead use `DateTime(1)`, `Date(1)` - and `Time(0)` respectively ([#23724](https://github.com/JuliaLang/julia/issues/23724)). - - * The fallback method `^(x, p::Integer)` is deprecated. If your type relied on this definition, - add a method such as `^(x::MyType, p::Integer) = Base.power_by_squaring(x, p)` ([#23332](https://github.com/JuliaLang/julia/issues/23332)). - - * `DevNull`, `STDIN`, `STDOUT`, and `STDERR` have been renamed to `devnull`, `stdin`, `stdout`, - and `stderr`, respectively ([#25786](https://github.com/JuliaLang/julia/issues/25786)). - - * `wait` and `fetch` on `Task` now resemble the interface of `Future`. - - * `showcompact(io, x...)` has been deprecated in favor of - `show(IOContext(io, :compact => true), x...)` ([#26080](https://github.com/JuliaLang/julia/issues/26080)). - Use `sprint(show, x..., context=:compact => true)` instead of `sprint(showcompact, x...)`. - - * `isupper`, `islower`, `ucfirst` and `lcfirst` have been deprecated in favor of `isuppercase`, - `islowercase`, `uppercasefirst` and `lowercasefirst`, respectively ([#26442](https://github.com/JuliaLang/julia/issues/26442)). - - * `signif` has been deprecated in favor of the `sigdigits` keyword argument to `round`. - - * `Base.IntSet` has been deprecated in favor of `Base.BitSet` ([#24282](https://github.com/JuliaLang/julia/issues/24282)). - - * `setrounding` has been deprecated for `Float32` and `Float64`, as the behaviour was too unreliable ([#26935](https://github.com/JuliaLang/julia/issues/26935)). - - * `gamma`, `lgamma`, `beta`, `lbeta` and `lfact` have been moved to - [SpecialFunctions.jl](https://github.com/JuliaMath/SpecialFunctions.jl) ([#27459](https://github.com/JuliaLang/julia/issues/27459), [#27473](https://github.com/JuliaLang/julia/issues/27473)). - - * `atan2` is now a 2-argument method of `atan` ([#27248](https://github.com/JuliaLang/julia/issues/27248)). - - * The functions `eigs` and `svds` have been moved to the `Arpack.jl` package ([#27616](https://github.com/JuliaLang/julia/issues/27616)). - - * `vecdot` and `vecnorm` are deprecated in favor of `dot` and `norm`, respectively ([#27401](https://github.com/JuliaLang/julia/issues/27401)). - - * `clipboard` has been moved to the `InteractiveUtils` standard library package - (along with other utilities mostly used at the interactive prompt, such as `edit` - and `less`) ([#27635](https://github.com/JuliaLang/julia/issues/27635)). - - * `ndigits(n, b, [pad])` is deprecated in favor of `ndigits(n, base=b, pad=pad)` ([#27908](https://github.com/JuliaLang/julia/issues/27908)). - - * `squeeze` is deprecated in favor of `dropdims`. - - * `srand` is deprecated in favor of the unexported `Random.seed!` ([#27726](https://github.com/JuliaLang/julia/issues/27726)). - - * `realmin`/`realmax` are deprecated in favor of `floatmin`/`floatmax` ([#28302](https://github.com/JuliaLang/julia/issues/28302)). - - * `sortrows`/`sortcols` have been deprecated in favor of the more general `sortslices`. - - * `nextpow2`/`prevpow2` have been deprecated in favor of the more general `nextpow`/`prevpow` functions. +The old package manager (now called `OldPkg`) has been moved to a +separate repository at https://github.com/JuliaArchive/OldPkg.jl ([#27930](https://github.com/JuliaLang/julia/issues/27930)) Command-line option changes --------------------------- - * New option `--warn-overwrite={yes|no}` to control the warning for overwriting method - definitions. The default is `no` ([#23002](https://github.com/JuliaLang/julia/issues/23002)). - - * New option `--banner={yes,no}` allows suppressing or forcing the printing of the - startup banner, overriding the default behavior (banner in REPL, no banner otherwise). - The `--quiet` option implies `--banner=no` even in REPL mode but can be overridden by - passing `--quiet` together with `--banner=yes` ([#23342](https://github.com/JuliaLang/julia/issues/23342)). - - * The option `--precompiled` has been renamed to `--sysimage-native-code` ([#23054](https://github.com/JuliaLang/julia/issues/23054)). - - * The option `--compilecache` has been renamed to `--compiled-modules` ([#23054](https://github.com/JuliaLang/julia/issues/23054)). - diff --git a/codex/devdocs/object.md b/codex/devdocs/object.md index 49d1e46..cf9223f 100644 --- a/codex/devdocs/object.md +++ b/codex/devdocs/object.md @@ -1,6 +1,6 @@ # Memory layout of Julia Objects -## Object layout (`jl_value_t`) +## Object layout (jl_value_t) The `jl_value_t` struct is the name for a block of memory owned by the Julia Garbage Collector, representing the data associated with a Julia object in memory. Absent any type information, it diff --git a/codex/index.md b/codex/index.md index c7420bc..855e45d 100644 --- a/codex/index.md +++ b/codex/index.md @@ -1,8 +1,12 @@ -# Julia 0.7 Documentation +# Julia 1.0 Documentation -Welcome to the documentation for Julia 0.7. +Welcome to the documentation for Julia 1.0. -Please read the [release notes](NEWS.md) to see what has changed since the last release. +Please read the [release blog post](https://julialang.org/blog/2018/08/one-point-zero) for a general overview of the language and +many of the changes since Julia v0.6. Note that version 0.7 was released alongside +1.0 to provide an upgrade path for packages and code that predates the 1.0 release. +The only difference between 0.7 and 1.0 is the removal of deprecation warnings. +For a complete list of all the changes since 0.6, see the [release notes for version 0.7](https://docs.julialang.org/en/v0.7.0/NEWS/) ### [Introduction](@id man-introduction) diff --git a/codex/manual/profile.md b/codex/manual/profile.md index 00d91cf..e3403cd 100644 --- a/codex/manual/profile.md +++ b/codex/manual/profile.md @@ -312,3 +312,34 @@ memory allocation). The recommended procedure is to force compilation by executi you want to analyze, then call [`Profile.clear_malloc_data()`](@ref) to reset all allocation counters. Finally, execute the desired commands and quit Julia to trigger the generation of the `.mem` files. + +# External Profiling + +Currently Julia supports `Intel VTune`, `OProfile` and `perf` as external profiling tools. + +Depending on the tool you choose, compile with `USE_INTEL_JITEVENTS`, `USE_OPROFILE_JITEVENTS` and +`USE_PERF_JITEVENTS` set to 1 in `Make.user`. Multiple flags are supported. + +Before running Julia set the environment variable `ENABLE_JITPROFILING` to 1. + +Now you have a multitude of ways to employ those tools! +For example with `OProfile` you can try a simple recording : + +``` +>ENABLE_JITPROFILING=1 sudo operf -Vdebug ./julia test/fastmath.jl +>opreport -l `which ./julia` +``` + +Or similary with with `perf` : + +``` +$ ENABLE_JITPROFILING=1 perf record -o /tmp/perf.data --call-graph dwarf ./julia /test/fastmath.jl +$ perf report --call-graph -G +``` + +There are many more interesting things that you can measure about your program, to get a comprehensive list +please read the [Linux perf examples page](http://www.brendangregg.com/perf.html). + +Remember that perf saves for each execution a `perf.data` file that, even for small programs, can get +quite large. Also the perf LLVM module saves temporarly debug objects in `~/.debug/jit`, remember +to clean that folder frequently. diff --git a/codex/manual/types.md b/codex/manual/types.md index 7cd8c58..44eb1c7 100644 --- a/codex/manual/types.md +++ b/codex/manual/types.md @@ -1383,7 +1383,7 @@ for cases where you don't need a more elaborate hierarchy. julia> struct Val{x} end -julia> Base.@pure Val(x) = Val{x}() +julia> Val(x) = Val{x}() Val ``` diff --git a/codex/stdlib/REPL.md b/codex/stdlib/REPL.md index 42348a1..0920ab3 100644 --- a/codex/stdlib/REPL.md +++ b/codex/stdlib/REPL.md @@ -6,18 +6,12 @@ it has a searchable history, tab-completion, many helpful keybindings, and dedic shell modes. The REPL can be started by simply calling `julia` with no arguments or double-clicking on the executable: -``` -$ julia - _ - _ _ _(_)_ | A fresh approach to technical computing - (_) | (_) (_) | Documentation: https://docs.julialang.org - _ _ _| |_ __ _ | Type "?help" for help. - | | | | | | |/ _` | | - | | |_| | | | (_| | | Version 0.6.0-dev.2493 (2017-01-31 18:53 UTC) - _/ |\__'_|_|_|\__'_| | Commit c99e12c* (0 days old master) -|__/ | x86_64-linux-gnu - -julia> +```@eval +io = IOBuffer() +Base.banner(io) +banner = String(take!(io)) +import Markdown +Markdown.parse("```\n\$ julia\n\n$(banner)\njulia>\n```") ``` To exit the interactive session, type `^D` -- the control key together with the `d` key on a blank diff --git a/make.jl b/make.jl index 46ef699..bf972bf 100644 --- a/make.jl +++ b/make.jl @@ -39,7 +39,7 @@ const t_Manual = "매뉴얼" const PAGES = [ t_Home => "index.md", - hide("NEWS.md"), + # hide("NEWS.md"), t_Manual => [ "manual/getting-started.md", "manual/variables.md", diff --git a/src/NEWS.md b/src/NEWS.md index 740f802..ac7b3ae 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -1,1369 +1,29 @@ -줄리아 v0.7.0 릴리즈 노트 -======================== +Julia v1.0.0 Release Notes +========================== -새로 추가된 기능 ----------------- - - * 지역 변수가 정의되었는지 알아볼 때 `@isdefined 변수이름` 매크로를 사용합니다 ([#22281](https://github.com/JuliaLang/julia/pull/22281)). - - * 함수 인자에서 터플 배분(destructuring): `(x, y)`와 같은 표현을 함수 인자 이름에 사용하면, - `x`와 `y`라는 지역 변수로 인자를 배분합니다. 할당문 `(x, y) = arg` 처럼요 ([#6614](https://github.com/JuliaLang/julia/issues/6614)). - - * 네임드 터플(이름을 갖는 터플, named tuples). 문법은 `(a=1, b=2)` 이런 식입니다. 터플처럼 쓰면 되는데 - .이름 `t.a` 이런 식으로 해당 요소에 접근할 수 있습니다 ([#22194](https://github.com/JuliaLang/julia/issues/22194)). - - * 키워드 인자 컨테이너(`f(; kw...)` 에서 `kw`)는 네임드 터플(named tuples)을 기반으로 합니다. `haskey`와 같은 딕셔너리 함수로 인덱싱할 수 있고, - 이름-값 쌍은 `pairs(kw)`를 사용하여 차례대로 접근할 수 있습니다. `kw`는 더 이상 같은 인자 이름을 중복하여 쓸 수 없습니다 ([#4916](https://github.com/JuliaLang/julia/issues/4916)). - - * 사용자 정의 infix 연산자를 유니코드 결합 기호, 부호, 윗/아래 첨자로 정의할 수 있습니다. - 예를 들어 `+̂ₐ″`는 `+`와 같은 우선순위의 infix 연산자로 파싱 됩니다 ([#22089](https://github.com/JuliaLang/julia/issues/22089)). - - * 매크로 호출 문법 `@macroname[args]`은 이제 `@macroname([args])`로 파싱 합니다 ([#23519](https://github.com/JuliaLang/julia/issues/23519)). - - * `if @generated ...; else ...; end` 문은 `@generated` 처리한 것과 보통 구현을 모두 제공합니다. - 둘러 싼 코드는 공통으로 이들에 적용됩니다 ([#23168](https://github.com/JuliaLang/julia/issues/23168)). - - * `⟂` (`\perp`) 연산자가 비교 우위를 갖습니다 ([#24404](https://github.com/JuliaLang/julia/issues/24404)). - - * `missing` 싱글턴 객체(`Missing` 타입)는 누락된 값을 표현하는데 씁니다 ([#24653](https://github.com/JuliaLang/julia/issues/24653)). - 표준 연산자와 수학 함수를 통해 전달되며, 이를 통해 SQL의 `NULL`이나 R의 `NA`와 같은 세개의 상태를 갖는 로직을 구현합니다. - - * 점(.)을 사용한 필드 접근은 `Base.getproperty`와 `Base.setproperty!`를 오버로딩하여 확장할 수 있습니다 ([#1974](https://github.com/JuliaLang/julia/issues/1974)). - - * `@enum` 매크로를 쓸 때 `begin` 블럭으로 `Enum` 값을 특정할 수 있습니다 ([#25424](https://github.com/JuliaLang/julia/issues/25424)). - - * 키워드 인자를 요구할 수 있습니다: 기본값을 생략한 경우, 호출하는 쪽에서 키워드 값을 지정하지 않으면 - 예외를 던집니다 ([#25830](https://github.com/JuliaLang/julia/issues/25830)). - - * pair 연산자 `=>` 또한 `.=>`로 브로드캐스팅 할 수 있습니다. 파싱 에러(parsing error) 였던 것을 고쳤습니다. ([#27447](https://github.com/JuliaLang/julia/issues/27447)) +New language features +--------------------- Language changes ---------------- - * The syntax for parametric methods, `function f{T}(x::T)`, has been - changed to `function f(x::T) where {T}` ([#11310](https://github.com/JuliaLang/julia/issues/11310)). - - * The fallback constructor that calls `convert` is deprecated. Instead, new types should - prefer to define constructors, and add `convert` methods that call those constructors - only as necessary ([#15120](https://github.com/JuliaLang/julia/issues/15120)). - - * The syntax `1.+2` is deprecated, since it is ambiguous: it could mean either - `1 .+ 2` (the current meaning) or `1. + 2` ([#19089](https://github.com/JuliaLang/julia/issues/19089)). - - * Mutable structs with no fields are no longer singletons; it is now possible to make - multiple instances of them that can be distinguished by `===` ([#25854](https://github.com/JuliaLang/julia/issues/25854)). - Zero-size immutable structs are still singletons. - - * In string and character literals, backslash `\` may no longer - precede unrecognized escape characters ([#22800](https://github.com/JuliaLang/julia/issues/22800)). - - * Juxtaposing binary, octal, and hexadecimal literals is deprecated, since it can lead to - confusing code such as `0xapi == 0xa * pi` ([#16356](https://github.com/JuliaLang/julia/issues/16356)). - - * Numeric literal juxtaposition now has slighty lower precedence than unary operators, - so for example `√2x` parses as `(√2) * x` ([#27641](https://github.com/JuliaLang/julia/issues/27641)). - - * Declaring arguments as `x::ANY` to avoid specialization has been replaced - by `@nospecialize x`. ([#22666](https://github.com/JuliaLang/julia/issues/22666)). - - This can also be used in global scope, to apply to all subsequent method definitions - in the module (until `@specialize`). ([#28065](https://github.com/JuliaLang/julia/issues/28065)) - - * Keyword argument default values are now evaluated in successive scopes --- - the scope for each expression includes only previous keyword arguments, in - left-to-right order ([#17240](https://github.com/JuliaLang/julia/issues/17240)). - - * The parsing of `1<<2*3` as `1<<(2*3)` is deprecated, and will change to - `(1<<2)*3` in a future version ([#13079](https://github.com/JuliaLang/julia/issues/13079)). - - * The parsing of `<|` is now right associative. `|>` remains left associative ([#24153](https://github.com/JuliaLang/julia/issues/24153)). - - * `:` now parses like other operators, as a call to a function named `:`, instead of - calling `colon` ([#25947](https://github.com/JuliaLang/julia/issues/25947)). - - * `{ }` expressions now use `braces` and `bracescat` as expression heads instead - of `cell1d` and `cell2d`, and parse similarly to `vect` and `vcat` ([#8470](https://github.com/JuliaLang/julia/issues/8470)). - - * Nested `if` expressions that arise from the keyword `elseif` now use `elseif` - as their expression head instead of `if` ([#21774](https://github.com/JuliaLang/julia/issues/21774)). - - * `let` blocks now parse the same as `for` loops; the first argument is either an - assignment or `block` of assignments, and the second argument is a block of - statements ([#21774](https://github.com/JuliaLang/julia/issues/21774)). - - * `do` syntax now parses to an expression with head `:do`, instead of as a function - call ([#21774](https://github.com/JuliaLang/julia/issues/21774)). - - * Parsed and lowered forms of type definitions have been synchronized with their - new keywords ([#23157](https://github.com/JuliaLang/julia/issues/23157)). Expression heads are renamed as follows: - - + `type` => `struct` - - + `bitstype` => `primitive` (order of arguments is also reversed, to match syntax) - - + `composite_type` => `struct_type` - - + `bits_type` => `primitive_type` - - * The `global` keyword now only introduces a new binding if one doesn't already exist - in the module. - This means that assignment to a global (`global sin = 3`) may now throw the error: - "cannot assign variable Base.sin from module Main", rather than emitting a warning. - Additionally, the new bindings are now created before the statement is executed. - For example, `f() = (global sin = "gluttony"; nothing)` will now resolve which module - contains `sin` eagerly, rather than delaying that decision until `f` is run. ([#22984](https://github.com/JuliaLang/julia/issues/22984)). - - * `global const` declarations may no longer appear inside functions ([#12010](https://github.com/JuliaLang/julia/issues/12010)). - - * Uninitialized `BitArray` constructors of the form `BitArray[{N}](shape...)` have been - deprecated in favor of equivalents accepting `undef` (an alias for - `UndefInitializer()`) as their first argument, as in - `BitArray[{N}](undef, shape...)`. For example, `BitVector(3)` is now - `BitVector(undef, 3)`, `BitMatrix((2, 4))` is now - `BitMatrix(undef, (2, 4))`, and `BitArray{3}(11, 13, 17)` is now - `BitArray{3}(undef, 11, 14, 17)` ([#24785](https://github.com/JuliaLang/julia/issues/24785)). - - * Dispatch rules have been simplified: - method matching is now determined exclusively by subtyping; - the rule that method type parameters must also be captured has been removed. - Instead, attempting to access the unconstrained parameters will throw an `UndefVarError`. - Linting in package tests is recommended to confirm that the set of methods - which might throw `UndefVarError` when accessing the static parameters - (`need_to_handle_undef_sparam = Set{Any}(m.sig for m in Test.detect_unbound_args(Base, recursive=true))`) - is equal (`==`) to some known set (`expected = Set()`). ([#23117](https://github.com/JuliaLang/julia/issues/23117)) - - * `const` declarations on local variables were previously ignored. They now give a - warning, so that this syntax can be disallowed or given a new meaning in a - future version ([#5148](https://github.com/JuliaLang/julia/issues/5148)). - - * Placing an expression after `catch`, as in `catch f(x)`, is deprecated. - Use `catch; f(x)` instead ([#19987](https://github.com/JuliaLang/julia/issues/19987)). - - * In `for i = ...`, if a local variable `i` already existed it would be overwritten - during the loop. This behavior is deprecated, and in the future `for` loop variables - will always be new variables local to the loop ([#22314](https://github.com/JuliaLang/julia/issues/22314)). - The old behavior of overwriting an existing variable is available via `for outer i = ...`. - - * In `for i in x`, `x` used to be evaluated in a new scope enclosing the `for` loop. - Now it is evaluated in the scope outside the `for` loop. - - * In `for i in x, j in y`, all variables now have fresh bindings on each iteration of the - innermost loop. For example, an assignment to `i` will not be visible on the next `j` - loop iteration ([#330](https://github.com/JuliaLang/julia/issues/330)). - - * Variable bindings local to `while` loop bodies are now freshly allocated on each loop iteration, - matching the behavior of `for` loops. - - * Prefix `&` for by-reference arguments to `ccall` has been deprecated in favor of - `Ref` argument types ([#6080](https://github.com/JuliaLang/julia/issues/6080)). - - * The constructor `Ref(x::T)` now always returns a `Ref{T}` ([#21527](https://github.com/JuliaLang/julia/issues/21527)). - - * All line numbers in ASTs are represented by `LineNumberNode`s; the `:line` expression - head is no longer used. `QuoteNode`s are also consistently used for quoted symbols instead - of the `:quote` expression head (though `:quote` `Expr`s are still used for quoted - expressions) ([#23885](https://github.com/JuliaLang/julia/issues/23885)). - - * The `+` and `-` methods for `Number` and `UniformScaling` are not ambiguous anymore since `+` - and `-` no longer do automatic broadcasting. Hence, the methods for `UniformScaling` and `Number` are - no longer deprecated ([#23923](https://github.com/JuliaLang/julia/issues/23923)). - - * The keyword `importall` is deprecated. Use `using` and/or individual `import` statements - instead ([#22789](https://github.com/JuliaLang/julia/issues/22789)). - - * `reduce(+, [...])` and `reduce(*, [...])` no longer widen the iterated over arguments to - system word size. `sum` and `prod` still preserve this behavior. ([#22825](https://github.com/JuliaLang/julia/issues/22825)) - - * Like `_`, variable names consisting only of underscores can be assigned, - but accessing their values is deprecated ([#24221](https://github.com/JuliaLang/julia/issues/24221)). - - * Raw string literal escaping rules have been changed to make it possible to write all strings. - The rule is that backslashes escape both quotes and other backslashes, but only when a sequence - of backslashes precedes a quote character. Thus, 2n backslashes followed by a quote encodes n - backslashes and the end of the literal while 2n+1 backslashes followed by a quote encodes n - backslashes followed by a quote character ([#22926](https://github.com/JuliaLang/julia/issues/22926)). - - * `reprmime(mime, x)` has been renamed to `repr(mime, x)`, and along with `repr(x)` - and `sprint` it now accepts an optional `context` keyword for `IOContext` attributes. - `stringmime` has been moved to the Base64 stdlib package ([#25990](https://github.com/JuliaLang/julia/issues/25990)). - - * The syntax `(x...)` for constructing a tuple is deprecated; use `(x...,)` instead ([#24452](https://github.com/JuliaLang/julia/issues/24452)). - - * Non-parenthesized interpolated variables in strings, e.g. `"$x"`, must be followed - by a character that will never be an allowed identifier character (currently - operators, space/control characters, or common punctuation characters) ([#25231](https://github.com/JuliaLang/julia/issues/25231)). - - * The syntax `using A.B` can now only be used when `A.B` is a module, and the syntax - `using A: B` can only be used for adding single bindings ([#8000](https://github.com/JuliaLang/julia/issues/8000)). - - * `=>` now has its own precedence level, giving it strictly higher precedence than - `=` and `,` ([#25391](https://github.com/JuliaLang/julia/issues/25391)). - - * The conditions under which unary operators followed by `(` are parsed as prefix function - calls have changed ([#26154](https://github.com/JuliaLang/julia/issues/26154)). - - * `begin` is disallowed inside indexing expressions, in order to enable the syntax - `a[begin]` (for selecting the first element) in the future ([#23354](https://github.com/JuliaLang/julia/issues/23354)). - - * Underscores for `_italics_` and `__bold__` are now supported by the Base Markdown - parser. ([#25564](https://github.com/JuliaLang/julia/issues/25564)) - - * `…` (`\dots`) and `⁝` (`\tricolon`) are now parsed as binary operators ([#26262](https://github.com/JuliaLang/julia/issues/26262)). - - * Assignment syntax (`a=b`) inside square bracket expressions (e.g. `A[...]`, `[x, y]`) - is deprecated. It will likely be reclaimed in a later version for passing keyword - arguments. Note this does not affect updating operators like `+=` ([#25631](https://github.com/JuliaLang/julia/issues/25631)). - - * `try` blocks without `catch` or `finally` are no longer allowed. An explicit empty - `catch` block should be written instead ([#27554](https://github.com/JuliaLang/julia/issues/27554)). - - * `AbstractArray` types that use unconventional (not 1-based) indexing can now support - `size`, `length`, and `@inbounds`. To optionally enforce conventional indices, - you can `@assert !has_offset_axes(A)`. - - * Module pre-compilation is now the default for code loading. Adding a - `__precompile__()` declaration is no longer necessary, although - `__precompile__(false)` can still be used to opt-out ([#26991](https://github.com/JuliaLang/julia/issues/26991)). - Breaking changes ---------------- -This section lists changes that do not have deprecation warnings. - - * The package manager `Pkg` has been replaced with a new one. See the manual entries on - "Code Loading" and "Pkg" for documentation. - - * `replace(s::AbstractString, pat=>repl)` for function `repl` arguments formerly - passed a substring to `repl` in all cases. It now passes substrings for - string patterns `pat`, but a `Char` for character patterns (when `pat` is a - `Char`, collection of `Char`, or a character predicate) ([#25815](https://github.com/JuliaLang/julia/issues/25815)). - - * `readuntil` now does *not* include the delimiter in its result, matching the - behavior of `readline`. Pass `keep=true` to get the old behavior ([#25633](https://github.com/JuliaLang/julia/issues/25633)). - - * `lu` methods now return decomposition objects such as `LU` rather than - tuples of arrays or tuples of numbers ([#26997](https://github.com/JuliaLang/julia/issues/26997), [#27159](https://github.com/JuliaLang/julia/issues/27159), [#27212](https://github.com/JuliaLang/julia/issues/27212)). - - * `schur` methods now return decomposition objects such as `Schur` and - `GeneralizedSchur` rather than tuples of arrays ([#26997](https://github.com/JuliaLang/julia/issues/26997), [#27159](https://github.com/JuliaLang/julia/issues/27159), [#27212](https://github.com/JuliaLang/julia/issues/27212)). - - * `lq` methods now return decomposition objects such as `LQ` - rather than tuples of arrays ([#26997](https://github.com/JuliaLang/julia/issues/26997), [#27159](https://github.com/JuliaLang/julia/issues/27159), [#27212](https://github.com/JuliaLang/julia/issues/27212)). - - * `qr` methods now return decomposition objects such as `QR`, `QRPivoted`, - and `QRCompactWY` rather than tuples of arrays ([#26997](https://github.com/JuliaLang/julia/issues/26997), [#27159](https://github.com/JuliaLang/julia/issues/27159), [#27212](https://github.com/JuliaLang/julia/issues/27212)). - - * `svd` methods now return decomposition objects such as `SVD` and - `GeneralizedSVD` rather than tuples of arrays or tuples of numbers ([#26997](https://github.com/JuliaLang/julia/issues/26997), [#27159](https://github.com/JuliaLang/julia/issues/27159), [#27212](https://github.com/JuliaLang/julia/issues/27212)). - - * `countlines` now always counts the last non-empty line even if it does not - end with EOL, matching the behavior of `eachline` and `readlines` ([#25845](https://github.com/JuliaLang/julia/issues/25845)). - - * `getindex(s::String, r::UnitRange{Int})` now throws `StringIndexError` if `last(r)` - is not a valid index into `s` ([#22572](https://github.com/JuliaLang/julia/issues/22572)). - - * `ntuple(f, n::Integer)` throws `ArgumentError` if `n` is negative. - Previously an empty tuple was returned ([#21697](https://github.com/JuliaLang/julia/issues/21697)). - - * `⋮`, `⋱`, `⋰`, and `⋯` are now parsed as binary operators, not ordinary - identifiers. `≔`, `≕`, and `⩴` now parse with assignment rather than comparison - precedence ([#26262](https://github.com/JuliaLang/julia/issues/26262)). - - * Juxtaposing string literals (e.g. `"x"y`) is now a syntax error ([#20575](https://github.com/JuliaLang/julia/issues/20575)). - - * `finalizer(function, object)` now returns `object` rather than `nothing` ([#24679](https://github.com/JuliaLang/julia/issues/24679)). - - * The constructor of `SubString` now checks if the requested view range - is defined by valid indices in the parent `AbstractString` ([#22511](https://github.com/JuliaLang/julia/issues/22511)). - - * Macro calls with `for` expressions are now parsed as generators inside - function argument lists ([#18650](https://github.com/JuliaLang/julia/issues/18650)). Examples: - - + `sum(@inbounds a[i] for i = 1:n)` used to give a syntax error, but is now - parsed as `sum(@inbounds(a[i]) for i = 1:n)`. - - + `sum(@m x for i = 1:n end)` used to parse the argument to `sum` as a 2-argument - call to macro `@m`, but now parses it as a generator plus a syntax error - for the dangling `end`. - - * `@__DIR__` returns the current working directory rather than `nothing` when not run - from a file ([#21759](https://github.com/JuliaLang/julia/issues/21759)). - - * `@__FILE__` and `@__DIR__` return information relative to the file that it was parsed from, - rather than from the task-local `SOURCE_PATH` global when it was expanded. - - * All macros receive an extra argument `__source__::LineNumberNode` which describes the - parser location in the source file for the `@` of the macro call. - It can be accessed as a normal argument variable in the body of the macro. - This is implemented by inserting an extra leading argument into the - `Expr(:macrocall, :@name, LineNumberNode(...), args...)` - surface syntax. ([#21746](https://github.com/JuliaLang/julia/issues/21746)) - - * Passing the same keyword argument multiple times is now a syntax error ([#16937](https://github.com/JuliaLang/julia/issues/16937)). - - * `getsockname` on a `TCPSocket` now returns the locally bound address and port - of the socket. Previously the address of the remote endpoint was being - returned ([#21825](https://github.com/JuliaLang/julia/issues/21825)). - - * The `~/.juliarc.jl` file has been moved to `~/.julia/config/startup.jl` and - `/etc/julia/juliarc.jl` file has been renamed to `/etc/julia/startup.jl` ([#26161](https://github.com/JuliaLang/julia/issues/26161)). - - * Using `ARGS` within `startup.jl` files or within a .jl file loaded with `--load` will no - longer contain the script name as the first argument. Instead, the script name will be - assigned to `PROGRAM_FILE`. ([#22092](https://github.com/JuliaLang/julia/issues/22092)) - - * The format for a `ClusterManager` specifying the cookie on the command line is now - `--worker=`. `--worker ` will not work as it is now an optional argument. - - * The representation of `CartesianRange` has changed to a - tuple-of-AbstractUnitRanges; the `start` and `stop` fields are no - longer present. Use `first(R)` and `last(R)` to obtain - start/stop. ([#20974](https://github.com/JuliaLang/julia/issues/20974)) - - * The `Diagonal`, `Bidiagonal`, `Tridiagonal` and `SymTridiagonal` type definitions have - changed from `Diagonal{T}`, `Bidiagonal{T}`, `Tridiagonal{T}` and `SymTridiagonal{T}` - to `Diagonal{T,V<:AbstractVector{T}}`, `Bidiagonal{T,V<:AbstractVector{T}}`, - `Tridiagonal{T,V<:AbstractVector{T}}` and `SymTridiagonal{T,V<:AbstractVector{T}}` - respectively ([#22718](https://github.com/JuliaLang/julia/issues/22718), [#22925](https://github.com/JuliaLang/julia/issues/22925), [#23035](https://github.com/JuliaLang/julia/issues/23035), [#23154](https://github.com/JuliaLang/julia/issues/23154)). - - * The immediate supertype of `BitArray` is now simply `AbstractArray`. `BitArray` is no longer - considered a subtype of `DenseArray` and `StridedArray` ([#25858](https://github.com/JuliaLang/julia/issues/25858)). - - * When called with an argument that contains `NaN` elements, `findmin` and `findmax` now return the - first `NaN` found and its corresponding index. Previously, `NaN` elements were ignored. - The new behavior matches that of `min`, `max`, `minimum`, and `maximum`. - - * `isapprox(x,y)` now tests `norm(x-y) <= max(atol, rtol*max(norm(x), norm(y)))` - rather than `norm(x-y) <= atol + ...`, and `rtol` defaults to zero - if an `atol > 0` is specified ([#22742](https://github.com/JuliaLang/julia/issues/22742)). - - * Spaces are no longer allowed between `@` and the name of a macro in a macro call ([#22868](https://github.com/JuliaLang/julia/issues/22868)). - - * Juxtaposition of a non-literal with a macro call (`x@macro`) is no longer valid syntax ([#22868](https://github.com/JuliaLang/julia/issues/22868)). - - * On a cluster, all files are now loaded from the local file system rather than node 1 ([#22588](https://github.com/JuliaLang/julia/issues/22588)). - To load the same file everywhere from node 1, one possible alternative is to broadcast a call to `include_string`: - `@everywhere include_string(Main, $(read("filename", String)), "filename")`. - Improving upon this API is left as an opportunity for packages. - - * `randperm(n)` and `randcycle(n)` now always return a `Vector{Int}` (independent of - the type of `n`). Use the corresponding mutating functions `randperm!` and `randcycle!` - to control the array type ([#22723](https://github.com/JuliaLang/julia/issues/22723)). - - * Hermitian now ignores any imaginary components in the diagonal instead of checking - the diagonal. ([#17367](https://github.com/JuliaLang/julia/issues/17367)) - - * Worker-worker connections are setup lazily for an `:all_to_all` topology. Use keyword - arg `lazy=false` to force all connections to be setup during a `addprocs` call. ([#22814](https://github.com/JuliaLang/julia/issues/22814)) - - * In `joinpath(a, b)` on Windows, if the drive specifications of `a` and `b` do not match, - `joinpath` now returns `b` instead of throwing an `ArgumentError`. `joinpath(path...)` is - defined to be left associative, so if any argument has a drive path which does not match - the drive of the join of the preceding paths, the prior ones are dropped. ([#20912](https://github.com/JuliaLang/julia/issues/20912)) - - * `^(A::AbstractMatrix{<:Integer}, p::Integer)` now throws a `DomainError` - if `p < 0`, unless `A == one(A)` or `A == -one(A)` (same as for - `^(A::Integer, p::Integer)`) ([#23366](https://github.com/JuliaLang/julia/issues/23366)). - - * `^(A::AbstractMatrix{<:Integer}, p::Integer)` now promotes the element type in the same - way as `^(A::Integer, p::Integer)`. This means, for instance, that `[1 1; 0 1]^big(1)` - will return a `Matrix{BigInt}` instead of a `Matrix{Int}` ([#23366](https://github.com/JuliaLang/julia/issues/23366)). - - * The element type of the input is now preserved in `unique`. Previously the element type - of the output was shrunk to fit the union of the type of each element in the input. - ([#22696](https://github.com/JuliaLang/julia/issues/22696)) - - * The `promote` function now raises an error if its arguments are of different types - and if attempting to convert them to a common type fails to change any of their types. - This avoids stack overflows in the common case of definitions like - `f(x, y) = f(promote(x, y)...)` ([#22801](https://github.com/JuliaLang/julia/issues/22801)). - - * `indmin` and `indmax` have been renamed to `argmin` and `argmax`, respectively ([#25654](https://github.com/JuliaLang/julia/issues/25654)). - - * `findmin`, `findmax`, `argmin`, and `argmax` used to always return linear indices. - They now return `CartesianIndex`es for all but 1-d arrays, and in general return - the `keys` of indexed collections (e.g. dictionaries) ([#22907](https://github.com/JuliaLang/julia/issues/22907)). - - * The `openspecfun` library is no longer built and shipped with Julia, as it is no longer - used internally ([#22390](https://github.com/JuliaLang/julia/issues/22390)). - - * All loaded packages used to have bindings in `Main` (e.g. `Main.Package`). This is no - longer the case; now bindings will only exist for packages brought into scope by - typing `using Package` or `import Package` ([#17997](https://github.com/JuliaLang/julia/issues/17997)). - - * The rules for mixed-signedness integer arithmetic (e.g. `Int32(1) + UInt64(1)`) have been - simplified: if the arguments have different sizes (in bits), then the type of the larger - argument is used. If the arguments have the same size, the unsigned type is used ([#9292](https://github.com/JuliaLang/julia/issues/9292)). - - * All command line arguments passed via `-e`, `-E`, and `-L` will be executed in the order - given on the command line ([#23665](https://github.com/JuliaLang/julia/issues/23665)). - - * `I` now yields `UniformScaling{Bool}(true)` rather than `UniformScaling{Int64}(1)` - to better preserve types in operations involving `I` ([#24396](https://github.com/JuliaLang/julia/issues/24396)). - - * The return type of `reinterpret` has changed to `ReinterpretArray`. `reinterpret` on sparse - arrays has been discontinued. - - * `Base.find_in_path` is now `Base.find_package` or `Base.find_source_file` ([#24320](https://github.com/JuliaLang/julia/issues/24320)). - - * `finalizer` now takes functions or pointers as its first argument, and the object being - finalized as its second (rather than the reverse). For the majority of use cases - deprecation warnings will be triggered. However, deprecation warnings will not trigger where - (1) the callable argument is not a subtype of `Function`; or (2) both arguments are - `Function`s or `Ptr{Cvoid}`s ([#24605](https://github.com/JuliaLang/julia/issues/24605)). - - * The `kill` function now throws errors on user error (e.g. on permission - errors), but returns successfully if the process had previously exited. - Its return value has been removed. Use the `process_running` function - to determine if a process has already exited. - - * The logging system has been redesigned - `info` and `warn` are deprecated - and replaced with the logging macros `@info`, `@warn`, `@debug` and - `@error`. The `logging` function is also deprecated and replaced with - `AbstractLogger` and the functions from the new standard `Logging` library. - ([#24490](https://github.com/JuliaLang/julia/issues/24490)) - - * The `RevString` type has been removed from the language; `reverse(::String)` returns - a `String` with code points (or fragments thereof) in reverse order. In general, - `reverse(s)` should return a string of the same type and encoding as `s` with code - points in reverse order; any string type overrides `reverse` to return a different - type of string must also override `reverseind` to compute reversed indices correctly. - - * `eachindex(A, B...)` now requires that all inputs have the same number of elements. - When the chosen indexing is Cartesian, they must have the same axes. - - * `AbstractRange` objects are now considered as equal to other `AbstractArray` objects - by `==` and `isequal` if all of their elements are equal ([#16401](https://github.com/JuliaLang/julia/issues/16401)). - This has required changing the hashing algorithm: ranges now use an O(N) fallback - instead of a O(1) specialized method unless they define the `Base.RangeStepStyle` - trait; see its documentation for details. Types which support subtraction (operator - `-`) must now implement `widen` for hashing to work inside heterogeneous arrays. - - * `findn(x::AbstractArray)` has been deprecated in favor of `findall(!iszero, x)`, which - now returns cartesian indices for multidimensional arrays (see below, [#25532](https://github.com/JuliaLang/julia/issues/25532)). - - * Broadcasting operations are no longer fused into a single operation by Julia's parser. - Instead, a lazy `Broadcasted` object is created to represent the fused expression and - then realized with `copy(bc::Broadcasted)` or `copyto!(dest, bc::Broadcasted)` - to evaluate the wrapper. Consequently, package authors generally need to specialize - `copy` and `copyto!` methods rather than `broadcast` and `broadcast!`. This also allows - for more customization and control of fused broadcasts. See the - [Interfaces chapter](https://docs.julialang.org/en/latest/manual/interfaces/#man-interfaces-broadcasting-1) - for more information. - - * `find` has been renamed to `findall`. `findall`, `findfirst`, `findlast`, `findnext` - now take and/or return the same type of indices as `keys`/`pairs` for `AbstractArray`, - `AbstractDict`, `AbstractString`, `Tuple` and `NamedTuple` objects ([#24774](https://github.com/JuliaLang/julia/issues/24774), [#25545](https://github.com/JuliaLang/julia/issues/25545)). - In particular, this means that they use `CartesianIndex` objects for matrices - and higher-dimensional arrays instead of linear indices as was previously the case. - Use `LinearIndices(a)[findall(f, a)]` and similar constructs to compute linear indices. - - * The `find*` functions, i.e. `findnext`, `findprev`, `findfirst`, - and `findlast`, as well as `indexin`, now return `nothing` when no match is found rather - than `0` or `0:-1` ([#25472](https://github.com/JuliaLang/julia/issues/25472), [#25662](https://github.com/JuliaLang/julia/issues/25662), [#26149](https://github.com/JuliaLang/julia/issues/26149)) - - * The `Base.HasShape` iterator trait has gained a type parameter `N` indicating the - number of dimensions, which must correspond to the length of the tuple returned by - `size` ([#25655](https://github.com/JuliaLang/julia/issues/25655)). - - * `AbstractSet` objects are now considered equal by `==` and `isequal` if all of their - elements are equal ([#25368](https://github.com/JuliaLang/julia/issues/25368)). This has required changing the hashing algorithm - for `BitSet`. - - * the default behavior of `titlecase` is changed in two ways ([#23393](https://github.com/JuliaLang/julia/issues/23393)): - + characters not starting a word are converted to lowercase; - a new keyword argument `strict` is added which - allows to get the old behavior when it's `false`. - + any non-letter character is considered as a word separator; - to get the old behavior (only "space" characters are considered as - word separators), use the keyword `wordsep=isspace`. - - * `writedlm` in the standard library module DelimitedFiles now writes numeric values - using `print` rather than `print_shortest` ([#25745](https://github.com/JuliaLang/julia/issues/25745)). - - * The `tempname` function used to create a file on Windows but not on other - platforms. It now never creates a file ([#9053](https://github.com/JuliaLang/julia/issues/9053)). - - * The `fieldnames` and `propertynames` functions now return a tuple rather than - an array ([#25725](https://github.com/JuliaLang/julia/issues/25725)). - - * `indexin` now returns the first rather than the last matching index ([#25998](https://github.com/JuliaLang/julia/issues/25998)). - - * `parse(::Type, ::Char)` now uses a default base of 10, like other number parsing - methods, instead of 36 ([#26576](https://github.com/JuliaLang/julia/issues/26576)). - - * `isequal` for `Ptr`s now compares element types; `==` still compares only addresses - ([#26858](https://github.com/JuliaLang/julia/issues/26858)). - - * `widen` on 8- and 16-bit integer types now widens to 16- and 32-bit types, respectively. ([#28045](https://github.com/JuliaLang/julia/issues/28045)). - - - * `mv`,`cp`, `touch`, `mkdir`, `mkpath`, `chmod` and `chown` now return the path that was created/modified - rather than `nothing` ([#27071](https://github.com/JuliaLang/julia/issues/27071)). - - * Regular expressions now default to UCP mode. Escape sequences such as `\w` - will now match based on unicode character properties, e.g. `r"\w+"` will - match `café` (not just `caf`). Add the `a` modifier (e.g. `r"\w+"a`) to - restore the previous behavior ([#27189](https://github.com/JuliaLang/julia/issues/27189)). - - * `@sync` now waits only for *lexically* enclosed (i.e. visible directly in the source - text of its argument) `@async` expressions. If you need to wait for a task created by - a called function `f`, have `f` return the task and put `@async wait(f(...))` within - the `@sync` block. - This change makes `@schedule` redundant with `@async`, so `@schedule` has been - deprecated ([#27164](https://github.com/JuliaLang/julia/issues/27164)). - - * `norm(A::AbstractMatrix, p=2)` computes no longer the operator/matrix norm but the `norm` of `A` - as for other iterables, i.e. as if it were a vector. Especially, `norm(A::AbstractMatrix)` is the - Frobenius norm. To compute the operator/matrix norm, use the new function `opnorm` ([#27401](https://github.com/JuliaLang/julia/issues/27401)). - - * `dot(u, v)` now acts recursively. Instead of `sum(u[i]' * v[i] for i in ...)`, it computes - `sum(dot(u[i], v[i]) for i in ...)`, similarly to `vecdot` before ([#27401](https://github.com/JuliaLang/julia/issues/27401)). - - * `Sys.CPU_CORES` has been renamed to `Sys.CPU_THREADS`; it still gives the number - of "logical cores" (including hyperthreading) rather than the number of physical - cores present on the CPU. Similarly, the environment variable `JULIA_CPU_CORES` is - deprecated in favor of `JULIA_CPU_THREADS` ([#27856](https://github.com/JuliaLang/julia/issues/27856)). - - * `WeakKeyDict` does not convert keys on insertion anymore (#24941). - Library improvements -------------------- - * The function `thisind(s::AbstractString, i::Integer)` returns the largest valid index - less or equal than `i` in the string `s` or `0` if no such index exists ([#24414](https://github.com/JuliaLang/julia/issues/24414)). - - * Support for Unicode 11 ([#28266](https://github.com/JuliaLang/julia/issues/28266)). - - * `Char` is now a subtype of `AbstractChar`, and most of the functions that - take character arguments now accept any `AbstractChar` ([#26286](https://github.com/JuliaLang/julia/issues/26286)). - - * `pathof(module)` returns the path a module was imported from ([#28310](https://github.com/JuliaLang/julia/issues/28310)). - - * `bytes2hex` now accepts an optional `io` argument to output to a hexadecimal stream - without allocating a `String` first ([#27121](https://github.com/JuliaLang/julia/issues/27121)). - - * `String(array)` now accepts an arbitrary `AbstractVector{UInt8}`. For `Vector` - inputs, it "steals" the memory buffer, leaving them with an empty buffer which - is guaranteed not to be shared with the `String` object. For other types of vectors - (in particular immutable vectors), a copy is made and the input is not truncated ([#26093](https://github.com/JuliaLang/julia/issues/26093)). - - * `Irrational` is now a subtype of `AbstractIrrational` ([#24245](https://github.com/JuliaLang/julia/issues/24245)). - - * Introduced the `empty` function, the functional pair to `empty!` which returns a new, - empty container ([#24390](https://github.com/JuliaLang/julia/issues/24390)). - - * Jump to first/last history entries in the REPL via "Alt-<" and "Alt->" ([#22829](https://github.com/JuliaLang/julia/issues/22829)). - - * REPL LaTeX-like tab completions have been simplified for several Unicode characters, - e.g. `𝔸` is now `\bbA` rather than `\BbbA` ([#25980](https://github.com/JuliaLang/julia/issues/25980)). - - * The function `chop` now accepts two arguments `head` and `tail` allowing to specify - number of characters to remove from the head and tail of the string ([#24126](https://github.com/JuliaLang/julia/issues/24126)). - - * `get(io, :color, false)` can now be used to query whether a stream `io` supports - [ANSI color codes](https://en.wikipedia.org/wiki/ANSI_escape_code) ([#25067](https://github.com/JuliaLang/julia/issues/25067)), - rather than using the undocumented `Base.have_color` global flag. - - * `print_with_color` has been deprecated in favor of - `printstyled([io], xs...; bold=false, color=:normal)` for printing styled text ([#25522](https://github.com/JuliaLang/julia/issues/25522)). - - * Functions `first` and `last` now accept `nchar` argument for `AbstractString`. - If this argument is used they return a string consisting of first/last `nchar` - characters from the original string ([#23960](https://github.com/JuliaLang/julia/issues/23960)). - - * Expressions `x^-n` where `n` is an *integer literal* now correspond to `inv(x)^n`. - For example, `x^-1` is now essentially a synonym for `inv(x)`, and works - in a type-stable way even if `typeof(x) != typeof(inv(x))` ([#24240](https://github.com/JuliaLang/julia/issues/24240)). - - * New `Iterators.reverse(itr)` for reverse-order iteration ([#24187](https://github.com/JuliaLang/julia/issues/24187)). Iterator - types `T` can implement `start` etc. for `Iterators.Reverse{T}` to support this. - - * The functions `nextind` and `prevind` now accept `nchar` argument that indicates - the number of characters to move ([#23805](https://github.com/JuliaLang/julia/issues/23805)). - - * The functions `strip`, `lstrip` and `rstrip` now return `SubString` ([#22496](https://github.com/JuliaLang/julia/issues/22496)). - - * The functions `strwidth` and `charwidth` have been merged into `textwidth`([#20816](https://github.com/JuliaLang/julia/issues/20816)). - - * The functions `base` and `digits` digits now accept a negative - base (like `ndigits` did) ([#21692](https://github.com/JuliaLang/julia/issues/21692)). - - * The function `randn` now accepts complex arguments (`Complex{T <: AbstractFloat}`) - ([#21973](https://github.com/JuliaLang/julia/issues/21973)). - - * `parse(Complex{T}, string)` can parse complex numbers in some common formats ([#24713](https://github.com/JuliaLang/julia/issues/24713)). - - * The function `rand` can now pick up random elements from strings, associatives - and sets ([#22228](https://github.com/JuliaLang/julia/issues/22228), [#21960](https://github.com/JuliaLang/julia/issues/21960), [#18155](https://github.com/JuliaLang/julia/issues/18155), [#22224](https://github.com/JuliaLang/julia/issues/22224)). - - * It's now possible to specify the characters to pick from in the `randstring` function ([#22222](https://github.com/JuliaLang/julia/issues/22222)). - - * Allow multidimensional arrays in `shuffle` and `shuffle!` functions ([#22226](https://github.com/JuliaLang/julia/issues/22226)). - - * Method lists are now printed as a numbered list. In addition, the source code of a - method can be opened in an editor by entering the corresponding number in the REPL - and pressing `^Q` ([#22007](https://github.com/JuliaLang/julia/issues/22007)). - - * `getpeername` on a `TCPSocket` returns the address and port of the remote - endpoint of the TCP connection ([#21825](https://github.com/JuliaLang/julia/issues/21825)). - - * `resize!` and `sizehint!` methods no longer over-reserve memory when the - requested array size is more than double of its current size ([#22038](https://github.com/JuliaLang/julia/issues/22038)). - - * The `crc32c` function for CRC-32c checksums is now exported ([#22274](https://github.com/JuliaLang/julia/issues/22274)). - - * `eye(::Type{Diagonal{T}}, m::Integer)` has been deprecated in favor of - `Diagonal{T}(I, m)` ([#24413](https://github.com/JuliaLang/julia/issues/24413)). - - * The output of `versioninfo` is now controlled with keyword arguments ([#21974](https://github.com/JuliaLang/julia/issues/21974)). - - * The function `LibGit2.set_remote_url` now always sets both the fetch and push URLs for a - git repo. Additionally, the argument order was changed to be consistent with the git - command line tool ([#22062](https://github.com/JuliaLang/julia/issues/22062)). - - * Added `unique!` which is an inplace version of `unique` ([#20549](https://github.com/JuliaLang/julia/issues/20549)). - - * `@test isequal(x, y)` and `@test isapprox(x, y)` now prints an evaluated expression when - the test fails ([#22296](https://github.com/JuliaLang/julia/issues/22296)). - - * Uses of `Val{c}` in `Base` has been replaced with `Val{c}()`, which is now easily - accessible via the efficient constructor `Val(c)`. Functions are defined as - `f(::Val{c}) = ...` and called by `f(Val(c))`. Notable affected functions include: - `ntuple`, `Base.literal_pow`, `sqrtm`, `lufact`, `lufact!`, `qrfact`, `qrfact!`, - `cholfact`, `cholfact!`, `_broadcast!`, `reshape`, `cat` and `cat_t`. - - * A new `@macroexpand1` macro for non recursive macro expansion ([#21662](https://github.com/JuliaLang/julia/issues/21662)). - - * `Char`s can now be concatenated with `String`s and/or other `Char`s using `*` ([#22532](https://github.com/JuliaLang/julia/issues/22532)). - - * `Diagonal`, `Bidiagonal`, `Tridiagonal` and `SymTridiagonal` are now parameterized on - the type of the wrapped vectors, allowing `Diagonal`, `Bidiagonal`, `Tridiagonal` and - `SymTridiagonal` matrices with arbitrary `AbstractVector`s - ([#22718](https://github.com/JuliaLang/julia/issues/22718), [#22925](https://github.com/JuliaLang/julia/issues/22925), [#23035](https://github.com/JuliaLang/julia/issues/23035), [#23154](https://github.com/JuliaLang/julia/issues/23154)). - - * Mutating versions of `randperm` and `randcycle` have been added: - `randperm!` and `randcycle!` ([#22723](https://github.com/JuliaLang/julia/issues/22723)). - - * `BigFloat` random numbers can now be generated ([#22720](https://github.com/JuliaLang/julia/issues/22720)). - - * The efficiency of random generation for MersenneTwister RNGs has been improved for - integers, `Float64` and ranges; as a result, given a seed, the produced stream of numbers - has changed ([#27560](https://github.com/JuliaLang/julia/issues/27560), [#25277](https://github.com/JuliaLang/julia/issues/25277), [#25197](https://github.com/JuliaLang/julia/issues/25197), [#25058](https://github.com/JuliaLang/julia/issues/25058), [#25047](https://github.com/JuliaLang/julia/issues/25047)). - - * REPL Undo via Ctrl-/ and Ctrl-_ - - * `diagm` now accepts several diagonal index/vector `Pair`s ([#24047](https://github.com/JuliaLang/julia/issues/24047)). - - * `isequal`, `==`, and `in` have one argument "curried" forms. For example `isequal(x)` - returns a function that compares its argument to `x` using `isequal` ([#26436](https://github.com/JuliaLang/julia/issues/26436)). - - * `reinterpret` now works on any AbstractArray using the new `ReinterpretArray` type. - This supersedes the old behavior of reinterpret on Arrays. As a result, reinterpreting - arrays with different alignment requirements (removed in 0.6) is once again allowed ([#23750](https://github.com/JuliaLang/julia/issues/23750)). - - * The `keys` of an `Associative` are now an `AbstractSet`. `Base.KeyIterator{<:Associative}` - has been changed to `KeySet{K, <:Associative{K}} <: AbstractSet{K}` ([#24580](https://github.com/JuliaLang/julia/issues/24580)). - - * New function `ncodeunits(s::AbstractString)` gives the number of code units in a string. - The generic definition is constant time but calls `lastindex(s)` which may be inefficient. - Therefore custom string types may want to define direct `ncodeunits` methods. - - * `reverseind(s::AbstractString, i::Integer)` now has an efficient generic fallback, so - custom string types do not need to provide their own efficient definitions. The generic - definition relies on `ncodeunits` however, so for optimal performance you may need to - define a custom method for that function. - - * The global RNG is being re-seeded with its own seed at the beginning of each `@testset`, - and have its original state restored at the end ([#24445](https://github.com/JuliaLang/julia/issues/24445)). This is breaking for testsets - relying implicitly on the global RNG being in a specific state. - - * `permutedims(m::AbstractMatrix)` is now short for `permutedims(m, (2,1))`, and is now a - more convenient way of making a "shallow transpose" of a 2D array. This is the - recommended approach for manipulating arrays of data, rather than the recursively - defined, linear-algebra function `transpose`. Similarly, - `permutedims(v::AbstractVector)` will create a row matrix ([#24839](https://github.com/JuliaLang/julia/issues/24839)). - - * A new `replace(A, old=>new)` function is introduced to replace `old` by `new` in - collection `A`. There is also another method with a different API, and - a mutating variant, `replace!` ([#22324](https://github.com/JuliaLang/julia/issues/22324), [#25697](https://github.com/JuliaLang/julia/issues/25697), [#26206](https://github.com/JuliaLang/julia/issues/26206), [#27944](https://github.com/JuliaLang/julia/issues/27944)). - - * Adding integers to `CartesianIndex` objects is now deprecated. Instead of - `i::Int + x::CartesianIndex`, use `i*one(x) + x` ([#26284](https://github.com/JuliaLang/julia/issues/26284)). - - * `CartesianRange` changes ([#24715](https://github.com/JuliaLang/julia/issues/24715)): - - Inherits from `AbstractArray`, and linear indexing can be used to provide - linear-to-cartesian conversion ([#24715](https://github.com/JuliaLang/julia/issues/24715)) - - It has a new constructor taking an array - - * several missing set-like operations have been added ([#23528](https://github.com/JuliaLang/julia/issues/23528)): - `union`, `intersect`, `symdiff`, `setdiff` are now implemented for - all collections with arbitrary many arguments, as well as the - mutating counterparts (`union!` etc.). The performance is also - much better in many cases. Note that this change is slightly - breaking: all the non-mutating functions always return a new - object even if only one argument is passed. Moreover the semantics - of `intersect` and `symdiff` is changed for vectors: - + `intersect` doesn't preserve the multiplicity anymore (use `filter` for - the old behavior) - + `symdiff` has been made consistent with the corresponding methods for - other containers, by taking the multiplicity of the arguments into account. - Use `unique` to get the old behavior. - - * The `linearindices` function has been deprecated in favor of the new - `LinearIndices` type, which additionally provides conversion from - cartesian indices to linear indices using the normal indexing operation. - ([#24715](https://github.com/JuliaLang/julia/issues/24715), [#26775](https://github.com/JuliaLang/julia/issues/26775)). - - * `IdDict{K,V}` replaces `ObjectIdDict`. It has type parameters - like other `AbstractDict` subtypes and its constructors mirror the - ones of `Dict`. ([#25210](https://github.com/JuliaLang/julia/issues/25210)) - - * `IOBuffer` can take the `sizehint` keyword argument to suggest a capacity of - the buffer ([#25944](https://github.com/JuliaLang/julia/issues/25944)). - - * `lstrip` and `rstrip` now accept a predicate function that defaults to `isspace` - ([#27309](https://github.com/JuliaLang/julia/issues/27309)). - - * `trunc`, `floor`, `ceil`, and `round` specify `digits`, `sigdigits` and `base` using - keyword arguments. ([#26156](https://github.com/JuliaLang/julia/issues/26156), [#26670](https://github.com/JuliaLang/julia/issues/26670)) - - * `Sys.which()` provides a cross-platform method to find executable files, similar to - the Unix `which` command. ([#26559](https://github.com/JuliaLang/julia/issues/26559)) - - * Added an optimized method of `vecdot` for taking the Frobenius inner product - of sparse matrices. ([#27470](https://github.com/JuliaLang/julia/issues/27470)) - - * Added an optimized method of `kron` for taking the tensor product of two - `Diagonal` matrices. ([27581]) - - * An official API for extending `rand` is now defined ([#23964](https://github.com/JuliaLang/julia/issues/23964), [#25002](https://github.com/JuliaLang/julia/issues/25002)). - - * The constructor `MersenneTwister()` is re-enabled, producing a randomly initialized RNG - (similar to `Random.seed!(MersenneTwister(0))`) ([#21909](https://github.com/JuliaLang/julia/issues/21909)). - - * `BitSet` can now store any `Int` (instead of only positive ones) ([#25029](https://github.com/JuliaLang/julia/issues/25029)). - - * The initial element `v0` in `reduce(op, v0, itr)` has been replaced with an `init` - optional keyword argument, as in `reduce(op, itr; init=v0)`. Similarly for `foldl`, - `foldr`, `mapreduce`, `mapfoldl`, `mapfoldr`, `accumulate` and `accumulate!`. - ([#27711](https://github.com/JuliaLang/julia/issues/27711), [#27859](https://github.com/JuliaLang/julia/issues/27859)) - Compiler/Runtime improvements ----------------------------- - * The inlining heuristic now models the approximate runtime cost of - a method (using some strongly-simplifying assumptions). Functions - are inlined unless their estimated runtime cost substantially - exceeds the cost of setting up and issuing a subroutine - call. ([#22210](https://github.com/JuliaLang/julia/issues/22210), [#22732](https://github.com/JuliaLang/julia/issues/22732)) - - * Inference recursion-detection heuristics are now more precise, - allowing them to be triggered less often, but being more aggressive when they - are triggered to drive the inference computation to a solution ([#23912](https://github.com/JuliaLang/julia/issues/23912)). - - * Inference now propagates constants inter-procedurally, and can compute - various constants expressions at compile-time ([#24362](https://github.com/JuliaLang/julia/issues/24362)). - - * The LLVM SLP Vectorizer optimization pass is now enabled at the default - optimization level. - Deprecated or removed --------------------- - * The `JULIA_HOME` environment variable has been renamed to `JULIA_BINDIR` and - `Base.JULIA_HOME` has been moved to `Sys.BINDIR` ([#20899](https://github.com/JuliaLang/julia/issues/20899)). - - * The keyword `immutable` is fully deprecated to `struct`, and - `type` is fully deprecated to `mutable struct` ([#19157](https://github.com/JuliaLang/julia/issues/19157), [#20418](https://github.com/JuliaLang/julia/issues/20418)). - - * `lufact`, `schurfact`, `lqfact`, `qrfact`, `ldltfact`, `svdfact`, - `bkfact`, `hessfact`, `eigfact`, and `cholfact` have respectively been - deprecated to `lu`, `schur`, `lq`, `qr`, `ldlt`, `svd`, `bunchkaufman`, - `hessenberg`, `eigen`, and `cholesky` ([#26997](https://github.com/JuliaLang/julia/issues/26997), [#27159](https://github.com/JuliaLang/julia/issues/27159), [#27212](https://github.com/JuliaLang/julia/issues/27212)). - - * `lufact!`, `schurfact!`, `lqfact!`, `qrfact!`, `ldltfact!`, `svdfact!`, - `bkfact!`, `hessfact!`, and `eigfact!` have respectively been deprecated to - `lu!`, `schur!`, `lq!`, `qr!`, `ldlt!`, `svd!`, `bunchkaufman!`, - `hessenberg!`, and `eigen!` ([#26997](https://github.com/JuliaLang/julia/issues/26997), [#27159](https://github.com/JuliaLang/julia/issues/27159), [#27212](https://github.com/JuliaLang/julia/issues/27212)). - - * `eig(A[, args...])` has been deprecated in favor of `eigen(A[, args...])`. - Whereas the former returns a tuple of arrays, the latter returns an `Eigen` object. - So for a direct replacement, use `(eigen(A[, args...])...,)`. But going forward, - consider using the direct result of `eigen(A[, args...])` instead, either - destructured into its components (`vals, vecs = eigen(A[, args...])`) or - as an `Eigen` object (`X = eigen(A[, args...])`) ([#26997](https://github.com/JuliaLang/julia/issues/26997), [#27159](https://github.com/JuliaLang/julia/issues/27159), [#27212](https://github.com/JuliaLang/julia/issues/27212)). - - * `eig(A::AbstractMatrix, B::AbstractMatrix)` and `eig(A::Number, B::Number)` - have been deprecated in favor of `eigen(A, B)`. Whereas the former each return - a tuple of arrays, the latter returns a `GeneralizedEigen` object. So for a direct - replacement, use `(eigen(A, B)...,)`. But going forward, consider using the - direct result of `eigen(A, B)` instead, either destructured into its components - (`vals, vecs = eigen(A, B)`), or as a `GeneralizedEigen` object - (`X = eigen(A, B)`) ([#26997](https://github.com/JuliaLang/julia/issues/26997), [#27159](https://github.com/JuliaLang/julia/issues/27159), [#27212](https://github.com/JuliaLang/julia/issues/27212)). - - * `ordschur(T::StridedMatrix{Ty}, Z::StridedMatrix{Ty}, select::Union{Vector{Bool},BitVector})` - and `ordschur(S::StridedMatrix{Ty}, T::StridedMatrix{Ty}, Q::StridedMatrix{Ty}, - Z::StridedMatrix{Ty}, select::Union{Vector{Bool},BitVector})` and their respective - inplace versions have been deprecated. - Use `ordschur(schur::Schur, select::Union{Vector{Bool},BitVector})` and - `ordschur(gschur::GeneralizedSchur, select::Union{Vector{Bool},BitVector})` instead - ([#28155](https://github.com/JuliaLang/julia/issues/28155)). - - * Indexing into multidimensional arrays with more than one index but fewer indices than there are - dimensions is no longer permitted when those trailing dimensions have lengths greater than 1. - Instead, reshape the array or add trailing indices so the dimensionality and number of indices - match ([#14770](https://github.com/JuliaLang/julia/issues/14770), [#23628](https://github.com/JuliaLang/julia/issues/23628)). - - * The use of a positional dimension argument has largely been deprecated in favor of a - `dims` keyword argument. This includes the functions `sum`, `prod`, `maximum`, - `minimum`, `all`, `any`, `findmax`, `findmin`, `mean`, `varm`, `std`, `var`, `cov`, - `cor`, `median`, `mapreducedim`, `reducedim`, `sort`, `accumulate`, `accumulate!`, - `cumsum`, `cumsum!`, `cumprod`, `cumprod!`, `flipdim`, `dropdims`, and `cat` ([#25501](https://github.com/JuliaLang/julia/issues/25501), [#26660](https://github.com/JuliaLang/julia/issues/26660), [#27100](https://github.com/JuliaLang/julia/issues/27100)). - - * `indices(a)` and `indices(a,d)` have been deprecated in favor of `axes(a)` and - `axes(a, d)` ([#25057](https://github.com/JuliaLang/julia/issues/25057)). - - * `EnvHash` has been renamed to `EnvDict` ([#24167](https://github.com/JuliaLang/julia/issues/24167)). - - * Uninitialized `Array` constructors of the form - `Array[{T,N}](shape...)` have been deprecated in favor of equivalents - accepting `undef` (an alias for `UndefInitializer()`) as their first argument, - as in `Array[{T,N}](undef, shape...)`. For example, - `Vector(3)` is now `Vector(undef, 3)`, `Matrix{Int}((2, 4))` is now, - `Matrix{Int}(undef, (2, 4))`, and `Array{Float32,3}(11, 13, 17)` is now - `Array{Float32,3}(undef, 11, 13, 17)` ([#24781](https://github.com/JuliaLang/julia/issues/24781)). - - * Previously `setindex!(A, x, I...)` (and the syntax `A[I...] = x`) supported two - different modes of operation when supplied with a set of non-scalar indices `I` - (e.g., at least one index is an `AbstractArray`) depending upon the value of `x` - on the right hand side. If `x` is an `AbstractArray`, its _contents_ are copied - elementwise into the locations in `A` selected by `I` and it must have the same - number of elements as `I` selects locations. Otherwise, if `x` is not an - `AbstractArray`, then its _value_ is implicitly broadcast to all locations to - all locations in `A` selected by `I`. This latter behavior—implicitly broadcasting - "scalar"-like values across many locations—is now deprecated in favor of explicitly - using the broadcasted assignment syntax `A[I...] .= x` or `fill!(view(A, I...), x)` - ([#26347](https://github.com/JuliaLang/julia/issues/26347)). - - * `broadcast_getindex(A, I...)` and `broadcast_setindex!(A, v, I...)` are deprecated in - favor of `getindex.((A,), I...)` and `setindex!.((A,), v, I...)`, respectively ([#27075](https://github.com/JuliaLang/julia/issues/27075)). - - * `LinAlg.fillslots!` has been renamed `LinAlg.fillstored!` ([#25030](https://github.com/JuliaLang/julia/issues/25030)). - - * `fill!(A::Diagonal, x)` and `fill!(A::AbstractTriangular, x)` have been deprecated - in favor of `Base.LinAlg.fillstored!(A, x)` ([#24413](https://github.com/JuliaLang/julia/issues/24413)). - - * `eye` has been deprecated in favor of `I` and `Matrix` constructors. Please see the - deprecation warnings for replacement details ([#24438](https://github.com/JuliaLang/julia/issues/24438)). - - * `zeros(D::Diagonal[, opts...])` has been deprecated ([#24654](https://github.com/JuliaLang/julia/issues/24654)). - - * Using Bool values directly as indices is now deprecated and will be an error in the future. Convert - them to `Int` before indexing if you intend to access index `1` for `true` and `0` for `false`. - - * `slicedim(A, d, i)` has been deprecated in favor of `copy(selectdim(A, d, i))`. The new - `selectdim` function now always returns a view into `A`; in many cases the `copy` is - not necessary. Previously, `slicedim` on a vector `V` over dimension `d=1` and scalar - index `i` would return the just selected element (unless `V` was a `BitVector`). This - has now been made consistent: `selectdim` now always returns a view into the original - array, with a zero-dimensional view in this specific case ([#26009](https://github.com/JuliaLang/julia/issues/26009)). - - * `whos` has been renamed `varinfo`, and now returns a markdown table instead of printing - output ([#12131](https://github.com/JuliaLang/julia/issues/12131)). - - * Uninitialized `RowVector` constructors of the form `RowVector{T}(shape...)` have been - deprecated in favor of equivalents accepting `undef` (an alias for - `UndefInitializer()`) as their first argument, as in - `RowVector{T}(undef, shape...)`. For example, `RowVector{Int}(3)` is now - `RowVector{Int}(undef, 3)`, and `RowVector{Float32}((1, 4))` is now - `RowVector{Float32}(undef, (1, 4))` ([#24786](https://github.com/JuliaLang/julia/issues/24786)). - - * `writecsv(io, a; opts...)` has been deprecated in favor of - `writedlm(io, a, ','; opts...)` ([#23529](https://github.com/JuliaLang/julia/issues/23529)). - - * The method `srand(rng, filename, n=4)` has been deprecated ([#21359](https://github.com/JuliaLang/julia/issues/21359)). - - * `readcsv(io[, T::Type]; opts...)` has been deprecated in favor of - `readdlm(io, ','[, T]; opts...)` ([#23530](https://github.com/JuliaLang/julia/issues/23530)). - - * `sparse(s::UniformScaling, m::Integer)` has been deprecated in favor of the - three-argument equivalent `sparse(s::UniformScaling, m, n)` ([#24472](https://github.com/JuliaLang/julia/issues/24472)). - - * The `cholfact`/`cholfact!` methods that accepted an `uplo` symbol have been deprecated - in favor of using `Hermitian` (or `Symmetric`) views ([#22187](https://github.com/JuliaLang/julia/issues/22187), [#22188](https://github.com/JuliaLang/julia/issues/22188)). - - * The `thin` keyword argument for orthogonal decomposition methods has - been deprecated in favor of `full`, which has the opposite meaning: - `thin == true` if and only if `full == false` ([#24279](https://github.com/JuliaLang/julia/issues/24279)). - - * `isposdef(A::AbstractMatrix, UL::Symbol)` and `isposdef!(A::AbstractMatrix, UL::Symbol)` - have been deprecated in favor of `isposdef(Hermitian(A, UL))` and `isposdef!(Hermitian(A, UL))` - respectively ([#22245](https://github.com/JuliaLang/julia/issues/22245)). - - * The `bkfact`/`bkfact!` methods that accepted `uplo` and `issymmetric` symbols have been deprecated - in favor of using `Hermitian` (or `Symmetric`) views ([#22605](https://github.com/JuliaLang/julia/issues/22605)). - - * The function `current_module` is deprecated and replaced with `@__MODULE__`. - This caused the deprecation of some reflection methods (such as `macroexpand` and - `isconst`), which now require a module argument. And it caused the bugfix of other - default arguments to use the Main module (including `whos`, `which`) ([#22064](https://github.com/JuliaLang/julia/issues/22064)). - - * `expand(ex)` and `expand(module, ex)` have been deprecated in favor of - `Meta.lower(module, ex)` ([#22064](https://github.com/JuliaLang/julia/issues/22064), [#24278](https://github.com/JuliaLang/julia/issues/24278)). - - * `ones(A::AbstractArray[, opts...])` and `zeros(A::AbstractArray[, opts...])` methods - have been deprecated. For `zeros(A)`, consider `zero(A)`. For `ones(A)` or `zeros(A)`, - consider `ones(size(A))`, `zeros(size(A))`, `fill(v, size(A))` for `v` an appropriate - one or zero, `fill!(copy(A), {1|0})`, `fill!(similar(A), {1|0})`, or any of the preceding - with different element type and/or shape depending on `opts...`. Where strictly - necessary, consider `fill!(similar(A[, opts...]), {one(eltype(A)) | zero(eltype(A))})`. - For an algebraic multiplicative identity, consider `one(A)` ([#24656](https://github.com/JuliaLang/julia/issues/24656)). - - * The `similar(dims->f(..., dims...), [T], axes...)` method to add offset array support - to a function `f` that would otherwise create a non-offset array has been deprecated. - Instead, call `f(..., axes...)` directly and, if needed, the offset array implementation - should add offset axis support to the function `f` directly ([#26733](https://github.com/JuliaLang/julia/issues/26733)). - - * The functions `ones` and `zeros` used to accept any objects as dimensional arguments, - implicitly converting them to `Int`s. This is now deprecated; only `Integer`s or - `AbstractUnitRange`s are accepted as arguments. Instead, convert the arguments before - calling `ones` or `zeros` ([#26733](https://github.com/JuliaLang/julia/issues/26733)). - - * The variadic `size(A, dim1, dim2, dims...)` method to return a tuple of multiple - dimension lengths of `A` has been deprecated ([#26862](https://github.com/JuliaLang/julia/issues/26862)). - - * The `Operators` module is deprecated. Instead, import required operators explicitly - from `Base`, e.g. `import Base: +, -, *, /` ([#22251](https://github.com/JuliaLang/julia/issues/22251)). - - * Bindings to the FFTW library have been removed from Base. The DFT framework for building FFT - implementations is now in AbstractFFTs.jl, the bindings to the FFTW library are in FFTW.jl, - and the Base signal processing functions which used FFTs are now in DSP.jl ([#21956](https://github.com/JuliaLang/julia/issues/21956)). - - * The `corrected` positional argument to `cov` has been deprecated in favor of - a keyword argument with the same name ([#21709](https://github.com/JuliaLang/julia/issues/21709)). - - * Omitting spaces around the `?` and the `:` tokens in a ternary expression has been deprecated. - Ternaries must now include some amount of whitespace, e.g. `x ? a : b` rather than - `x?a:b` ([#22523](https://github.com/JuliaLang/julia/issues/22523) and [#22712](https://github.com/JuliaLang/julia/issues/22712)). - - * `?` can no longer be used as an identifier name ([#22712](https://github.com/JuliaLang/julia/issues/22712)) - - * The method `replace(s::AbstractString, pat, r, [count])` is deprecated - in favor of `replace(s::AbstractString, pat => r; [count])` ([#25165](https://github.com/JuliaLang/julia/issues/25165)). - Moreover, `count` cannot be negative anymore (use `typemax(Int)` instead ([#22325](https://github.com/JuliaLang/julia/issues/22325)). - - * `read(io, type, dims)` is deprecated to `read!(io, Array{type}(undef, dims))` ([#21450](https://github.com/JuliaLang/julia/issues/21450)). - - * `read(::IO, ::Ref)` is now a method of `read!`, since it mutates its `Ref` argument ([#21592](https://github.com/JuliaLang/julia/issues/21592)). - - * `nb_available` is now `bytesavailable` ([#25634](https://github.com/JuliaLang/julia/issues/25634)). - - * `skipchars(io::IO, predicate; linecomment=nothing)` is deprecated in favor of - `skipchars(predicate, io::IO; linecomment=nothing)` ([#25667](https://github.com/JuliaLang/julia/issues/25667)). - - * `Bidiagonal` constructors now use a `Symbol` (`:U` or `:L`) for the upper/lower - argument, instead of a `Bool` or a `Char` ([#22703](https://github.com/JuliaLang/julia/issues/22703)). - - * `Bidiagonal`, `Tridiagonal` and `SymTridiagonal` constructors that automatically - converted the input vectors to the same type are deprecated in favor of explicit - conversion ([#22925](https://github.com/JuliaLang/julia/issues/22925), [#23035](https://github.com/JuliaLang/julia/issues/23035), [#23154](https://github.com/JuliaLang/julia/issues/23154). - - * Calling `nfields` on a type to find out how many fields its instances have is deprecated. - Use `fieldcount` instead. Use `nfields` only to get the number of fields in a specific object ([#22350](https://github.com/JuliaLang/julia/issues/22350)). - - * `fieldnames` now operates only on types. To get the names of fields in an object, use - `fieldnames(typeof(x))` ([#22350](https://github.com/JuliaLang/julia/issues/22350)). - - * `InexactError`, `DomainError`, and `OverflowError` now take - arguments. `InexactError(func::Symbol, type, -3)` now prints as - "ERROR: InexactError: func(type, -3)", `DomainError(val, - [msg])` prints as "ERROR: DomainError with val:\nmsg", - and `OverflowError(msg)` prints as "ERROR: OverflowError: msg". - ([#20005](https://github.com/JuliaLang/julia/issues/20005), [#22751](https://github.com/JuliaLang/julia/issues/22751), [#22761](https://github.com/JuliaLang/julia/issues/22761)) - - * The operating system identification functions: `is_linux`, `is_bsd`, `is_apple`, `is_unix`, - and `is_windows`, have been deprecated in favor of `Sys.islinux`, `Sys.isbsd`, `Sys.isapple`, - `Sys.isunix`, and `Sys.iswindows`, respectively ([#22182](https://github.com/JuliaLang/julia/issues/22182)). - - * The forms of `read`, `readstring`, and `eachline` that accepted both a `Cmd` object and an - input stream are deprecated. Use e.g. `read(pipeline(stdin, cmd))` instead ([#22762](https://github.com/JuliaLang/julia/issues/22762)). - - * The unexported type `AbstractIOBuffer` has been renamed to `GenericIOBuffer` ([#17360](https://github.com/JuliaLang/julia/issues/17360) [#22796](https://github.com/JuliaLang/julia/issues/22796)). - - * `IOBuffer(data::AbstractVector{UInt8}, read::Bool, write::Bool, maxsize::Integer)`, - `IOBuffer(read::Bool, write::Bool)`, and `IOBuffer(maxsize::Integer)` are - deprecated in favor of constructors taking keyword arguments ([#25872](https://github.com/JuliaLang/julia/issues/25872)). - - * `Display` has been renamed to `AbstractDisplay` ([#24831](https://github.com/JuliaLang/julia/issues/24831)). - - * Remaining vectorized methods over `SparseVector`s, particularly `floor`, `ceil`, - `trunc`, `round`, and most common transcendental functions such as `exp`, `log`, and - `sin` variants, have been deprecated in favor of dot-syntax ([#22961](https://github.com/JuliaLang/julia/issues/22961)). - - * The method `String(io::IOBuffer)` is deprecated to `String(take!(copy(io)))` ([#21438](https://github.com/JuliaLang/julia/issues/21438)). - - * The function `readstring` is deprecated in favor of `read(io, String)` ([#22793](https://github.com/JuliaLang/julia/issues/22793)) - - * The function `showall` is deprecated. Showing entire values is the default, unless an - `IOContext` specifying `:limit=>true` is in use ([#22847](https://github.com/JuliaLang/julia/issues/22847)). - - * `issubtype` has been deprecated in favor of `<:` (which used to be an alias for `issubtype`). - - * Calling `write` on non-isbits arrays is deprecated in favor of explicit loops or - `serialize` ([#6466](https://github.com/JuliaLang/julia/issues/6466)). - - * The default `startup.jl` file on Windows has been removed. Now must explicitly include the - full path if you need access to executables or libraries in the `Sys.BINDIR` directory, e.g. - `joinpath(Sys.BINDIR, "7z.exe")` for `7z.exe` ([#21540](https://github.com/JuliaLang/julia/issues/21540)). - - * `sqrtm` has been deprecated in favor of `sqrt` ([#23504](https://github.com/JuliaLang/julia/issues/23504)). - - * `expm` has been deprecated in favor of `exp` ([#23233](https://github.com/JuliaLang/julia/issues/23233)). - - * `logm` has been deprecated in favor of `log` ([#23505](https://github.com/JuliaLang/julia/issues/23505)). - - * `full` has been deprecated in favor of more specific, better defined alternatives. - On structured matrices `A`, consider instead `Matrix(A)`, `Array(A)`, - `SparseMatrixCSC(A)`, or `sparse(A)`. On sparse arrays `S`, consider instead - `Vector(S)`, `Matrix(S)`, or `Array(S)` as appropriate. On factorizations `F`, - consider instead `Matrix(F)`, `Array(F)`, `AbstractMatrix(F)`, or `AbstractArray(F)`. - On implicit orthogonal factors `Q`, consider instead `Matrix(Q)` or `Array(Q)`; for - implicit orthogonal factors that can be recovered in square or truncated form, - see the deprecation message for square recovery instructions. On `Symmetric`, - `Hermitian`, or `AbstractTriangular` matrices `A`, consider instead `Matrix(S)`, - `Array(S)`, `SparseMatrixCSC(S)`, or `sparse(S)`. On `Symmetric` matrices `A` - particularly, consider instead `LinAlg.copytri!(copy(parent(A)), A.uplo)`. On - `Hermitian` matrices `A` particularly, consider instead - `LinAlg.copytri!(copy(parent(A)), A.uplo, true)`. On `UpperTriangular` matrices `A` - particularly, consider instead `triu!(copy(parent(A)))`. On `LowerTriangular` matrices - `A` particularly, consider instead `tril!(copy(parent(A)))` ([#24250](https://github.com/JuliaLang/julia/issues/24250)). - - * `speye` has been deprecated in favor of `I`, `sparse`, and `SparseMatrixCSC` - constructor methods ([#24356](https://github.com/JuliaLang/julia/issues/24356)). - - * Calling `union` with no arguments is deprecated; construct an empty set with an appropriate - element type using `Set{T}()` instead ([#23144](https://github.com/JuliaLang/julia/issues/23144)). - - * Vectorized `DateTime`, `Date`, and `format` methods have been deprecated in favor of - dot-syntax ([#23207](https://github.com/JuliaLang/julia/issues/23207)). - - * `Base.cpad` has been removed; use an appropriate combination of `rpad` and `lpad` - instead ([#23187](https://github.com/JuliaLang/julia/issues/23187)). - - * `ctranspose` and `ctranspose!` have been deprecated in favor of `adjoint` and `adjoint!`, - respectively ([#23235](https://github.com/JuliaLang/julia/issues/23235)). - - * `filter` and `filter!` on dictionaries now pass a single `key=>value` pair to the - argument function, instead of two arguments ([#17886](https://github.com/JuliaLang/julia/issues/17886)). - - * `rol`, `rol!`, `ror`, and `ror!` have been deprecated in favor of specialized methods for - `circshift`/`circshift!` ([#23404](https://github.com/JuliaLang/julia/issues/23404)). - - * `Base.SparseArrays.SpDiagIterator` has been removed ([#23261](https://github.com/JuliaLang/julia/issues/23261)). - - * The function `cfunction`, has been deprecated in favor of a macro form `@cfunction`. - Most existing uses can be upgraded simply by adding a `@`. - The new syntax now additionally supports allocating closures at runtime, - for dealing with C APIs that don't provide a separate `void* env`-type callback - argument. ([#26486](https://github.com/JuliaLang/julia/issues/26486)) - - * `diagm(v::AbstractVector, k::Integer=0)` has been deprecated in favor of - `diagm(k => v)` ([#24047](https://github.com/JuliaLang/julia/issues/24047)). - - * `diagm(x::Number)` has been deprecated in favor of `fill(x, 1, 1)` ([#24047](https://github.com/JuliaLang/julia/issues/24047)). - - * `diagm(A::SparseMatrixCSC)` has been deprecated in favor of - `spdiagm(sparsevec(A))` ([#23341](https://github.com/JuliaLang/julia/issues/23341)). - - * `diagm(A::BitMatrix)` has been deprecated, use `diagm(0 => vec(A))` or - `BitMatrix(Diagonal(vec(A)))` instead ([#23373](https://github.com/JuliaLang/julia/issues/23373), [#24047](https://github.com/JuliaLang/julia/issues/24047)). - - * `ℯ` (written as `\mscre` or `\euler`) is now the only (by default) exported - name for Euler's number, and the type has changed from `Irrational{:e}` to - `Irrational{:ℯ}` ([#23427](https://github.com/JuliaLang/julia/issues/23427)). - - * The mathematical constants `π`, `pi`, `ℯ`, `e`, `γ`, `eulergamma`, `catalan`, `φ` and - `golden` have been moved from `Base` to a new module; `Base.MathConstants`. - Only `π`, `pi` and `ℯ` are now exported by default from `Base` ([#23427](https://github.com/JuliaLang/julia/issues/23427)). - - * `eu` (previously an alias for `ℯ`) has been deprecated in favor of `ℯ` (or `MathConstants.e`) ([#23427](https://github.com/JuliaLang/julia/issues/23427)). - - * `GMP.gmp_version()`, `GMP.GMP_VERSION`, `GMP.gmp_bits_per_limb()`, and `GMP.GMP_BITS_PER_LIMB` - have been renamed to `GMP.version()`, `GMP.VERSION`, `GMP.bits_per_limb()`, and `GMP.BITS_PER_LIMB`, - respectively. Similarly, `MPFR.get_version()`, has been renamed to `MPFR.version()` ([#23323](https://github.com/JuliaLang/julia/issues/23323)). Also, - `LinAlg.LAPACK.laver()` has been renamed to `LinAlg.LAPACK.version()` and now returns a `VersionNumber`. - - * `select`, `select!`, `selectperm` and `selectperm!` have been renamed respectively to - `partialsort`, `partialsort!`, `partialsortperm` and `partialsortperm!` ([#23051](https://github.com/JuliaLang/julia/issues/23051)). - - * The `Range` abstract type has been renamed to `AbstractRange` ([#23570](https://github.com/JuliaLang/julia/issues/23570)). - - * `map` on dictionaries previously operated on `key=>value` pairs. This behavior is deprecated, - and in the future `map` will operate only on values ([#5794](https://github.com/JuliaLang/julia/issues/5794)). - - * `map` on sets previously returned a `Set`, possibly changing the order or number of elements. This - behavior is deprecated and in the future `map` will preserve order and number of elements ([#26980](https://github.com/JuliaLang/julia/issues/26980)). - - * Previously, broadcast defaulted to treating its arguments as scalars if they were not - arrays. This behavior is deprecated, and in the future `broadcast` will default to - iterating over all its arguments. Wrap arguments you wish to be treated as scalars with - `Ref()` or a 1-tuple. Package developers can choose to allow a non-iterable type `T` to - always behave as a scalar by implementing `broadcastable(x::T) = Ref(x)` ([#26212](https://github.com/JuliaLang/julia/issues/26212)). - - * Automatically broadcasted `+` and `-` for `array + scalar`, `scalar - array`, and so-on have - been deprecated due to inconsistency with linear algebra. Use `.+` and `.-` for these operations - instead ([#22880](https://github.com/JuliaLang/julia/issues/22880), [#22932](https://github.com/JuliaLang/julia/issues/22932)). - - * `flipbits!(B)` is deprecated in favor of using in-place broadcast to negate each element: - `B .= .!B` ([#27067](https://github.com/JuliaLang/julia/issues/27067)). - - * `isleaftype` is deprecated in favor of the simpler predicates `isconcretetype` and `isdispatchtuple`. - Concrete types are those that might equal `typeof(x)` for some `x`; - `isleaftype` included some types for which this is not true. Those are now categorized more precisely - as "dispatch tuple types" and "!has_free_typevars" (not exported). ([#17086](https://github.com/JuliaLang/julia/issues/17086), [#25496](https://github.com/JuliaLang/julia/issues/25496)) - - * `contains(eq, itr, item)` is deprecated in favor of `any` with a predicate ([#23716](https://github.com/JuliaLang/julia/issues/23716)). - - * `spdiagm(x::AbstractVector)` has been deprecated in favor of `sparse(Diagonal(x))` - alternatively `spdiagm(0 => x)` ([#23757](https://github.com/JuliaLang/julia/issues/23757)). - - * `spdiagm(x::AbstractVector, d::Integer)` and `spdiagm(x::Tuple{<:AbstractVector}, d::Tuple{<:Integer})` - have been deprecated in favor of `spdiagm(d => x)` and `spdiagm(d[1] => x[1], d[2] => x[2], ...)` - respectively. The new `spdiagm` implementation now always returns a square matrix ([#23757](https://github.com/JuliaLang/julia/issues/23757)). - - * `spones(A::AbstractSparseArray)` has been deprecated in favor of - `LinAlg.fillstored!(copy(A), 1)` ([#25037](https://github.com/JuliaLang/julia/issues/25037)). - - * Constructors for `LibGit2.UserPasswordCredentials` and `LibGit2.SSHCredentials` which take a - `prompt_if_incorrect` argument are deprecated. Instead, prompting behavior is controlled using - the `allow_prompt` keyword in the `LibGit2.CredentialPayload` constructor ([#23690](https://github.com/JuliaLang/julia/issues/23690)). - - * `gradient` is deprecated and will be removed in the next release ([#23816](https://github.com/JuliaLang/julia/issues/23816)). - - * The timing functions `tic`, `toc`, and `toq` are deprecated in favor of `@time` and `@elapsed` - ([#17046](https://github.com/JuliaLang/julia/issues/17046)). - - * Methods of `findfirst`, `findnext`, `findlast`, and `findprev` that accept a value to - search for are deprecated in favor of passing a predicate ([#19186](https://github.com/JuliaLang/julia/issues/19186), [#10593](https://github.com/JuliaLang/julia/issues/10593)). - - * `find` functions now operate only on booleans by default. To look for non-zeros, use - `x->x!=0` or `!iszero` ([#23120](https://github.com/JuliaLang/julia/issues/23120)). - - * The ability of `reinterpret` to yield `Array`s of different type than the underlying storage - has been removed. The `reinterpret` function is still available, but now returns a - `ReinterpretArray`. The three argument form of `reinterpret` that implicitly reshapes - has been deprecated ([#23750](https://github.com/JuliaLang/julia/issues/23750)). - - * `bits` has been deprecated in favor of `bitstring` ([#24281](https://github.com/JuliaLang/julia/issues/24281), [#24263](https://github.com/JuliaLang/julia/issues/24263)). - - * `num2hex` and `hex2num` have been deprecated in favor of `reinterpret` combined with `parse`/`hex` ([#22088](https://github.com/JuliaLang/julia/issues/22088)). - - * `copy!` is deprecated for `AbstractSet` and `AbstractDict`, with the intention to re-enable - it with a cleaner meaning in a future version ([#24844](https://github.com/JuliaLang/julia/issues/24844)). - - * `copy!` (resp. `unsafe_copy!`) is deprecated for `AbstractArray` and is renamed `copyto!` - (resp. `unsafe_copyto!`); it will be re-introduced with a different meaning in a future - version ([#24808](https://github.com/JuliaLang/julia/issues/24808)). - - * `a:b` is deprecated for constructing a `StepRange` when `a` and `b` have physical units - (Dates and Times). Use `a:s:b`, where `s = Dates.Day(1)` or `s = Dates.Second(1)`. - - * `trues(A::AbstractArray)` and `falses(A::AbstractArray)` are deprecated in favor of - `trues(size(A))` and `falses(size(A))` respectively ([#24595](https://github.com/JuliaLang/julia/issues/24595)). - - * `workspace` is discontinued, check out [Revise.jl](https://github.com/timholy/Revise.jl) - for an alternative workflow ([#25046](https://github.com/JuliaLang/julia/issues/25046)). - - * `cumsum`, `cumprod`, `accumulate`, their mutating versions, and `diff` all now require a `dim` - argument instead of defaulting to using the first dimension unless there is only - one dimension ([#24684](https://github.com/JuliaLang/julia/issues/24684), [#25457](https://github.com/JuliaLang/julia/issues/25457)). - - * The `sum_kbn` and `cumsum_kbn` functions have been moved to the - [KahanSummation](https://github.com/JuliaMath/KahanSummation.jl) package ([#24869](https://github.com/JuliaLang/julia/issues/24869)). - - * `isnumber` has been renamed to `isnumeric` ([#25021](https://github.com/JuliaLang/julia/issues/25021)). - - * `isalpha` has been renamed to `isletter` ([#26932](https://github.com/JuliaLang/julia/issues/26932)). - - * `is_assigned_char` and `normalize_string` have been renamed to `isassigned` and - `normalize`, and moved to the new `Unicode` standard library module. - `graphemes` has also been moved to that module ([#25021](https://github.com/JuliaLang/julia/issues/25021)). - - * Sparse array functionality has moved to the `SparseArrays` standard library module ([#25249](https://github.com/JuliaLang/julia/issues/25249)). - - * Linear algebra functionality, and specifically the `LinAlg` module has moved to the - `LinearAlgebra` standard library module ([#25571](https://github.com/JuliaLang/julia/issues/25571)). - - * `@printf` and `@sprintf` have been moved to the `Printf` standard library ([#23929](https://github.com/JuliaLang/julia/issues/23929),[#25056](https://github.com/JuliaLang/julia/issues/25056)). - - * The `Libdl` module has moved to the `Libdl` standard library module ([#25459](https://github.com/JuliaLang/julia/issues/25459)). - - * The aliases `Complex32`, `Complex64` and `Complex128` have been deprecated in favor of `ComplexF16`, - `ComplexF32` and `ComplexF64` respectively ([#24647](https://github.com/JuliaLang/julia/issues/24647)). - - * `Base.parentindexes` and `SharedArrays.localindexes` have been renamed to `parentindices` - and `localindices`, respectively. Similarly, the `indexes` field in the `SubArray` type - has been renamed to `indices` without deprecation ([#25088](https://github.com/JuliaLang/julia/issues/25088)). - - * `Associative` has been deprecated in favor of `AbstractDict` ([#25012](https://github.com/JuliaLang/julia/issues/25012)). - - * `Void` has been renamed back to `Nothing` with an alias `Cvoid` for use when calling C - with a return type of `Cvoid` or a return or argument type of `Ptr{Cvoid}` ([#25162](https://github.com/JuliaLang/julia/issues/25162)). - - * `Nullable{T}` has been deprecated and moved to the Nullables package ([#23642](https://github.com/JuliaLang/julia/issues/23642)). Use - `Union{T, Nothing}` instead, or `Union{Some{T}, Nothing}` if `nothing` is a possible - value (i.e. `Nothing <: T`). `isnull(x)` can be replaced with `x === nothing` and - `unsafe_get`/`get` can be dropped or replaced with `coalesce`. - `NullException` has been removed. - - * `unshift!` and `shift!` have been renamed to `pushfirst!` and `popfirst!` ([#23902](https://github.com/JuliaLang/julia/issues/23902)) - - * `ipermute!` has been deprecated in favor of `invpermute!` ([#25168](https://github.com/JuliaLang/julia/issues/25168)). - - * `CartesianRange` has been renamed `CartesianIndices` ([#24715](https://github.com/JuliaLang/julia/issues/24715)). - - * `sub2ind` and `ind2sub` are deprecated in favor of using `CartesianIndices` and `LinearIndices` ([#24715](https://github.com/JuliaLang/julia/issues/24715)). - - * `getindex(F::Factorization, s::Symbol)` (usually seen as e.g. `F[:Q]`) is deprecated - in favor of dot overloading (`getproperty`) so factors should now be accessed as e.g. - `F.Q` instead of `F[:Q]` ([#25184](https://github.com/JuliaLang/julia/issues/25184)). - - * `search` and `rsearch` have been deprecated in favor of `findfirst`/`findnext` and - `findlast`/`findprev` respectively, in combination with curried `isequal` and `in` - predicates for some methods ([#24673](https://github.com/JuliaLang/julia/issues/24673)). - - * `search(buf::IOBuffer, delim::UInt8)` has been deprecated in favor of either `occursin(delim, buf)` - (to test containment) or `readuntil(buf, delim)` (to read data up to `delim`) ([#26600](https://github.com/JuliaLang/julia/issues/26600)). - - * `ismatch(regex, str)` has been deprecated in favor of `contains(str, regex)` ([#24673](https://github.com/JuliaLang/julia/issues/24673)). - - * `matchall` has been deprecated in favor of `collect(m.match for m in eachmatch(r, s))` ([#26071](https://github.com/JuliaLang/julia/issues/26071)). - - * `similar(::Associative)` has been deprecated in favor of `empty(::Associative)`, and - `similar(::Associative, ::Pair{K, V})` has been deprecated in favour of - `empty(::Associative, K, V)` ([#24390](https://github.com/JuliaLang/julia/issues/24390)). - - * `findin(a, b)` has been deprecated in favor of `findall(in(b), a)` ([#24673](https://github.com/JuliaLang/julia/issues/24673)). - - * `module_name` has been deprecated in favor of a new, general `nameof` function. Similarly, - the unexported `Base.function_name` and `Base.datatype_name` have been deprecated in favor - of `nameof` methods ([#25622](https://github.com/JuliaLang/julia/issues/25622)). - - * The module `Random.dSFMT` is renamed `Random.DSFMT` ([#25567](https://github.com/JuliaLang/julia/issues/25567)). - - * `Random.RandomDevice(unlimited::Bool)` (on non-Windows systems) is deprecated in favor of - `Random.RandomDevice(; unlimited=unlimited)` ([#25668](https://github.com/JuliaLang/julia/issues/25668)). - - * The generic implementations of `strides(::AbstractArray)` and `stride(::AbstractArray, ::Int)` - have been deprecated. Subtypes of `AbstractArray` that implement the newly introduced strided - array interface should define their own `strides` method ([#25321](https://github.com/JuliaLang/julia/issues/25321)). - - * `module_parent`, `Base.datatype_module`, and `Base.function_module` have been deprecated - in favor of `parentmodule` ([#TODO]). - - * `rand(t::Tuple{Vararg{Int}})` is deprecated in favor of `rand(Float64, t)` or `rand(t...)`; - `rand(::Tuple)` will have another meaning in the future ([#25429](https://github.com/JuliaLang/julia/issues/25429), [#25278](https://github.com/JuliaLang/julia/issues/25278)). - - * `randjump`, which produced an array, is deprecated in favor of the - scalar version `Future.randjump` used with `accumulate` ([#27746](https://github.com/JuliaLang/julia/issues/27746)). - - * The `assert` function (and `@assert` macro) have been documented that they are not guaranteed to run under various optimization levels and should therefore not be used to e.g. verify passwords. - - * `ObjectIdDict` has been deprecated in favor of `IdDict{Any,Any}` ([#25210](https://github.com/JuliaLang/julia/issues/25210)). - - * `gc` and `gc_enable` have been deprecated in favor of `GC.gc` and `GC.enable` ([#25616](https://github.com/JuliaLang/julia/issues/25616)). - - * `Base.@gc_preserve` has been deprecated in favor of `GC.@preserve` ([#25616](https://github.com/JuliaLang/julia/issues/25616)). - - * `print_shortest` has been discontinued, but is still available in the `Base.Grisu` - submodule ([#25745](https://github.com/JuliaLang/julia/issues/25745)). - - * `scale!` has been deprecated in favor of `mul!`, `lmul!`, and `rmul!` ([#25701](https://github.com/JuliaLang/julia/issues/25701), [#25812](https://github.com/JuliaLang/julia/issues/25812)). - - * The `remove_destination` keyword argument to `cp`, `mv`, and the unexported `cptree` - has been renamed to `force` ([#25979](https://github.com/JuliaLang/julia/issues/25979)). - - * `contains` has been deprecated in favor of a more general `occursin` function, which - takes its arguments in reverse order from `contains` ([#26283](https://github.com/JuliaLang/julia/issues/26283)). - - * `Regex` objects are no longer callable. Use `occursin` instead ([#26283](https://github.com/JuliaLang/julia/issues/26283)). - - * The methods of `range` based on positional arguments have been deprecated in favor of - keyword arguments ([#25896](https://github.com/JuliaLang/julia/issues/25896)). - - * `linspace` has been deprecated in favor of `range` with `stop` and `length` keyword - arguments ([#25896](https://github.com/JuliaLang/julia/issues/25896)). - - * `LinSpace` has been renamed to `LinRange` ([#25896](https://github.com/JuliaLang/julia/issues/25896)). - - * `logspace` has been deprecated to its definition ([#25896](https://github.com/JuliaLang/julia/issues/25896)). - - * `endof(a)` has been renamed to `lastindex(a)`, and the `end` keyword in indexing expressions now - lowers to either `lastindex(a)` (in the case with only one index) or `lastindex(a, d)` (in cases - where there is more than one index and `end` appears at dimension `d`) ([#23554](https://github.com/JuliaLang/julia/issues/23554), [#25763](https://github.com/JuliaLang/julia/issues/25763)). - - * `DateTime()`, `Date()`, and `Time()` have been deprecated, instead use `DateTime(1)`, `Date(1)` - and `Time(0)` respectively ([#23724](https://github.com/JuliaLang/julia/issues/23724)). - - * The fallback method `^(x, p::Integer)` is deprecated. If your type relied on this definition, - add a method such as `^(x::MyType, p::Integer) = Base.power_by_squaring(x, p)` ([#23332](https://github.com/JuliaLang/julia/issues/23332)). - - * `DevNull`, `STDIN`, `STDOUT`, and `STDERR` have been renamed to `devnull`, `stdin`, `stdout`, - and `stderr`, respectively ([#25786](https://github.com/JuliaLang/julia/issues/25786)). - - * `wait` and `fetch` on `Task` now resemble the interface of `Future`. - - * `showcompact(io, x...)` has been deprecated in favor of - `show(IOContext(io, :compact => true), x...)` ([#26080](https://github.com/JuliaLang/julia/issues/26080)). - Use `sprint(show, x..., context=:compact => true)` instead of `sprint(showcompact, x...)`. - - * `isupper`, `islower`, `ucfirst` and `lcfirst` have been deprecated in favor of `isuppercase`, - `islowercase`, `uppercasefirst` and `lowercasefirst`, respectively ([#26442](https://github.com/JuliaLang/julia/issues/26442)). - - * `signif` has been deprecated in favor of the `sigdigits` keyword argument to `round`. - - * `Base.IntSet` has been deprecated in favor of `Base.BitSet` ([#24282](https://github.com/JuliaLang/julia/issues/24282)). - - * `setrounding` has been deprecated for `Float32` and `Float64`, as the behaviour was too unreliable ([#26935](https://github.com/JuliaLang/julia/issues/26935)). - - * `gamma`, `lgamma`, `beta`, `lbeta` and `lfact` have been moved to - [SpecialFunctions.jl](https://github.com/JuliaMath/SpecialFunctions.jl) ([#27459](https://github.com/JuliaLang/julia/issues/27459), [#27473](https://github.com/JuliaLang/julia/issues/27473)). - - * `atan2` is now a 2-argument method of `atan` ([#27248](https://github.com/JuliaLang/julia/issues/27248)). - - * The functions `eigs` and `svds` have been moved to the `Arpack.jl` package ([#27616](https://github.com/JuliaLang/julia/issues/27616)). - - * `vecdot` and `vecnorm` are deprecated in favor of `dot` and `norm`, respectively ([#27401](https://github.com/JuliaLang/julia/issues/27401)). - - * `clipboard` has been moved to the `InteractiveUtils` standard library package - (along with other utilities mostly used at the interactive prompt, such as `edit` - and `less`) ([#27635](https://github.com/JuliaLang/julia/issues/27635)). - - * `ndigits(n, b, [pad])` is deprecated in favor of `ndigits(n, base=b, pad=pad)` ([#27908](https://github.com/JuliaLang/julia/issues/27908)). - - * `squeeze` is deprecated in favor of `dropdims`. - - * `srand` is deprecated in favor of the unexported `Random.seed!` ([#27726](https://github.com/JuliaLang/julia/issues/27726)). - - * `realmin`/`realmax` are deprecated in favor of `floatmin`/`floatmax` ([#28302](https://github.com/JuliaLang/julia/issues/28302)). - - * `sortrows`/`sortcols` have been deprecated in favor of the more general `sortslices`. - - * `nextpow2`/`prevpow2` have been deprecated in favor of the more general `nextpow`/`prevpow` functions. +The old package manager (now called `OldPkg`) has been moved to a +separate repository at https://github.com/JuliaArchive/OldPkg.jl ([#27930]) Command-line option changes --------------------------- - * New option `--warn-overwrite={yes|no}` to control the warning for overwriting method - definitions. The default is `no` ([#23002](https://github.com/JuliaLang/julia/issues/23002)). - - * New option `--banner={yes,no}` allows suppressing or forcing the printing of the - startup banner, overriding the default behavior (banner in REPL, no banner otherwise). - The `--quiet` option implies `--banner=no` even in REPL mode but can be overridden by - passing `--quiet` together with `--banner=yes` ([#23342](https://github.com/JuliaLang/julia/issues/23342)). - - * The option `--precompiled` has been renamed to `--sysimage-native-code` ([#23054](https://github.com/JuliaLang/julia/issues/23054)). - - * The option `--compilecache` has been renamed to `--compiled-modules` ([#23054](https://github.com/JuliaLang/julia/issues/23054)). - + +[#27930]: https://github.com/JuliaLang/julia/issues/27930 diff --git a/src/index.md b/src/index.md index f50e24b..e6049d3 100644 --- a/src/index.md +++ b/src/index.md @@ -1,11 +1,16 @@ -# 줄리아 0.7 문서 +# 줄리아 1.0 문서 -환영합니다. 줄리아 0.7 문서입니다. +환영합니다. 줄리아 1.0 문서입니다. -지난 버전에 이어, 새롭게 바뀐 점은 [릴리즈 노트](NEWS.md)에서 확인하세요. +전체적으로 언어를 훑어보며, 0.6 버전 이후 어떤 것들이 바뀌었는지 +[블로그 글](https://julialang.org/blog/2018/08/one-point-zero)(번역 필요)을 읽어 주세요. +0.7 버전은 기존의 패키지와 코드를 업그레이드 하기 위해, 1.0 릴리즈와 같이 출시한 버전입니다. +0.7과 1.0의 차이는 지원 중단 경고문(deprecation warnings) 부분을 삭제한 것입니다. +0.6으로부터 바뀐 모든 내용은 [0.7 버전 릴리즈 노트](https://github.com/juliakorea/translate-doc/wiki/NEWS)를 봐 주세요. !!! note 한글 문서 번역은 [깃헙](https://github.com/juliakorea/translate-doc)에서 누구나 참여하실 수 있습니다. + 많은 참여 부탁드립니다. ### [소개글](@id man-introduction) diff --git a/src/manual/profile.md b/src/manual/profile.md index 00d91cf..e3403cd 100644 --- a/src/manual/profile.md +++ b/src/manual/profile.md @@ -312,3 +312,34 @@ memory allocation). The recommended procedure is to force compilation by executi you want to analyze, then call [`Profile.clear_malloc_data()`](@ref) to reset all allocation counters. Finally, execute the desired commands and quit Julia to trigger the generation of the `.mem` files. + +# External Profiling + +Currently Julia supports `Intel VTune`, `OProfile` and `perf` as external profiling tools. + +Depending on the tool you choose, compile with `USE_INTEL_JITEVENTS`, `USE_OPROFILE_JITEVENTS` and +`USE_PERF_JITEVENTS` set to 1 in `Make.user`. Multiple flags are supported. + +Before running Julia set the environment variable `ENABLE_JITPROFILING` to 1. + +Now you have a multitude of ways to employ those tools! +For example with `OProfile` you can try a simple recording : + +``` +>ENABLE_JITPROFILING=1 sudo operf -Vdebug ./julia test/fastmath.jl +>opreport -l `which ./julia` +``` + +Or similary with with `perf` : + +``` +$ ENABLE_JITPROFILING=1 perf record -o /tmp/perf.data --call-graph dwarf ./julia /test/fastmath.jl +$ perf report --call-graph -G +``` + +There are many more interesting things that you can measure about your program, to get a comprehensive list +please read the [Linux perf examples page](http://www.brendangregg.com/perf.html). + +Remember that perf saves for each execution a `perf.data` file that, even for small programs, can get +quite large. Also the perf LLVM module saves temporarly debug objects in `~/.debug/jit`, remember +to clean that folder frequently. diff --git a/src/manual/types.md b/src/manual/types.md index 7cd8c58..44eb1c7 100644 --- a/src/manual/types.md +++ b/src/manual/types.md @@ -1383,7 +1383,7 @@ for cases where you don't need a more elaborate hierarchy. julia> struct Val{x} end -julia> Base.@pure Val(x) = Val{x}() +julia> Val(x) = Val{x}() Val ``` diff --git a/src/stdlib/REPL.md b/src/stdlib/REPL.md index 42348a1..0920ab3 100644 --- a/src/stdlib/REPL.md +++ b/src/stdlib/REPL.md @@ -6,18 +6,12 @@ it has a searchable history, tab-completion, many helpful keybindings, and dedic shell modes. The REPL can be started by simply calling `julia` with no arguments or double-clicking on the executable: -``` -$ julia - _ - _ _ _(_)_ | A fresh approach to technical computing - (_) | (_) (_) | Documentation: https://docs.julialang.org - _ _ _| |_ __ _ | Type "?help" for help. - | | | | | | |/ _` | | - | | |_| | | | (_| | | Version 0.6.0-dev.2493 (2017-01-31 18:53 UTC) - _/ |\__'_|_|_|\__'_| | Commit c99e12c* (0 days old master) -|__/ | x86_64-linux-gnu - -julia> +```@eval +io = IOBuffer() +Base.banner(io) +banner = String(take!(io)) +import Markdown +Markdown.parse("```\n\$ julia\n\n$(banner)\njulia>\n```") ``` To exit the interactive session, type `^D` -- the control key together with the `d` key on a blank diff --git a/tools/check_codex.jl b/tools/check_codex.jl index d815fb2..551e8ee 100644 --- a/tools/check_codex.jl +++ b/tools/check_codex.jl @@ -19,7 +19,7 @@ const julia_doc_src_path = abspath(JULIA_PATH, "doc", "src") translated_files = [] function check_src_and_codex(path1, path2) - ignore_assets = ["custom.css", "font-iropke-batang.css", "fonts"] + ignore_assets = ["custom.css", "font-iropke-batang.css", "fonts", "HISTORY.md"] src_codex_diff = `diff -qr $path1 $path2` lines = readlines(ignorestatus(src_codex_diff)) for line in lines From 6ddaf167830d87e030836fc1f57f15818a85cdeb Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Fri, 17 Aug 2018 18:48:04 +0900 Subject: [PATCH 052/153] update Julia Commit cd5e5a38c5 --- codex/base/arrays.md | 2 ++ codex/devdocs/object.md | 2 +- codex/manual/noteworthy-differences.md | 2 +- codex/stdlib/REPL.md | 2 +- src/base/arrays.md | 2 ++ src/devdocs/object.md | 2 +- src/manual/noteworthy-differences.md | 2 +- src/stdlib/REPL.md | 2 +- 8 files changed, 10 insertions(+), 6 deletions(-) diff --git a/codex/base/arrays.md b/codex/base/arrays.md index 521cbc2..260649a 100644 --- a/codex/base/arrays.md +++ b/codex/base/arrays.md @@ -53,6 +53,8 @@ Base.axes(::AbstractArray, ::Any) Base.length(::AbstractArray) Base.eachindex Base.IndexStyle +Base.IndexLinear +Base.IndexCartesian Base.conj! Base.stride Base.strides diff --git a/codex/devdocs/object.md b/codex/devdocs/object.md index cf9223f..49d1e46 100644 --- a/codex/devdocs/object.md +++ b/codex/devdocs/object.md @@ -1,6 +1,6 @@ # Memory layout of Julia Objects -## Object layout (jl_value_t) +## Object layout (`jl_value_t`) The `jl_value_t` struct is the name for a block of memory owned by the Julia Garbage Collector, representing the data associated with a Julia object in memory. Absent any type information, it diff --git a/codex/manual/noteworthy-differences.md b/codex/manual/noteworthy-differences.md index 9aff0df..c45d7b1 100644 --- a/codex/manual/noteworthy-differences.md +++ b/codex/manual/noteworthy-differences.md @@ -253,7 +253,7 @@ For users coming to Julia from R, these are some noteworthy differences: Floating point literals are closer in behavior to C/C++. Octal (prefixed with `0o`) and binary (prefixed with `0b`) literals are also treated as unsigned. * String literals can be delimited with either `"` or `"""`, `"""` delimited literals can contain - `"` characters without quoting it like `"\""` String literals can have values of other variables + `"` characters without quoting it like `"\""`. String literals can have values of other variables or expressions interpolated into them, indicated by `$variablename` or `$(expression)`, which evaluates the variable name or the expression in the context of the function. * `//` indicates a [`Rational`](@ref) number, and not a single-line comment (which is `#` in Julia) diff --git a/codex/stdlib/REPL.md b/codex/stdlib/REPL.md index 0920ab3..2afa93d 100644 --- a/codex/stdlib/REPL.md +++ b/codex/stdlib/REPL.md @@ -15,7 +15,7 @@ Markdown.parse("```\n\$ julia\n\n$(banner)\njulia>\n```") ``` To exit the interactive session, type `^D` -- the control key together with the `d` key on a blank -line -- or type `quit()` followed by the return or enter key. The REPL greets you with a banner +line -- or type `exit()` followed by the return or enter key. The REPL greets you with a banner and a `julia>` prompt. ## The different prompt modes diff --git a/src/base/arrays.md b/src/base/arrays.md index 521cbc2..260649a 100644 --- a/src/base/arrays.md +++ b/src/base/arrays.md @@ -53,6 +53,8 @@ Base.axes(::AbstractArray, ::Any) Base.length(::AbstractArray) Base.eachindex Base.IndexStyle +Base.IndexLinear +Base.IndexCartesian Base.conj! Base.stride Base.strides diff --git a/src/devdocs/object.md b/src/devdocs/object.md index cf9223f..49d1e46 100644 --- a/src/devdocs/object.md +++ b/src/devdocs/object.md @@ -1,6 +1,6 @@ # Memory layout of Julia Objects -## Object layout (jl_value_t) +## Object layout (`jl_value_t`) The `jl_value_t` struct is the name for a block of memory owned by the Julia Garbage Collector, representing the data associated with a Julia object in memory. Absent any type information, it diff --git a/src/manual/noteworthy-differences.md b/src/manual/noteworthy-differences.md index 9aff0df..c45d7b1 100644 --- a/src/manual/noteworthy-differences.md +++ b/src/manual/noteworthy-differences.md @@ -253,7 +253,7 @@ For users coming to Julia from R, these are some noteworthy differences: Floating point literals are closer in behavior to C/C++. Octal (prefixed with `0o`) and binary (prefixed with `0b`) literals are also treated as unsigned. * String literals can be delimited with either `"` or `"""`, `"""` delimited literals can contain - `"` characters without quoting it like `"\""` String literals can have values of other variables + `"` characters without quoting it like `"\""`. String literals can have values of other variables or expressions interpolated into them, indicated by `$variablename` or `$(expression)`, which evaluates the variable name or the expression in the context of the function. * `//` indicates a [`Rational`](@ref) number, and not a single-line comment (which is `#` in Julia) diff --git a/src/stdlib/REPL.md b/src/stdlib/REPL.md index 0920ab3..2afa93d 100644 --- a/src/stdlib/REPL.md +++ b/src/stdlib/REPL.md @@ -15,7 +15,7 @@ Markdown.parse("```\n\$ julia\n\n$(banner)\njulia>\n```") ``` To exit the interactive session, type `^D` -- the control key together with the `d` key on a blank -line -- or type `quit()` followed by the return or enter key. The REPL greets you with a banner +line -- or type `exit()` followed by the return or enter key. The REPL greets you with a banner and a `julia>` prompt. ## The different prompt modes From 47e3772f71c01cd98c375207b00afbdf822c7019 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Wed, 22 Aug 2018 00:14:16 +0900 Subject: [PATCH 053/153] update Julia Commit ae0738ebc7 --- codex/base/numbers.md | 16 ++++---- codex/base/sort.md | 12 ++++-- codex/devdocs/gc-sa.md | 4 +- codex/devdocs/llvm.md | 2 +- codex/manual/environment-variables.md | 9 +++++ codex/manual/functions.md | 7 ++-- codex/manual/index.md | 39 ------------------- .../integers-and-floating-point-numbers.md | 4 +- codex/manual/modules.md | 11 ++---- codex/manual/parallel-computing.md | 10 ++--- codex/manual/style-guide.md | 4 +- codex/manual/variables-and-scoping.md | 4 +- src/base/numbers.md | 16 ++++---- src/base/sort.md | 12 ++++-- src/devdocs/gc-sa.md | 4 +- src/devdocs/llvm.md | 2 +- src/manual/environment-variables.md | 9 +++++ src/manual/functions.md | 7 ++-- src/manual/index.md | 39 ------------------- src/manual/modules.md | 11 ++---- src/manual/parallel-computing.md | 10 ++--- src/manual/style-guide.md | 4 +- src/manual/variables-and-scoping.md | 4 +- 23 files changed, 96 insertions(+), 144 deletions(-) delete mode 100644 codex/manual/index.md delete mode 100644 src/manual/index.md diff --git a/codex/base/numbers.md b/codex/base/numbers.md index 190584b..50e6d2b 100644 --- a/codex/base/numbers.md +++ b/codex/base/numbers.md @@ -89,8 +89,6 @@ Base.isinteger Base.isreal Core.Float32(::Any) Core.Float64(::Any) -Base.GMP.BigInt(::Any) -Base.MPFR.BigFloat(::Any) Base.Rounding.rounding Base.Rounding.setrounding(::Type, ::Any) Base.Rounding.setrounding(::Function, ::Type, ::RoundingMode) @@ -113,18 +111,22 @@ Base.@int128_str Base.@uint128_str ``` -## BigFloats +## BigFloats and BigInts -The [`BigFloat`](@ref) type implements arbitrary-precision floating-point arithmetic using -the [GNU MPFR library](http://www.mpfr.org/). +The [`BigFloat`](@ref) and [`BigInt`](@ref) types implements +arbitrary-precision floating point and integer arithmetic, respectively. For +[`BigFloat`](@ref) the [GNU MPFR library](http://www.mpfr.org/) is used, +and for [`BigInt`](@ref) the [GNU Multiple Precision Arithmetic Library (GMP)] +(https://gmplib.org) is used. ```@docs +Base.MPFR.BigFloat(::Any) Base.precision Base.MPFR.precision(::Type{BigFloat}) Base.MPFR.setprecision Base.MPFR.BigFloat(x, prec::Int) -BigFloat(x::Union{Integer, AbstractFloat, String}, rounding::RoundingMode) +Base.MPFR.BigFloat(x::Union{Integer, AbstractFloat, String}, rounding::RoundingMode) Base.MPFR.BigFloat(x, prec::Int, rounding::RoundingMode) -Base.MPFR.BigFloat(x::String) +Base.GMP.BigInt(::Any) Base.@big_str ``` diff --git a/codex/base/sort.md b/codex/base/sort.md index a3c3b7c..17a9b8c 100644 --- a/codex/base/sort.md +++ b/codex/base/sort.md @@ -110,6 +110,10 @@ can be specified via the `lt` keyword. Base.sort! Base.sort Base.sortperm +Base.InsertionSort +Base.MergeSort +Base.QuickSort +Base.PartialQuickSort Base.Sort.sortperm! Base.Sort.sortslices ``` @@ -131,10 +135,10 @@ Base.Sort.partialsortperm! There are currently four sorting algorithms available in base Julia: - * `InsertionSort` - * `QuickSort` - * `PartialQuickSort(k)` - * `MergeSort` + * [`InsertionSort`](@ref) + * [`QuickSort`](@ref) + * [`PartialQuickSort(k)`](@ref) + * [`MergeSort`](@ref) `InsertionSort` is an O(n^2) stable sorting algorithm. It is efficient for very small `n`, and is used internally by `QuickSort`. diff --git a/codex/devdocs/gc-sa.md b/codex/devdocs/gc-sa.md index 6c5f5a8..0483d19 100644 --- a/codex/devdocs/gc-sa.md +++ b/codex/devdocs/gc-sa.md @@ -251,7 +251,9 @@ jl_ast_context_t *jl_ast_ctx(fl_context_t *fl) JL_GLOBALLY_ROOTED; This annotations is essentially equivalent to JL_GLOBALLY_ROOTED, except that is should only be used if those values are globally rooted by virtue of being -a leaftype. The rooting of leaftypes is a bit complicated, and we can generally +a leaftype. The rooting of leaftypes is a bit complicated. They are generally +rooted through `cache` field of the corresponding `TypeName`, which itself is +rooted by the containing module (so they're rooted as long as the containing module is ok) and we can generally assume that leaftypes are rooted where they are used, but we may refine this property in the future, so the separate annotation helps split out the reason for being globally rooted. diff --git a/codex/devdocs/llvm.md b/codex/devdocs/llvm.md index 9ed7da7..bc64345 100644 --- a/codex/devdocs/llvm.md +++ b/codex/devdocs/llvm.md @@ -42,7 +42,7 @@ The default version of LLVM is specified in `deps/Versions.make`. You can overri a file called `Make.user` in the top-level directory and adding a line to it such as: ``` -LLVM_VER = 3.5.0 +LLVM_VER = 6.0.1 ``` Besides the LLVM release numerals, you can also use `LLVM_VER = svn` to build against the latest diff --git a/codex/manual/environment-variables.md b/codex/manual/environment-variables.md index b27ff27..d38aa0f 100644 --- a/codex/manual/environment-variables.md +++ b/codex/manual/environment-variables.md @@ -65,6 +65,15 @@ and a global configuration search path of /etc/julia/startup.jl ``` +### `JULIA_PROJECT` + +A directory path that points to the current Julia project. Setting this +environment variable has the same effect as specifying the `--project` start-up +option, but `--project` has higher precedence. If the variable is set to `@.`, +Julia tries to find a project directory that contains `Project.toml` or +`JuliaProject.toml` file from the current directory and its parents. See also +the chapter on [Code Loading](@ref). + ### `JULIA_LOAD_PATH` A separated list of absolute paths that are to be appended to the variable diff --git a/codex/manual/functions.md b/codex/manual/functions.md index 45c170b..5b57f6a 100644 --- a/codex/manual/functions.md +++ b/codex/manual/functions.md @@ -541,6 +541,10 @@ function f(x; y=0, kwargs...) end ``` +Inside `f`, `kwargs` will be a key-value iterator over a named tuple. Named +tuples (as well as dictionaries with keys of `Symbol`) can be passed as keyword +arguments using a semicolon in a call, e.g. `f(x, z=1; kwargs...)`. + If a keyword argument is not assigned a default value in the method definition, then it is *required*: an [`UndefKeywordError`](@ref) exception will be thrown if the caller does not assign it a value: @@ -552,9 +556,6 @@ f(3, y=5) # ok, y is assigned f(3) # throws UndefKeywordError(:y) ``` -Inside `f`, `kwargs` will be a named tuple. Named tuples (as well as dictionaries) can be passed as -keyword arguments using a semicolon in a call, e.g. `f(x, z=1; kwargs...)`. - One can also pass `key => value` expressions after a semicolon. For example, `plot(x, y; :width => 2)` is equivalent to `plot(x, y, width=2)`. This is useful in situations where the keyword name is computed at runtime. diff --git a/codex/manual/index.md b/codex/manual/index.md deleted file mode 100644 index 3ae00cf..0000000 --- a/codex/manual/index.md +++ /dev/null @@ -1,39 +0,0 @@ -# The Julia Manual - - * [Introduction](@ref man-introduction) - * [Getting Started](@ref man-getting-started) - * [Variables](@ref) - * [Integers and Floating-Point Numbers](@ref) - * [Mathematical Operations and Elementary Functions](@ref) - * [Complex and Rational Numbers](@ref) - * [Strings](@ref) - * [Functions](@ref) - * [Control Flow](@ref) - * [Scope of Variables](@ref scope-of-variables) - * [Types](@ref man-types) - * [Methods](@ref) - * [Constructors](@ref man-constructors) - * [Conversion and Promotion](@ref conversion-and-promotion) - * [Interfaces](@ref) - * [Modules](@ref) - * [Documentation](@ref) - * [Metaprogramming](@ref) - * [Multi-dimensional Arrays](@ref man-multi-dim-arrays) - * [Missing Values](@ref missing) - * [Networking and Streams](@ref) - * [Parallel Computing](@ref) - * [Dates](@ref) - * [Running External Programs](@ref) - * [Calling C and Fortran Code](@ref) - * [Handling Operating System Variation](@ref) - * [Environment Variables](@ref) - * [Embedding Julia](@ref) - * [Profiling](@ref) - * [Memory allocation analysis](@ref) - * [Stack Traces](@ref) - * [Performance Tips](@ref man-performance-tips) - * [Workflow Tips](@ref man-workflow-tips) - * [Style Guide](@ref) - * [Frequently Asked Questions](@ref) - * [Noteworthy Differences from other Languages](@ref) - * [Unicode Input](@ref) diff --git a/codex/manual/integers-and-floating-point-numbers.md b/codex/manual/integers-and-floating-point-numbers.md index b218ab8..8478d49 100644 --- a/codex/manual/integers-and-floating-point-numbers.md +++ b/codex/manual/integers-and-floating-point-numbers.md @@ -215,7 +215,7 @@ UInt128: [0,340282366920938463463374607431768211455] ``` The values returned by [`typemin`](@ref) and [`typemax`](@ref) are always of the given argument -type. (The above expression uses several features we have yet to introduce, including [for loops](@ref man-loops), +type. (The above expression uses several features that have yet to be introduced, including [for loops](@ref man-loops), [Strings](@ref man-strings), and [Interpolation](@ref), but should be easy enough to understand for users with some existing programming experience.) @@ -678,7 +678,7 @@ where syntactic conflicts arise: * The 32-bit floating-point literal expression `1.5f22` could be interpreted as the numeric literal `1.5` multiplied by the variable `f22`. -In all cases, we resolve the ambiguity in favor of interpretation as numeric literals: +In all cases the ambiguity is resolved in favor of interpretation as numeric literals: * Expressions starting with `0x` are always hexadecimal literals. * Expressions starting with a numeric literal followed by `e` or `E` are always floating-point literals. diff --git a/codex/manual/modules.md b/codex/manual/modules.md index 7406560..ef073cb 100644 --- a/codex/manual/modules.md +++ b/codex/manual/modules.md @@ -232,13 +232,10 @@ For file dependencies, a change is determined by examining whether the modificat of each file loaded by `include` or added explicitly by `include_dependency` is unchanged, or equal to the modification time truncated to the nearest second (to accommodate systems that can't copy mtime with sub-second accuracy). It also takes into account whether the path to the file chosen -by the search logic in `require` matches the path that had created the precompile file. - -It also takes into account the set of dependencies already loaded into the current process and -won't recompile those modules, even if their files change or disappear, in order to avoid creating -incompatibilities between the running system and the precompile cache. If you want to have changes -to the source reflected in the running system, you should call `reload("Module")` on the module -you changed, and any module that depended on it in which you want to see the change reflected. +by the search logic in `require` matches the path that had created the precompile file. It also takes +into account the set of dependencies already loaded into the current process and won't recompile those +modules, even if their files change or disappear, in order to avoid creating incompatibilities between +the running system and the precompile cache. If you know that a module is *not* safe to precompile your module (for example, for one of the reasons described below), you should diff --git a/codex/manual/parallel-computing.md b/codex/manual/parallel-computing.md index 5f18d97..a073121 100644 --- a/codex/manual/parallel-computing.md +++ b/codex/manual/parallel-computing.md @@ -158,7 +158,7 @@ julia> data = [i for i in c] Consider a simple example using channels for inter-task communication. We start 4 tasks to process data from a single `jobs` channel. Jobs, identified by an id (`job_id`), are written to the channel. -Each task in this simulation reads a `job_id`, waits for a random amout of time and writes back +Each task in this simulation reads a `job_id`, waits for a random amount of time and writes back a tuple of `job_id` and the simulated time to the results channel. Finally all the `results` are printed out. @@ -1792,10 +1792,10 @@ mpirun -np 4 ./julia example.jl ``` [^1]: - in this context, mpi refers to the mpi-1 standard. beginning with mpi-2, the mpi standards committee - introduced a new set of communication mechanisms, collectively referred to as remote memory access - (rma). the motivation for adding rma to the mpi standard was to facilitate one-sided communication - patterns. for additional information on the latest mpi standard, see [http://mpi-forum.org/docs](http://mpi-forum.org/docs/). + In this context, MPI refers to the MPI-1 standard. Beginning with MPI-2, the MPI standards committee + introduced a new set of communication mechanisms, collectively referred to as Remote Memory Access + (RMA). The motivation for adding rma to the MPI standard was to facilitate one-sided communication + patterns. For additional information on the latest MPI standard, see [http://mpi-forum.org/docs](http://mpi-forum.org/docs/). [^2]: [Julia GPU man pages](http://juliagpu.github.io/CUDAnative.jl/stable/man/usage.html#Julia-support-1) diff --git a/codex/manual/style-guide.md b/codex/manual/style-guide.md index 624297d..a39697d 100644 --- a/codex/manual/style-guide.md +++ b/codex/manual/style-guide.md @@ -130,7 +130,7 @@ a = Vector{Union{Int,AbstractString,Tuple,Array}}(undef, n) In this case `Vector{Any}(undef, n)` is better. It is also more helpful to the compiler to annotate specific uses (e.g. `a[i]::Int`) than to try to pack many alternatives into one type. -## Use naming conventions consistent with Julia's `base/` +## Use naming conventions consistent with Julia `base/` * modules and type names use capitalization and camel case: `module SparseArrays`, `struct UnitRange`. * functions are lowercase ([`maximum`](@ref), [`convert`](@ref)) and, when readable, with multiple @@ -143,7 +143,7 @@ uses (e.g. `a[i]::Int`) than to try to pack many alternatives into one type. If a function name requires multiple words, consider whether it might represent more than one concept and might be better split into pieces. -## Write functions with argument ordering similar to Julia's Base +## Write functions with argument ordering similar to Julia Base As a general rule, the Base library uses the following order of arguments to functions, as applicable: diff --git a/codex/manual/variables-and-scoping.md b/codex/manual/variables-and-scoping.md index 496730a..ab6f196 100644 --- a/codex/manual/variables-and-scoping.md +++ b/codex/manual/variables-and-scoping.md @@ -495,7 +495,7 @@ are constant by default. Note that `const` only affects the variable binding; the variable may be bound to a mutable object (such as an array), and that object may still be modified. Additionally when one tries -to assign a value a variable that is declared constant the following scenarios are possible: +to assign a value to a variable that is declared constant the following scenarios are possible: * if a new value has a different type than the type of the constant then an error is thrown: ```jldoctest @@ -522,7 +522,7 @@ julia> const z = 100 julia> z = 100 100 ``` -The last rule applies for immutable objects even if the vairable binding would change, e.g.: +The last rule applies for immutable objects even if the variable binding would change, e.g.: ```julia-repl julia> const s1 = "1" "1" diff --git a/src/base/numbers.md b/src/base/numbers.md index 190584b..50e6d2b 100644 --- a/src/base/numbers.md +++ b/src/base/numbers.md @@ -89,8 +89,6 @@ Base.isinteger Base.isreal Core.Float32(::Any) Core.Float64(::Any) -Base.GMP.BigInt(::Any) -Base.MPFR.BigFloat(::Any) Base.Rounding.rounding Base.Rounding.setrounding(::Type, ::Any) Base.Rounding.setrounding(::Function, ::Type, ::RoundingMode) @@ -113,18 +111,22 @@ Base.@int128_str Base.@uint128_str ``` -## BigFloats +## BigFloats and BigInts -The [`BigFloat`](@ref) type implements arbitrary-precision floating-point arithmetic using -the [GNU MPFR library](http://www.mpfr.org/). +The [`BigFloat`](@ref) and [`BigInt`](@ref) types implements +arbitrary-precision floating point and integer arithmetic, respectively. For +[`BigFloat`](@ref) the [GNU MPFR library](http://www.mpfr.org/) is used, +and for [`BigInt`](@ref) the [GNU Multiple Precision Arithmetic Library (GMP)] +(https://gmplib.org) is used. ```@docs +Base.MPFR.BigFloat(::Any) Base.precision Base.MPFR.precision(::Type{BigFloat}) Base.MPFR.setprecision Base.MPFR.BigFloat(x, prec::Int) -BigFloat(x::Union{Integer, AbstractFloat, String}, rounding::RoundingMode) +Base.MPFR.BigFloat(x::Union{Integer, AbstractFloat, String}, rounding::RoundingMode) Base.MPFR.BigFloat(x, prec::Int, rounding::RoundingMode) -Base.MPFR.BigFloat(x::String) +Base.GMP.BigInt(::Any) Base.@big_str ``` diff --git a/src/base/sort.md b/src/base/sort.md index a3c3b7c..17a9b8c 100644 --- a/src/base/sort.md +++ b/src/base/sort.md @@ -110,6 +110,10 @@ can be specified via the `lt` keyword. Base.sort! Base.sort Base.sortperm +Base.InsertionSort +Base.MergeSort +Base.QuickSort +Base.PartialQuickSort Base.Sort.sortperm! Base.Sort.sortslices ``` @@ -131,10 +135,10 @@ Base.Sort.partialsortperm! There are currently four sorting algorithms available in base Julia: - * `InsertionSort` - * `QuickSort` - * `PartialQuickSort(k)` - * `MergeSort` + * [`InsertionSort`](@ref) + * [`QuickSort`](@ref) + * [`PartialQuickSort(k)`](@ref) + * [`MergeSort`](@ref) `InsertionSort` is an O(n^2) stable sorting algorithm. It is efficient for very small `n`, and is used internally by `QuickSort`. diff --git a/src/devdocs/gc-sa.md b/src/devdocs/gc-sa.md index 6c5f5a8..0483d19 100644 --- a/src/devdocs/gc-sa.md +++ b/src/devdocs/gc-sa.md @@ -251,7 +251,9 @@ jl_ast_context_t *jl_ast_ctx(fl_context_t *fl) JL_GLOBALLY_ROOTED; This annotations is essentially equivalent to JL_GLOBALLY_ROOTED, except that is should only be used if those values are globally rooted by virtue of being -a leaftype. The rooting of leaftypes is a bit complicated, and we can generally +a leaftype. The rooting of leaftypes is a bit complicated. They are generally +rooted through `cache` field of the corresponding `TypeName`, which itself is +rooted by the containing module (so they're rooted as long as the containing module is ok) and we can generally assume that leaftypes are rooted where they are used, but we may refine this property in the future, so the separate annotation helps split out the reason for being globally rooted. diff --git a/src/devdocs/llvm.md b/src/devdocs/llvm.md index 9ed7da7..bc64345 100644 --- a/src/devdocs/llvm.md +++ b/src/devdocs/llvm.md @@ -42,7 +42,7 @@ The default version of LLVM is specified in `deps/Versions.make`. You can overri a file called `Make.user` in the top-level directory and adding a line to it such as: ``` -LLVM_VER = 3.5.0 +LLVM_VER = 6.0.1 ``` Besides the LLVM release numerals, you can also use `LLVM_VER = svn` to build against the latest diff --git a/src/manual/environment-variables.md b/src/manual/environment-variables.md index b27ff27..d38aa0f 100644 --- a/src/manual/environment-variables.md +++ b/src/manual/environment-variables.md @@ -65,6 +65,15 @@ and a global configuration search path of /etc/julia/startup.jl ``` +### `JULIA_PROJECT` + +A directory path that points to the current Julia project. Setting this +environment variable has the same effect as specifying the `--project` start-up +option, but `--project` has higher precedence. If the variable is set to `@.`, +Julia tries to find a project directory that contains `Project.toml` or +`JuliaProject.toml` file from the current directory and its parents. See also +the chapter on [Code Loading](@ref). + ### `JULIA_LOAD_PATH` A separated list of absolute paths that are to be appended to the variable diff --git a/src/manual/functions.md b/src/manual/functions.md index 45c170b..5b57f6a 100644 --- a/src/manual/functions.md +++ b/src/manual/functions.md @@ -541,6 +541,10 @@ function f(x; y=0, kwargs...) end ``` +Inside `f`, `kwargs` will be a key-value iterator over a named tuple. Named +tuples (as well as dictionaries with keys of `Symbol`) can be passed as keyword +arguments using a semicolon in a call, e.g. `f(x, z=1; kwargs...)`. + If a keyword argument is not assigned a default value in the method definition, then it is *required*: an [`UndefKeywordError`](@ref) exception will be thrown if the caller does not assign it a value: @@ -552,9 +556,6 @@ f(3, y=5) # ok, y is assigned f(3) # throws UndefKeywordError(:y) ``` -Inside `f`, `kwargs` will be a named tuple. Named tuples (as well as dictionaries) can be passed as -keyword arguments using a semicolon in a call, e.g. `f(x, z=1; kwargs...)`. - One can also pass `key => value` expressions after a semicolon. For example, `plot(x, y; :width => 2)` is equivalent to `plot(x, y, width=2)`. This is useful in situations where the keyword name is computed at runtime. diff --git a/src/manual/index.md b/src/manual/index.md deleted file mode 100644 index 3ae00cf..0000000 --- a/src/manual/index.md +++ /dev/null @@ -1,39 +0,0 @@ -# The Julia Manual - - * [Introduction](@ref man-introduction) - * [Getting Started](@ref man-getting-started) - * [Variables](@ref) - * [Integers and Floating-Point Numbers](@ref) - * [Mathematical Operations and Elementary Functions](@ref) - * [Complex and Rational Numbers](@ref) - * [Strings](@ref) - * [Functions](@ref) - * [Control Flow](@ref) - * [Scope of Variables](@ref scope-of-variables) - * [Types](@ref man-types) - * [Methods](@ref) - * [Constructors](@ref man-constructors) - * [Conversion and Promotion](@ref conversion-and-promotion) - * [Interfaces](@ref) - * [Modules](@ref) - * [Documentation](@ref) - * [Metaprogramming](@ref) - * [Multi-dimensional Arrays](@ref man-multi-dim-arrays) - * [Missing Values](@ref missing) - * [Networking and Streams](@ref) - * [Parallel Computing](@ref) - * [Dates](@ref) - * [Running External Programs](@ref) - * [Calling C and Fortran Code](@ref) - * [Handling Operating System Variation](@ref) - * [Environment Variables](@ref) - * [Embedding Julia](@ref) - * [Profiling](@ref) - * [Memory allocation analysis](@ref) - * [Stack Traces](@ref) - * [Performance Tips](@ref man-performance-tips) - * [Workflow Tips](@ref man-workflow-tips) - * [Style Guide](@ref) - * [Frequently Asked Questions](@ref) - * [Noteworthy Differences from other Languages](@ref) - * [Unicode Input](@ref) diff --git a/src/manual/modules.md b/src/manual/modules.md index 7406560..ef073cb 100644 --- a/src/manual/modules.md +++ b/src/manual/modules.md @@ -232,13 +232,10 @@ For file dependencies, a change is determined by examining whether the modificat of each file loaded by `include` or added explicitly by `include_dependency` is unchanged, or equal to the modification time truncated to the nearest second (to accommodate systems that can't copy mtime with sub-second accuracy). It also takes into account whether the path to the file chosen -by the search logic in `require` matches the path that had created the precompile file. - -It also takes into account the set of dependencies already loaded into the current process and -won't recompile those modules, even if their files change or disappear, in order to avoid creating -incompatibilities between the running system and the precompile cache. If you want to have changes -to the source reflected in the running system, you should call `reload("Module")` on the module -you changed, and any module that depended on it in which you want to see the change reflected. +by the search logic in `require` matches the path that had created the precompile file. It also takes +into account the set of dependencies already loaded into the current process and won't recompile those +modules, even if their files change or disappear, in order to avoid creating incompatibilities between +the running system and the precompile cache. If you know that a module is *not* safe to precompile your module (for example, for one of the reasons described below), you should diff --git a/src/manual/parallel-computing.md b/src/manual/parallel-computing.md index 5f18d97..a073121 100644 --- a/src/manual/parallel-computing.md +++ b/src/manual/parallel-computing.md @@ -158,7 +158,7 @@ julia> data = [i for i in c] Consider a simple example using channels for inter-task communication. We start 4 tasks to process data from a single `jobs` channel. Jobs, identified by an id (`job_id`), are written to the channel. -Each task in this simulation reads a `job_id`, waits for a random amout of time and writes back +Each task in this simulation reads a `job_id`, waits for a random amount of time and writes back a tuple of `job_id` and the simulated time to the results channel. Finally all the `results` are printed out. @@ -1792,10 +1792,10 @@ mpirun -np 4 ./julia example.jl ``` [^1]: - in this context, mpi refers to the mpi-1 standard. beginning with mpi-2, the mpi standards committee - introduced a new set of communication mechanisms, collectively referred to as remote memory access - (rma). the motivation for adding rma to the mpi standard was to facilitate one-sided communication - patterns. for additional information on the latest mpi standard, see [http://mpi-forum.org/docs](http://mpi-forum.org/docs/). + In this context, MPI refers to the MPI-1 standard. Beginning with MPI-2, the MPI standards committee + introduced a new set of communication mechanisms, collectively referred to as Remote Memory Access + (RMA). The motivation for adding rma to the MPI standard was to facilitate one-sided communication + patterns. For additional information on the latest MPI standard, see [http://mpi-forum.org/docs](http://mpi-forum.org/docs/). [^2]: [Julia GPU man pages](http://juliagpu.github.io/CUDAnative.jl/stable/man/usage.html#Julia-support-1) diff --git a/src/manual/style-guide.md b/src/manual/style-guide.md index 624297d..a39697d 100644 --- a/src/manual/style-guide.md +++ b/src/manual/style-guide.md @@ -130,7 +130,7 @@ a = Vector{Union{Int,AbstractString,Tuple,Array}}(undef, n) In this case `Vector{Any}(undef, n)` is better. It is also more helpful to the compiler to annotate specific uses (e.g. `a[i]::Int`) than to try to pack many alternatives into one type. -## Use naming conventions consistent with Julia's `base/` +## Use naming conventions consistent with Julia `base/` * modules and type names use capitalization and camel case: `module SparseArrays`, `struct UnitRange`. * functions are lowercase ([`maximum`](@ref), [`convert`](@ref)) and, when readable, with multiple @@ -143,7 +143,7 @@ uses (e.g. `a[i]::Int`) than to try to pack many alternatives into one type. If a function name requires multiple words, consider whether it might represent more than one concept and might be better split into pieces. -## Write functions with argument ordering similar to Julia's Base +## Write functions with argument ordering similar to Julia Base As a general rule, the Base library uses the following order of arguments to functions, as applicable: diff --git a/src/manual/variables-and-scoping.md b/src/manual/variables-and-scoping.md index 496730a..ab6f196 100644 --- a/src/manual/variables-and-scoping.md +++ b/src/manual/variables-and-scoping.md @@ -495,7 +495,7 @@ are constant by default. Note that `const` only affects the variable binding; the variable may be bound to a mutable object (such as an array), and that object may still be modified. Additionally when one tries -to assign a value a variable that is declared constant the following scenarios are possible: +to assign a value to a variable that is declared constant the following scenarios are possible: * if a new value has a different type than the type of the constant then an error is thrown: ```jldoctest @@ -522,7 +522,7 @@ julia> const z = 100 julia> z = 100 100 ``` -The last rule applies for immutable objects even if the vairable binding would change, e.g.: +The last rule applies for immutable objects even if the variable binding would change, e.g.: ```julia-repl julia> const s1 = "1" "1" From 440cc22567f301e87e8a94129c8660497e596b2d Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Thu, 23 Aug 2018 18:25:29 +0900 Subject: [PATCH 054/153] update Julia Commit f31e28a50e --- codex/devdocs/gc-sa.md | 8 ++++---- codex/index.md | 21 +++++++++++++++++++-- src/devdocs/gc-sa.md | 8 ++++---- src/index.md | 28 +++++++++++++++++++++++----- 4 files changed, 50 insertions(+), 15 deletions(-) diff --git a/codex/devdocs/gc-sa.md b/codex/devdocs/gc-sa.md index 0483d19..4cf336b 100644 --- a/codex/devdocs/gc-sa.md +++ b/codex/devdocs/gc-sa.md @@ -253,10 +253,10 @@ This annotations is essentially equivalent to JL_GLOBALLY_ROOTED, except that is should only be used if those values are globally rooted by virtue of being a leaftype. The rooting of leaftypes is a bit complicated. They are generally rooted through `cache` field of the corresponding `TypeName`, which itself is -rooted by the containing module (so they're rooted as long as the containing module is ok) and we can generally -assume that leaftypes are rooted where they are used, but we may refine this -property in the future, so the separate annotation helps split out the reason -for being globally rooted. +rooted by the containing module (so they're rooted as long as the containing +module is ok) and we can generally assume that leaftypes are rooted where they +are used, but we may refine this property in the future, so the separate +annotation helps split out the reason for being globally rooted. The analyzer also automatically detects checks for leaftype-ness and will not complain about missing GC roots on these paths. diff --git a/codex/index.md b/codex/index.md index 855e45d..a627979 100644 --- a/codex/index.md +++ b/codex/index.md @@ -1,6 +1,23 @@ -# Julia 1.0 Documentation +```@eval +io = IOBuffer() +release = isempty(VERSION.prerelease) +v = "$(VERSION.major).$(VERSION.minor)" +!release && (v = v*"-$(first(VERSION.prerelease))") +print(io, """ + # Julia $(v) Documentation -Welcome to the documentation for Julia 1.0. + Welcome to the documentation for Julia $(v). + + """) +if !release + print(io,""" + !!! warning "Work in progress!" + This documentation is for an unreleased, in-development, version of Julia. + """) +end +import Markdown +Markdown.parse(String(take!(io))) +``` Please read the [release blog post](https://julialang.org/blog/2018/08/one-point-zero) for a general overview of the language and many of the changes since Julia v0.6. Note that version 0.7 was released alongside diff --git a/src/devdocs/gc-sa.md b/src/devdocs/gc-sa.md index 0483d19..4cf336b 100644 --- a/src/devdocs/gc-sa.md +++ b/src/devdocs/gc-sa.md @@ -253,10 +253,10 @@ This annotations is essentially equivalent to JL_GLOBALLY_ROOTED, except that is should only be used if those values are globally rooted by virtue of being a leaftype. The rooting of leaftypes is a bit complicated. They are generally rooted through `cache` field of the corresponding `TypeName`, which itself is -rooted by the containing module (so they're rooted as long as the containing module is ok) and we can generally -assume that leaftypes are rooted where they are used, but we may refine this -property in the future, so the separate annotation helps split out the reason -for being globally rooted. +rooted by the containing module (so they're rooted as long as the containing +module is ok) and we can generally assume that leaftypes are rooted where they +are used, but we may refine this property in the future, so the separate +annotation helps split out the reason for being globally rooted. The analyzer also automatically detects checks for leaftype-ness and will not complain about missing GC roots on these paths. diff --git a/src/index.md b/src/index.md index e6049d3..d838fcf 100644 --- a/src/index.md +++ b/src/index.md @@ -1,6 +1,23 @@ -# 줄리아 1.0 문서 +```@eval +io = IOBuffer() +release = isempty(VERSION.prerelease) +v = "$(VERSION.major).$(VERSION.minor)" +!release && (v = v*"-$(first(VERSION.prerelease))") +print(io, """ + # 줄리아 $(v) 문서 -환영합니다. 줄리아 1.0 문서입니다. + 환영합니다. 줄리아 $(v) 문서입니다. + + """) +if !release + print(io,""" + !!! warning "작업 진행 중!" + 개발 버전의 줄리아 문서입니다. + """) +end +import Markdown +Markdown.parse(String(take!(io))) +``` 전체적으로 언어를 훑어보며, 0.6 버전 이후 어떤 것들이 바뀌었는지 [블로그 글](https://julialang.org/blog/2018/08/one-point-zero)(번역 필요)을 읽어 주세요. @@ -8,10 +25,11 @@ 0.7과 1.0의 차이는 지원 중단 경고문(deprecation warnings) 부분을 삭제한 것입니다. 0.6으로부터 바뀐 모든 내용은 [0.7 버전 릴리즈 노트](https://github.com/juliakorea/translate-doc/wiki/NEWS)를 봐 주세요. -!!! note - 한글 문서 번역은 [깃헙](https://github.com/juliakorea/translate-doc)에서 누구나 참여하실 수 있습니다. - 많은 참여 부탁드립니다. +` ` +!!! note "번역 안내" + 한글 문서 번역은 깃헙 [https://github.com/juliakorea/translate-doc](https://github.com/juliakorea/translate-doc)에서 누구나 참여하실 수 있습니다. + 많은 참여 부탁드립니다. ### [소개글](@id man-introduction) From d195d25b1b12b4da802c39eb45b463bd6bb828fb Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Thu, 30 Aug 2018 23:55:30 +0900 Subject: [PATCH 055/153] update Julia Commit 2346be8961 --- codex/devdocs/backtraces.md | 4 ++-- codex/manual/arrays.md | 7 +------ codex/manual/code-loading.md | 2 +- codex/manual/parallel-computing.md | 12 ++++++------ codex/manual/performance-tips.md | 2 +- codex/manual/types.md | 3 --- codex/stdlib/Pkg.md | 3 +++ src/devdocs/backtraces.md | 4 ++-- src/manual/arrays.md | 8 ++------ src/manual/code-loading.md | 2 +- src/manual/parallel-computing.md | 12 ++++++------ src/manual/performance-tips.md | 2 +- src/manual/types.md | 3 --- src/stdlib/Pkg.md | 3 +++ 14 files changed, 29 insertions(+), 38 deletions(-) diff --git a/codex/devdocs/backtraces.md b/codex/devdocs/backtraces.md index ca750b7..a65a494 100644 --- a/codex/devdocs/backtraces.md +++ b/codex/devdocs/backtraces.md @@ -15,10 +15,10 @@ and follow the instructions to generate the debugging information requested. Ta ## [Version/Environment info](@id dev-version-info) No matter the error, we will always need to know what version of Julia you are running. When Julia -first starts up, a header is printed out with a version number and date. Please also include the -output of `versioninfo()` in any report you create: +first starts up, a header is printed out with a version number and date. Please also include the output of `versioninfo()` (exported from the [`InteractiveUtils`](@ref InteractiveUtils.versioninfo) standard library) in any report you create: ```@repl +using InteractiveUtils versioninfo() ``` diff --git a/codex/manual/arrays.md b/codex/manual/arrays.md index de54a61..4b4c4be 100644 --- a/codex/manual/arrays.md +++ b/codex/manual/arrays.md @@ -692,12 +692,7 @@ The following operators are supported for arrays: 2. Binary arithmetic -- `-`, `+`, `*`, `/`, `\`, `^` 3. Comparison -- `==`, `!=`, `≈` ([`isapprox`](@ref)), `≉` -Most of the binary arithmetic operators listed above also operate elementwise -when one argument is scalar: `-`, `+`, and `*` when either argument is scalar, -and `/` and `\` when the denominator is scalar. For example, `[1, 2] + 3 == [4, 5]` -and `[6, 4] / 2 == [3, 2]`. - -Additionally, to enable convenient vectorization of mathematical and other operations, +To enable convenient vectorization of mathematical and other operations, Julia [provides the dot syntax](@ref man-vectorized) `f.(args...)`, e.g. `sin.(x)` or `min.(x,y)`, for elementwise operations over arrays or mixtures of arrays and scalars (a [Broadcasting](@ref) operation); these have the additional advantage of diff --git a/codex/manual/code-loading.md b/codex/manual/code-loading.md index c990de6..603e3cc 100644 --- a/codex/manual/code-loading.md +++ b/codex/manual/code-loading.md @@ -160,7 +160,7 @@ If applying these rules doesn't find a loadable path, the package should be cons In the example manifest file above, to find the path of the first `Priv` package—the one with UUID `ba13f791-ae1d-465a-978b-69c3ad90f72b`—Julia looks for its stanza in the manifest file, sees that it has a `path` entry, looks at `deps/Priv` relative to the `App` project directory—let's suppose the `App` code lives in `/home/me/projects/App`—sees that `/home/me/projects/App/deps/Priv` exists and therefore loads `Priv` from there. -If, on the other hand, Julia was loading the *other* `Priv` package—the one with UUID `2d15fe94-a1f7-436c-a4d8-07a9a496e01c`—it finds its stanza in the manifest, see that it does *not* have a `path` entry, but that it does have a `git-tree-sha1` entry. It then computes the `slug` for this UUID/SHA-1 pair, which is `HDkr` (the exact details of this computation aren't important, but it is consistent and deterministic). This means that the path to this `Priv` package will be `packages/Priv/HDkr/src/Priv.jl` in one of the package depots. Suppose the contents of `DEPOT_PATH` is `["/users/me/.julia", "/usr/local/julia"]`; then Julia will look at the following paths to see if they exist: +If, on the other hand, Julia was loading the *other* `Priv` package—the one with UUID `2d15fe94-a1f7-436c-a4d8-07a9a496e01c`—it finds its stanza in the manifest, see that it does *not* have a `path` entry, but that it does have a `git-tree-sha1` entry. It then computes the `slug` for this UUID/SHA-1 pair, which is `HDkr` (the exact details of this computation aren't important, but it is consistent and deterministic). This means that the path to this `Priv` package will be `packages/Priv/HDkr/src/Priv.jl` in one of the package depots. Suppose the contents of `DEPOT_PATH` is `["/home/me/.julia", "/usr/local/julia"]`; then Julia will look at the following paths to see if they exist: 1. `/home/me/.julia/packages/Priv/HDkr/src/Priv.jl` 2. `/usr/local/julia/packages/Priv/HDkr/src/Priv.jl` diff --git a/codex/manual/parallel-computing.md b/codex/manual/parallel-computing.md index a073121..3dacfb5 100644 --- a/codex/manual/parallel-computing.md +++ b/codex/manual/parallel-computing.md @@ -77,7 +77,7 @@ A channel can be visualized as a pipe, i.e., it has a write end and a read end : # we can schedule `n` instances of `foo` to be active concurrently. for _ in 1:n - @schedule foo() + @async foo() end ``` * Channels are created via the `Channel{T}(sz)` constructor. The channel will only hold objects @@ -184,16 +184,16 @@ julia> function make_jobs(n) julia> n = 12; -julia> @schedule make_jobs(n); # feed the jobs channel with "n" jobs +julia> @async make_jobs(n); # feed the jobs channel with "n" jobs julia> for i in 1:4 # start 4 tasks to process requests in parallel - @schedule do_work() + @async do_work() end julia> @elapsed while n > 0 # print out results job_id, exec_time = take!(results) - println("$job_id finished in $(round(exec_time,2)) seconds") - n = n - 1 + println("$job_id finished in $(round(exec_time; digits=2)) seconds") + global n = n - 1 end 4 finished in 0.22 seconds 3 finished in 0.45 seconds @@ -1086,7 +1086,7 @@ julia> for p in workers() # start tasks on the workers to process requests in pa julia> @elapsed while n > 0 # print out results job_id, exec_time, where = take!(results) - println("$job_id finished in $(round(exec_time,2)) seconds on worker $where") + println("$job_id finished in $(round(exec_time; digits=2)) seconds on worker $where") n = n - 1 end 1 finished in 0.18 seconds on worker 4 diff --git a/codex/manual/performance-tips.md b/codex/manual/performance-tips.md index cd81e9e..a3e08d6 100644 --- a/codex/manual/performance-tips.md +++ b/codex/manual/performance-tips.md @@ -1151,7 +1151,7 @@ The common idiom of using 1:n to index into an AbstractArray is not safe if the and may cause a segmentation fault if bounds checking is turned off. Use `LinearIndices(x)` or `eachindex(x)` instead (see also [offset-arrays](https://docs.julialang.org/en/latest/devdocs/offset-arrays)). -!!!note +!!! note While `@simd` needs to be placed directly in front of an innermost `for` loop, both `@inbounds` and `@fastmath` can be applied to either single expressions or all the expressions that appear within nested blocks of code, e.g., using `@inbounds begin` or `@inbounds for ...`. diff --git a/codex/manual/types.md b/codex/manual/types.md index 44eb1c7..5f307ed 100644 --- a/codex/manual/types.md +++ b/codex/manual/types.md @@ -1152,9 +1152,6 @@ what their types are: julia> typeof(Rational{Int}) DataType -julia> typeof(Union{Real,Float64,Rational}) -DataType - julia> typeof(Union{Real,String}) Union ``` diff --git a/codex/stdlib/Pkg.md b/codex/stdlib/Pkg.md index 7e01e44..1ec7010 100644 --- a/codex/stdlib/Pkg.md +++ b/codex/stdlib/Pkg.md @@ -640,6 +640,9 @@ The build step is executed the first time a package is installed or when explici A package is built by executing the file `deps/build.jl`. ``` +shell> cat deps/build.jl +println("I am being built...") + shell> cat deps/build.log I am being built... diff --git a/src/devdocs/backtraces.md b/src/devdocs/backtraces.md index ca750b7..a65a494 100644 --- a/src/devdocs/backtraces.md +++ b/src/devdocs/backtraces.md @@ -15,10 +15,10 @@ and follow the instructions to generate the debugging information requested. Ta ## [Version/Environment info](@id dev-version-info) No matter the error, we will always need to know what version of Julia you are running. When Julia -first starts up, a header is printed out with a version number and date. Please also include the -output of `versioninfo()` in any report you create: +first starts up, a header is printed out with a version number and date. Please also include the output of `versioninfo()` (exported from the [`InteractiveUtils`](@ref InteractiveUtils.versioninfo) standard library) in any report you create: ```@repl +using InteractiveUtils versioninfo() ``` diff --git a/src/manual/arrays.md b/src/manual/arrays.md index 451879e..071ec87 100644 --- a/src/manual/arrays.md +++ b/src/manual/arrays.md @@ -649,12 +649,8 @@ Base.IndexStyle(::Type{<:MyArray}) = IndexLinear() 2. 이항 산술 연산자 -- `-`, `+`, `*`, `/`, `\`, `^` 3. 비교 연산자 -- `==`, `!=`, `≈` ([`isapprox`](@ref)), `≉` -위에 나열된 대부분의 이항 산술 연산자는 하나의 인수가 스칼라일때도 원소별 연산을 한다: -`-`, `+`, `*`는 두 인수 중 어느 한쪽이 스칼라인 경우, 그리고 `/` 와 `\` 는 분모가 스칼라 인 경우를 지원한다. -예를 들면 다음과 같다: `[1, 2] + 3 == [4, 5]` 그리고 `[6, 4] / 2 == [3, 2]`. - -또한 배열, 혹은 배열과 스칼라의 혼합에 대한 원소별 연산에 대해 -또한, `f.(args...)` 형태의 (예: `sin.(x)`, `min.(x,y)`) [점 문법](@ref man-vectorized)을 사용하여 수학 연산과 다른 연산을 편리하게 벡터화 할 수 있다; +배열 혹은 배열과 스칼라의 혼합에 대한 원소별 연산에 대해 +`f.(args...)` 형태의 (예: `sin.(x)`, `min.(x,y)`) [점 문법](@ref man-vectorized)을 사용하여 수학 연산과 다른 연산을 편리하게 벡터화 할 수 있다; 배열, 혹은 배열과 스칼라의 혼합에 대해 원소별 연산을 하기 위해서 점 문법을 쓸 수 있다 ([브로드캐스팅](@ref Broadcasting) 연산). 추가적인 이점으로는 다른 dot call 과 같이 쓴다면 하나의 루프로 융합한다는 것이다 (예: `sin.(cos.(x))`). diff --git a/src/manual/code-loading.md b/src/manual/code-loading.md index c990de6..603e3cc 100644 --- a/src/manual/code-loading.md +++ b/src/manual/code-loading.md @@ -160,7 +160,7 @@ If applying these rules doesn't find a loadable path, the package should be cons In the example manifest file above, to find the path of the first `Priv` package—the one with UUID `ba13f791-ae1d-465a-978b-69c3ad90f72b`—Julia looks for its stanza in the manifest file, sees that it has a `path` entry, looks at `deps/Priv` relative to the `App` project directory—let's suppose the `App` code lives in `/home/me/projects/App`—sees that `/home/me/projects/App/deps/Priv` exists and therefore loads `Priv` from there. -If, on the other hand, Julia was loading the *other* `Priv` package—the one with UUID `2d15fe94-a1f7-436c-a4d8-07a9a496e01c`—it finds its stanza in the manifest, see that it does *not* have a `path` entry, but that it does have a `git-tree-sha1` entry. It then computes the `slug` for this UUID/SHA-1 pair, which is `HDkr` (the exact details of this computation aren't important, but it is consistent and deterministic). This means that the path to this `Priv` package will be `packages/Priv/HDkr/src/Priv.jl` in one of the package depots. Suppose the contents of `DEPOT_PATH` is `["/users/me/.julia", "/usr/local/julia"]`; then Julia will look at the following paths to see if they exist: +If, on the other hand, Julia was loading the *other* `Priv` package—the one with UUID `2d15fe94-a1f7-436c-a4d8-07a9a496e01c`—it finds its stanza in the manifest, see that it does *not* have a `path` entry, but that it does have a `git-tree-sha1` entry. It then computes the `slug` for this UUID/SHA-1 pair, which is `HDkr` (the exact details of this computation aren't important, but it is consistent and deterministic). This means that the path to this `Priv` package will be `packages/Priv/HDkr/src/Priv.jl` in one of the package depots. Suppose the contents of `DEPOT_PATH` is `["/home/me/.julia", "/usr/local/julia"]`; then Julia will look at the following paths to see if they exist: 1. `/home/me/.julia/packages/Priv/HDkr/src/Priv.jl` 2. `/usr/local/julia/packages/Priv/HDkr/src/Priv.jl` diff --git a/src/manual/parallel-computing.md b/src/manual/parallel-computing.md index a073121..3dacfb5 100644 --- a/src/manual/parallel-computing.md +++ b/src/manual/parallel-computing.md @@ -77,7 +77,7 @@ A channel can be visualized as a pipe, i.e., it has a write end and a read end : # we can schedule `n` instances of `foo` to be active concurrently. for _ in 1:n - @schedule foo() + @async foo() end ``` * Channels are created via the `Channel{T}(sz)` constructor. The channel will only hold objects @@ -184,16 +184,16 @@ julia> function make_jobs(n) julia> n = 12; -julia> @schedule make_jobs(n); # feed the jobs channel with "n" jobs +julia> @async make_jobs(n); # feed the jobs channel with "n" jobs julia> for i in 1:4 # start 4 tasks to process requests in parallel - @schedule do_work() + @async do_work() end julia> @elapsed while n > 0 # print out results job_id, exec_time = take!(results) - println("$job_id finished in $(round(exec_time,2)) seconds") - n = n - 1 + println("$job_id finished in $(round(exec_time; digits=2)) seconds") + global n = n - 1 end 4 finished in 0.22 seconds 3 finished in 0.45 seconds @@ -1086,7 +1086,7 @@ julia> for p in workers() # start tasks on the workers to process requests in pa julia> @elapsed while n > 0 # print out results job_id, exec_time, where = take!(results) - println("$job_id finished in $(round(exec_time,2)) seconds on worker $where") + println("$job_id finished in $(round(exec_time; digits=2)) seconds on worker $where") n = n - 1 end 1 finished in 0.18 seconds on worker 4 diff --git a/src/manual/performance-tips.md b/src/manual/performance-tips.md index cd81e9e..a3e08d6 100644 --- a/src/manual/performance-tips.md +++ b/src/manual/performance-tips.md @@ -1151,7 +1151,7 @@ The common idiom of using 1:n to index into an AbstractArray is not safe if the and may cause a segmentation fault if bounds checking is turned off. Use `LinearIndices(x)` or `eachindex(x)` instead (see also [offset-arrays](https://docs.julialang.org/en/latest/devdocs/offset-arrays)). -!!!note +!!! note While `@simd` needs to be placed directly in front of an innermost `for` loop, both `@inbounds` and `@fastmath` can be applied to either single expressions or all the expressions that appear within nested blocks of code, e.g., using `@inbounds begin` or `@inbounds for ...`. diff --git a/src/manual/types.md b/src/manual/types.md index 44eb1c7..5f307ed 100644 --- a/src/manual/types.md +++ b/src/manual/types.md @@ -1152,9 +1152,6 @@ what their types are: julia> typeof(Rational{Int}) DataType -julia> typeof(Union{Real,Float64,Rational}) -DataType - julia> typeof(Union{Real,String}) Union ``` diff --git a/src/stdlib/Pkg.md b/src/stdlib/Pkg.md index 7e01e44..1ec7010 100644 --- a/src/stdlib/Pkg.md +++ b/src/stdlib/Pkg.md @@ -640,6 +640,9 @@ The build step is executed the first time a package is installed or when explici A package is built by executing the file `deps/build.jl`. ``` +shell> cat deps/build.jl +println("I am being built...") + shell> cat deps/build.log I am being built... From 6820afc6caaf4084a9f652340cb3b45d3f249aa2 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Sun, 2 Sep 2018 17:46:30 +0900 Subject: [PATCH 056/153] update Julia Commit 5ee5de4821 --- codex/manual/getting-started.md | 2 +- codex/manual/performance-tips.md | 6 +++--- src/manual/getting-started.md | 2 +- src/manual/performance-tips.md | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/codex/manual/getting-started.md b/codex/manual/getting-started.md index b41eab6..b648cf8 100644 --- a/codex/manual/getting-started.md +++ b/codex/manual/getting-started.md @@ -111,7 +111,7 @@ julia [switches] -- [programfile] [args...] |`--history-file={yes\|no}` |Load or save history| |`--depwarn={yes\|no\|error}` |Enable or disable syntax and method deprecation warnings (`error` turns warnings into errors)| |`--warn-overwrite={yes\|no}` |Enable or disable method overwrite warnings| -|`-C`, `--cpu-target ` |Limit usage of cpu features up to ; set to `help` to see the available options| +|`-C`, `--cpu-target ` |Limit usage of CPU features up to ``; set to `help` to see the available options| |`-O`, `--optimize={0,1,2,3}` |Set the optimization level (default level is 2 if unspecified or 3 if used without a level)| |`-g`, `-g ` |Enable / Set the level of debug info generation (default level is 1 if unspecified or 2 if used without a level)| |`--inline={yes\|no}` |Control whether inlining is permitted, including overriding `@inline` declarations| diff --git a/codex/manual/performance-tips.md b/codex/manual/performance-tips.md index a3e08d6..b830f34 100644 --- a/codex/manual/performance-tips.md +++ b/codex/manual/performance-tips.md @@ -467,7 +467,7 @@ end ``` the annotation of `c` harms performance. To write performant code involving types constructed at -run-time, use the [function-barrier technique](@ref kernal-functions) discussed below, and ensure +run-time, use the [function-barrier technique](@ref kernel-functions) discussed below, and ensure that the constructed type appears among the argument types of the kernel function so that the kernel operations are properly specialized by the compiler. For example, in the above snippet, as soon as `b` is constructed, it can be passed to another function `k`, the kernel. If, for example, function @@ -576,7 +576,7 @@ optimize the body of the loop. There are several possible fixes: * Use an explicit conversion: `x = oneunit(Float64)` * Initialize with the first loop iteration, to `x = 1 / rand()`, then loop `for i = 2:10` -## [Separate kernel functions (aka, function barriers)](@id kernal-functions) +## [Separate kernel functions (aka, function barriers)](@id kernel-functions) Many functions follow a pattern of performing some set-up work, and then running many iterations to perform a core computation. Where possible, it is a good idea to put these core computations @@ -675,7 +675,7 @@ does not (and cannot) predict its value in advance. This means that code using t function has to be conservative, checking the type on each access of `A`; such code will be very slow. -Now, one very good way to solve such problems is by using the [function-barrier technique](@ref kernal-functions). +Now, one very good way to solve such problems is by using the [function-barrier technique](@ref kernel-functions). However, in some cases you might want to eliminate the type-instability altogether. In such cases, one approach is to pass the dimensionality as a parameter, for example through `Val{T}()` (see ["Value types"](@ref)): diff --git a/src/manual/getting-started.md b/src/manual/getting-started.md index 2ebfa06..201f325 100644 --- a/src/manual/getting-started.md +++ b/src/manual/getting-started.md @@ -91,7 +91,7 @@ julia [switches] -- [programfile] [args...] |`--history-file={yes\|no}` |작업내역을 저장하거나 로드한다| |`--depwarn={yes\|no\|error}` |문법과 함수가 폐기됐다는 경고를 활성화/비활성화 한다 (`error`는 경고를 에러로 바꾼다)| |`--warn-overwrite={yes\|no}` |메소드 오버라이딩 경고를 활성화/비활성화 한다| -|`-C`, `--cpu-target ` |까지의 CUPU기능만을 사용한다; 사용 가능한 옵션을 보려면 `help`로 설정| +|`-C`, `--cpu-target ` |``까지의 CPU 기능만을 사용한다; 사용 가능한 옵션을 보려면 `help`로 설정| |`-O`, `--optimize={0,1,2,3}` |코드 실행시간에 관련된 최적화를 실행한다 (지정되지 않을 경우 2단계 실행, 레벨 이외의 값을 사용할 경우 3단계 실행)| |`-g`, `-g ` |디버그 정보 생성 수준을 활성화/비활성화 합니다 (지정되지 않을 경우 레벨 1, 레벨 이외의 값을 사용할 경우 레벨 2)| |`--inline={yes\|no}` |`@inline`으로 선언된 함수를 덮어쓰는 경우를 포함해서, 인라이닝을 허용할지 결정한다| diff --git a/src/manual/performance-tips.md b/src/manual/performance-tips.md index a3e08d6..b830f34 100644 --- a/src/manual/performance-tips.md +++ b/src/manual/performance-tips.md @@ -467,7 +467,7 @@ end ``` the annotation of `c` harms performance. To write performant code involving types constructed at -run-time, use the [function-barrier technique](@ref kernal-functions) discussed below, and ensure +run-time, use the [function-barrier technique](@ref kernel-functions) discussed below, and ensure that the constructed type appears among the argument types of the kernel function so that the kernel operations are properly specialized by the compiler. For example, in the above snippet, as soon as `b` is constructed, it can be passed to another function `k`, the kernel. If, for example, function @@ -576,7 +576,7 @@ optimize the body of the loop. There are several possible fixes: * Use an explicit conversion: `x = oneunit(Float64)` * Initialize with the first loop iteration, to `x = 1 / rand()`, then loop `for i = 2:10` -## [Separate kernel functions (aka, function barriers)](@id kernal-functions) +## [Separate kernel functions (aka, function barriers)](@id kernel-functions) Many functions follow a pattern of performing some set-up work, and then running many iterations to perform a core computation. Where possible, it is a good idea to put these core computations @@ -675,7 +675,7 @@ does not (and cannot) predict its value in advance. This means that code using t function has to be conservative, checking the type on each access of `A`; such code will be very slow. -Now, one very good way to solve such problems is by using the [function-barrier technique](@ref kernal-functions). +Now, one very good way to solve such problems is by using the [function-barrier technique](@ref kernel-functions). However, in some cases you might want to eliminate the type-instability altogether. In such cases, one approach is to pass the dimensionality as a parameter, for example through `Val{T}()` (see ["Value types"](@ref)): From 65abd2210c502510edea394e5432f3a40183c2e3 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Wed, 5 Sep 2018 13:12:38 +0900 Subject: [PATCH 057/153] update Julia Commit 3fbdc9bbc9 --- codex/manual/documentation.md | 13 ++--- codex/manual/faq.md | 13 +++-- codex/manual/parallel-computing.md | 2 +- codex/stdlib/Logging.md | 37 +++++++++++++ codex/stdlib/Pkg.md | 84 +++++++++++++++--------------- src/manual/documentation.md | 13 ++--- src/manual/faq.md | 13 +++-- src/manual/parallel-computing.md | 2 +- src/stdlib/Logging.md | 37 +++++++++++++ src/stdlib/Pkg.md | 84 +++++++++++++++--------------- 10 files changed, 186 insertions(+), 112 deletions(-) diff --git a/codex/manual/documentation.md b/codex/manual/documentation.md index 0eae97d..195df3e 100644 --- a/codex/manual/documentation.md +++ b/codex/manual/documentation.md @@ -621,16 +621,17 @@ the Julia documentation itself. For example: ```julia """ - accumulate!(op, y, x) + tryparse(type, str; base) -Cumulative operation `op` on a vector `x`, storing the result in `y`. See also [`accumulate`](@ref). +Like [`parse`](@ref), but returns either a value of the requested type, +or [`nothing`](@ref) if the string does not contain a valid number. """ ``` -This will create a link in the generated docs to the `accumulate` 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. +This will create a link in the generated docs to the [`parse`](@ref) documentation +(which has more information about what this function actually does), and to the +[`nothing`](@ref) documentation. 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 diff --git a/codex/manual/faq.md b/codex/manual/faq.md index 192aa28..6301192 100644 --- a/codex/manual/faq.md +++ b/codex/manual/faq.md @@ -41,6 +41,12 @@ obj3 = MyModule.someotherfunction(obj2, c) ... ``` +### How do I check if the current file is being run as the main script? + +When a file is run as the main script using `julia file.jl` one might want to activate extra +functionality like command line argument handling. A way to determine that a file is run in +this fashion is to check if `abspath(PROGRAM_FILE) == @__FILE__` is `true`. + ## Functions ### I passed an argument `x` to a function, modified it inside that function, but on the outside, the variable `x` is still unchanged. Why? @@ -645,13 +651,6 @@ as nothing but rather a tuple of zero values. The empty (or "bottom") type, written as `Union{}` (an empty union type), is a type with no values and no subtypes (except itself). You will generally not need to use this type. - -### How do I check if the current file is being run as the main script? - -When a file is run as the main script using `julia file.jl` one might want to activate extra -functionality like command line argument handling. A way to determine that a file is run in -this fashion is to check if `abspath(PROGRAM_FILE) == @__FILE__` is `true`. - ## Memory ### Why does `x += y` allocate memory when `x` and `y` are arrays? diff --git a/codex/manual/parallel-computing.md b/codex/manual/parallel-computing.md index 3dacfb5..08addb8 100644 --- a/codex/manual/parallel-computing.md +++ b/codex/manual/parallel-computing.md @@ -465,7 +465,7 @@ julia> function g_fix(r) g_fix (generic function with 1 method) julia> r = let m = MersenneTwister(1) - [m; accumulate(Future.randjump, m, fill(big(10)^20, nthreads()-1))] + [m; accumulate(Future.randjump, fill(big(10)^20, nthreads()-1), init=m)] end; julia> g_fix(r) diff --git a/codex/stdlib/Logging.md b/codex/stdlib/Logging.md index ba07f66..bed0b1b 100644 --- a/codex/stdlib/Logging.md +++ b/codex/stdlib/Logging.md @@ -193,6 +193,43 @@ Similarly, the environment variable can be used to enable debug logging of modules, such as `Pkg`, or module roots (see [`Base.moduleroot`](@ref)). To enable all debug logging, use the special value `all`. +## Writing log events to a file + +Sometimes it can be useful to write log events to a file. Here is an example +of how to use a task-local and global logger to write information to a text +file: + +```julia-repl +# Load the logging module +julia> using Logging + +# Open a textfile for writing +julia> io = open("log.txt", "w+") +IOStream() + +# Create a simple logger +julia> logger = SimpleLogger(io) +SimpleLogger(IOStream(), Info, Dict{Any,Int64}()) + +# Log a task-specific message +julia> with_logger(logger) do + @info("a context specific log message") + end + +# Write all buffered messages to the file +julia> flush(io) + +# Set the global logger to logger +julia> global_logger(logger) +SimpleLogger(IOStream(), Info, Dict{Any,Int64}()) + +# This message will now also be written to the file +julia> @info("a global log message") + +# Close the file +julia> close(io) +``` + ## Reference diff --git a/codex/stdlib/Pkg.md b/codex/stdlib/Pkg.md index 1ec7010..c76941e 100644 --- a/codex/stdlib/Pkg.md +++ b/codex/stdlib/Pkg.md @@ -146,7 +146,7 @@ format using ranges of package versions. **Depot:** a directory on a system where various package-related resources live, including: -- `environments`: shared named environments (e.g. `v0.7`, `devtools`) +- `environments`: shared named environments (e.g. `v1.0`, `devtools`) - `clones`: bare clones of package repositories - `compiled`: cached compiled package images (`.ji` files) - `config`: global configuration files (e.g. `startup.jl`) @@ -181,11 +181,11 @@ managed by system administrators. The Pkg REPL-mode is entered from the Julia REPL using the key `]`. ``` -(v0.7) pkg> +(v1.0) pkg> ``` The part inside the parenthesis of the prompt shows the name of the current project. -Since we haven't created our own project yet, we are in the default project, located at `~/.julia/environments/v0.7` +Since we haven't created our own project yet, we are in the default project, located at `~/.julia/environments/v1.0` (or whatever version of Julia you happen to run). To return to the `julia>` prompt, either press backspace when the input line is empty or press Ctrl+C. @@ -207,15 +207,15 @@ The most frequently used one is `add` and its usage is described first. In the Pkg REPL packages can be added with the `add` command followed by the name of the package, for example: ``` -(v0.7) pkg> add Example +(v1.0) pkg> add Example Cloning default registries into /Users/kristoffer/.julia/registries Cloning registry General from "https://github.com/JuliaRegistries/General.git" Updating registry at `~/.julia/registries/General` Updating git-repo `https://github.com/JuliaRegistries/General.git` Resolving package versions... - Updating `~/.julia/environments/v0.7/Project.toml` + Updating `~/.julia/environments/v1.0/Project.toml` [7876af07] + Example v0.5.1 - Updating `~/.julia/environments/v0.7/Manifest.toml` + Updating `~/.julia/environments/v1.0/Manifest.toml` [7876af07] + Example v0.5.1 [8dfed614] + Test ``` @@ -228,7 +228,7 @@ Since standard libraries (e.g. `Test`) are shipped with Julia, they do not have you have added yourself, in this case, `Example`: ``` -(v0.7) pkg> st +(v1.0) pkg> st Status `Project.toml` [7876af07] Example v0.5.1 ``` @@ -236,7 +236,7 @@ you have added yourself, in this case, `Example`: The manifest status, in addition, includes the dependencies of explicitly added packages. ``` -(v0.7) pkg> st --manifest +(v1.0) pkg> st --manifest Status `Manifest.toml` [7876af07] Example v0.5.1 [8dfed614] Test @@ -256,11 +256,11 @@ julia> Example.hello("User") A specific version can be installed by appending a version after a `@` symbol, e.g. `@v0.4`, to the package name: ``` -(v0.7) pkg> add Example@0.4 +(v1.0) pkg> add Example@0.4 Resolving package versions... - Updating `~/.julia/environments/v0.7/Project.toml` + Updating `~/.julia/environments/v1.0/Project.toml` [7876af07] + Example v0.4.1 - Updating `~/.julia/environments/v0.7/Manifest.toml` + Updating `~/.julia/environments/v1.0/Manifest.toml` [7876af07] + Example v0.4.1 ``` @@ -268,12 +268,12 @@ If the master branch (or a certain commit SHA) of `Example` has a hotfix that ha we can explicitly track a branch (or commit) by appending `#branch` (or `#commit`) to the package name: ``` -(v0.7) pkg> add Example#master +(v1.0) pkg> add Example#master Updating git-repo `https://github.com/JuliaLang/Example.jl.git` Resolving package versions... - Updating `~/.julia/environments/v0.7/Project.toml` + Updating `~/.julia/environments/v1.0/Project.toml` [7876af07] ~ Example v0.5.1 ⇒ v0.5.1+ #master (https://github.com/JuliaLang/Example.jl.git) - Updating `~/.julia/environments/v0.7/Manifest.toml` + Updating `~/.julia/environments/v1.0/Manifest.toml` [7876af07] ~ Example v0.5.1 ⇒ v0.5.1+ #master (https://github.com/JuliaLang/Example.jl.git) ``` @@ -283,11 +283,11 @@ When updating packages, we will pull updates from that branch. To go back to tracking the registry version of `Example`, the command `free` is used: ``` -(v0.7) pkg> free Example +(v1.0) pkg> free Example Resolving package versions... - Updating `~/.julia/environments/v0.7/Project.toml` + Updating `~/.julia/environments/v1.0/Project.toml` [7876af07] ~ Example v0.5.1+ #master (https://github.com/JuliaLang/Example.jl.git) ⇒ v0.5.1 - Updating `~/.julia/environments/v0.7/Manifest.toml` + Updating `~/.julia/environments/v1.0/Manifest.toml` [7876af07] ~ Example v0.5.1+ #master )https://github.com/JuliaLang/Example.jl.git) ⇒ v0.5.1 ``` @@ -297,13 +297,13 @@ To go back to tracking the registry version of `Example`, the command `free` is If a package is not in a registry, it can still be added by instead of the package name giving the URL to the repository to `add`. ``` -(v0.7) pkg> add https://github.com/fredrikekre/ImportMacros.jl +(v1.0) pkg> add https://github.com/fredrikekre/ImportMacros.jl Updating git-repo `https://github.com/fredrikekre/ImportMacros.jl` Resolving package versions... Downloaded MacroTools ─ v0.4.1 - Updating `~/.julia/environments/v0.7/Project.toml` + Updating `~/.julia/environments/v1.0/Project.toml` [e6797606] + ImportMacros v0.0.0 # (https://github.com/fredrikekre/ImportMacros.jl) - Updating `~/.julia/environments/v0.7/Manifest.toml` + Updating `~/.julia/environments/v1.0/Manifest.toml` [e6797606] + ImportMacros v0.0.0 # (https://github.com/fredrikekre/ImportMacros.jl) [1914dd2f] + MacroTools v0.4.1 ``` @@ -330,12 +330,12 @@ However, when you are developing a package, it is more convenient to load packag Let's try to `dev` a registered package: ``` -(v0.7) pkg> dev Example +(v1.0) pkg> dev Example Updating git-repo `https://github.com/JuliaLang/Example.jl.git` Resolving package versions... - Updating `~/.julia/environments/v0.7/Project.toml` + Updating `~/.julia/environments/v1.0/Project.toml` [7876af07] + Example v0.5.1+ [`~/.julia/dev/Example`] - Updating `~/.julia/environments/v0.7/Manifest.toml` + Updating `~/.julia/environments/v1.0/Manifest.toml` [7876af07] + Example v0.5.1+ [`~/.julia/dev/Example`] ``` @@ -347,7 +347,7 @@ If we try to `dev` a package at some branch that already exists at `~/.julia/dev For example: ``` -(v0.7) pkg> dev Example +(v1.0) pkg> dev Example Updating git-repo `https://github.com/JuliaLang/Example.jl.git` [ Info: Path `/Users/kristoffer/.julia/dev/Example` exists and looks like the correct package, using existing path instead of cloning ``` @@ -361,11 +361,11 @@ The path will be recorded relative to the project file, unless it is given as an To stop tracking a path and use the registered version again, use `free` ``` -(v0.7) pkg> free Example +(v1.0) pkg> free Example Resolving package versions... - Updating `~/.julia/environments/v0.7/Project.toml` + Updating `~/.julia/environments/v1.0/Project.toml` [7876af07] ↓ Example v0.5.1+ [`~/.julia/dev/Example`] ⇒ v0.5.1 - Updating `~/.julia/environments/v0.7/Manifest.toml` + Updating `~/.julia/environments/v1.0/Manifest.toml` [7876af07] ↓ Example v0.5.1+ [`~/.julia/dev/Example`] ⇒ v0.5.1 ``` @@ -390,13 +390,13 @@ When new versions of packages the project is using are released, it is a good id to the latest compatible version. Sometimes this is not what you want. You can specify a subset of the dependencies to upgrade by giving them as arguments to `up`, e.g: ``` -(v0.7) pkg> up Example +(v1.0) pkg> up Example ``` The version of all other packages direct dependencies will stay the same. If you only want to update the minor version of packages, to reduce the risk that your project breaks, you can give the `--minor` flag, e.g: ``` -(v0.7) pkg> up --minor Example +(v1.0) pkg> up --minor Example ``` Packages that track a repository are not updated when a minor upgrade is done. @@ -407,21 +407,21 @@ Packages that track a path are never touched by the package manager. A pinned package will never be updated. A package can be pinned using `pin` as for example ``` -(v0.7) pkg> pin Example +(v1.0) pkg> pin Example Resolving package versions... - Updating `~/.julia/environments/v0.7/Project.toml` + Updating `~/.julia/environments/v1.0/Project.toml` [7876af07] ~ Example v0.5.1 ⇒ v0.5.1 ⚲ - Updating `~/.julia/environments/v0.7/Manifest.toml` + Updating `~/.julia/environments/v1.0/Manifest.toml` [7876af07] ~ Example v0.5.1 ⇒ v0.5.1 ⚲ ``` Note the pin symbol `⚲` showing that the package is pinned. Removing the pin is done using `free` ``` -(v0.7) pkg> free Example - Updating `~/.julia/environments/v0.7/Project.toml` +(v1.0) pkg> free Example + Updating `~/.julia/environments/v1.0/Project.toml` [7876af07] ~ Example v0.5.1 ⚲ ⇒ v0.5.1 - Updating `~/.julia/environments/v0.7/Manifest.toml` + Updating `~/.julia/environments/v1.0/Manifest.toml` [7876af07] ~ Example v0.5.1 ⚲ ⇒ v0.5.1 ``` @@ -430,7 +430,7 @@ Note the pin symbol `⚲` showing that the package is pinned. Removing the pin i The tests for a package can be run using `test`command: ``` -(v0.7) pkg> test Example +(v1.0) pkg> test Example Testing Example Testing Example tests passed ``` @@ -442,7 +442,7 @@ The output of the build process is directed to a file. To explicitly run the build step for a package the `build` command is used: ``` -(v0.7) pkg> build MbedTLS +(v1.0) pkg> build MbedTLS Building MbedTLS → `~/.julia/packages/MbedTLS/h1Vu/deps/build.log` shell> cat ~/.julia/packages/MbedTLS/h1Vu/deps/build.log @@ -455,7 +455,7 @@ shell> cat ~/.julia/packages/MbedTLS/h1Vu/deps/build.log ## Creating your own projects -So far we have added packages to the default project at `~/.julia/environments/v0.7`, it is, however, easy to create other, independent, projects. +So far we have added packages to the default project at `~/.julia/environments/v1.0`, it is, however, easy to create other, independent, projects. It should be pointed out if two projects uses the same package at the same version, the content of this package is not duplicated. In order to create a new project, create a directory for it and then activate that directory to make it the "active project" which package operations manipulate: @@ -465,7 +465,7 @@ shell> mkdir MyProject shell> cd MyProject /Users/kristoffer/MyProject -(v0.7) pkg> activate . +(v1.0) pkg> activate . (MyProject) pkg> st Status `Project.toml` @@ -518,7 +518,7 @@ and what packages those projects used. The rest can be deleted. This is done with the `gc` command: ``` -(v0.7) pkg> gc +(v1.0) pkg> gc Active manifests at: `/Users/kristoffer/BinaryProvider/Manifest.toml` ... @@ -542,7 +542,7 @@ This file is executed when the package is loaded. To generate files for a new package, use `pkg> generate`. ``` -(v0.7) pkg> generate HelloWorld +(v1.0) pkg> generate HelloWorld ``` This creates a new project `HelloWorld` with the following files (visualized with the external [`tree` command](https://linux.die.net/man/1/tree)): @@ -828,7 +828,7 @@ However, nothing would be installed and your `Project.toml` and `Manifest.toml` Simply clone their project using e.g. `git clone`, `cd` to the project directory and call ``` -(v0.7) pkg> activate . +(v1.0) pkg> activate . (SomeProject) pkg> instantiate ``` diff --git a/src/manual/documentation.md b/src/manual/documentation.md index 0eae97d..195df3e 100644 --- a/src/manual/documentation.md +++ b/src/manual/documentation.md @@ -621,16 +621,17 @@ the Julia documentation itself. For example: ```julia """ - accumulate!(op, y, x) + tryparse(type, str; base) -Cumulative operation `op` on a vector `x`, storing the result in `y`. See also [`accumulate`](@ref). +Like [`parse`](@ref), but returns either a value of the requested type, +or [`nothing`](@ref) if the string does not contain a valid number. """ ``` -This will create a link in the generated docs to the `accumulate` 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. +This will create a link in the generated docs to the [`parse`](@ref) documentation +(which has more information about what this function actually does), and to the +[`nothing`](@ref) documentation. 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 diff --git a/src/manual/faq.md b/src/manual/faq.md index 192aa28..6301192 100644 --- a/src/manual/faq.md +++ b/src/manual/faq.md @@ -41,6 +41,12 @@ obj3 = MyModule.someotherfunction(obj2, c) ... ``` +### How do I check if the current file is being run as the main script? + +When a file is run as the main script using `julia file.jl` one might want to activate extra +functionality like command line argument handling. A way to determine that a file is run in +this fashion is to check if `abspath(PROGRAM_FILE) == @__FILE__` is `true`. + ## Functions ### I passed an argument `x` to a function, modified it inside that function, but on the outside, the variable `x` is still unchanged. Why? @@ -645,13 +651,6 @@ as nothing but rather a tuple of zero values. The empty (or "bottom") type, written as `Union{}` (an empty union type), is a type with no values and no subtypes (except itself). You will generally not need to use this type. - -### How do I check if the current file is being run as the main script? - -When a file is run as the main script using `julia file.jl` one might want to activate extra -functionality like command line argument handling. A way to determine that a file is run in -this fashion is to check if `abspath(PROGRAM_FILE) == @__FILE__` is `true`. - ## Memory ### Why does `x += y` allocate memory when `x` and `y` are arrays? diff --git a/src/manual/parallel-computing.md b/src/manual/parallel-computing.md index 3dacfb5..08addb8 100644 --- a/src/manual/parallel-computing.md +++ b/src/manual/parallel-computing.md @@ -465,7 +465,7 @@ julia> function g_fix(r) g_fix (generic function with 1 method) julia> r = let m = MersenneTwister(1) - [m; accumulate(Future.randjump, m, fill(big(10)^20, nthreads()-1))] + [m; accumulate(Future.randjump, fill(big(10)^20, nthreads()-1), init=m)] end; julia> g_fix(r) diff --git a/src/stdlib/Logging.md b/src/stdlib/Logging.md index ba07f66..bed0b1b 100644 --- a/src/stdlib/Logging.md +++ b/src/stdlib/Logging.md @@ -193,6 +193,43 @@ Similarly, the environment variable can be used to enable debug logging of modules, such as `Pkg`, or module roots (see [`Base.moduleroot`](@ref)). To enable all debug logging, use the special value `all`. +## Writing log events to a file + +Sometimes it can be useful to write log events to a file. Here is an example +of how to use a task-local and global logger to write information to a text +file: + +```julia-repl +# Load the logging module +julia> using Logging + +# Open a textfile for writing +julia> io = open("log.txt", "w+") +IOStream() + +# Create a simple logger +julia> logger = SimpleLogger(io) +SimpleLogger(IOStream(), Info, Dict{Any,Int64}()) + +# Log a task-specific message +julia> with_logger(logger) do + @info("a context specific log message") + end + +# Write all buffered messages to the file +julia> flush(io) + +# Set the global logger to logger +julia> global_logger(logger) +SimpleLogger(IOStream(), Info, Dict{Any,Int64}()) + +# This message will now also be written to the file +julia> @info("a global log message") + +# Close the file +julia> close(io) +``` + ## Reference diff --git a/src/stdlib/Pkg.md b/src/stdlib/Pkg.md index 1ec7010..c76941e 100644 --- a/src/stdlib/Pkg.md +++ b/src/stdlib/Pkg.md @@ -146,7 +146,7 @@ format using ranges of package versions. **Depot:** a directory on a system where various package-related resources live, including: -- `environments`: shared named environments (e.g. `v0.7`, `devtools`) +- `environments`: shared named environments (e.g. `v1.0`, `devtools`) - `clones`: bare clones of package repositories - `compiled`: cached compiled package images (`.ji` files) - `config`: global configuration files (e.g. `startup.jl`) @@ -181,11 +181,11 @@ managed by system administrators. The Pkg REPL-mode is entered from the Julia REPL using the key `]`. ``` -(v0.7) pkg> +(v1.0) pkg> ``` The part inside the parenthesis of the prompt shows the name of the current project. -Since we haven't created our own project yet, we are in the default project, located at `~/.julia/environments/v0.7` +Since we haven't created our own project yet, we are in the default project, located at `~/.julia/environments/v1.0` (or whatever version of Julia you happen to run). To return to the `julia>` prompt, either press backspace when the input line is empty or press Ctrl+C. @@ -207,15 +207,15 @@ The most frequently used one is `add` and its usage is described first. In the Pkg REPL packages can be added with the `add` command followed by the name of the package, for example: ``` -(v0.7) pkg> add Example +(v1.0) pkg> add Example Cloning default registries into /Users/kristoffer/.julia/registries Cloning registry General from "https://github.com/JuliaRegistries/General.git" Updating registry at `~/.julia/registries/General` Updating git-repo `https://github.com/JuliaRegistries/General.git` Resolving package versions... - Updating `~/.julia/environments/v0.7/Project.toml` + Updating `~/.julia/environments/v1.0/Project.toml` [7876af07] + Example v0.5.1 - Updating `~/.julia/environments/v0.7/Manifest.toml` + Updating `~/.julia/environments/v1.0/Manifest.toml` [7876af07] + Example v0.5.1 [8dfed614] + Test ``` @@ -228,7 +228,7 @@ Since standard libraries (e.g. `Test`) are shipped with Julia, they do not have you have added yourself, in this case, `Example`: ``` -(v0.7) pkg> st +(v1.0) pkg> st Status `Project.toml` [7876af07] Example v0.5.1 ``` @@ -236,7 +236,7 @@ you have added yourself, in this case, `Example`: The manifest status, in addition, includes the dependencies of explicitly added packages. ``` -(v0.7) pkg> st --manifest +(v1.0) pkg> st --manifest Status `Manifest.toml` [7876af07] Example v0.5.1 [8dfed614] Test @@ -256,11 +256,11 @@ julia> Example.hello("User") A specific version can be installed by appending a version after a `@` symbol, e.g. `@v0.4`, to the package name: ``` -(v0.7) pkg> add Example@0.4 +(v1.0) pkg> add Example@0.4 Resolving package versions... - Updating `~/.julia/environments/v0.7/Project.toml` + Updating `~/.julia/environments/v1.0/Project.toml` [7876af07] + Example v0.4.1 - Updating `~/.julia/environments/v0.7/Manifest.toml` + Updating `~/.julia/environments/v1.0/Manifest.toml` [7876af07] + Example v0.4.1 ``` @@ -268,12 +268,12 @@ If the master branch (or a certain commit SHA) of `Example` has a hotfix that ha we can explicitly track a branch (or commit) by appending `#branch` (or `#commit`) to the package name: ``` -(v0.7) pkg> add Example#master +(v1.0) pkg> add Example#master Updating git-repo `https://github.com/JuliaLang/Example.jl.git` Resolving package versions... - Updating `~/.julia/environments/v0.7/Project.toml` + Updating `~/.julia/environments/v1.0/Project.toml` [7876af07] ~ Example v0.5.1 ⇒ v0.5.1+ #master (https://github.com/JuliaLang/Example.jl.git) - Updating `~/.julia/environments/v0.7/Manifest.toml` + Updating `~/.julia/environments/v1.0/Manifest.toml` [7876af07] ~ Example v0.5.1 ⇒ v0.5.1+ #master (https://github.com/JuliaLang/Example.jl.git) ``` @@ -283,11 +283,11 @@ When updating packages, we will pull updates from that branch. To go back to tracking the registry version of `Example`, the command `free` is used: ``` -(v0.7) pkg> free Example +(v1.0) pkg> free Example Resolving package versions... - Updating `~/.julia/environments/v0.7/Project.toml` + Updating `~/.julia/environments/v1.0/Project.toml` [7876af07] ~ Example v0.5.1+ #master (https://github.com/JuliaLang/Example.jl.git) ⇒ v0.5.1 - Updating `~/.julia/environments/v0.7/Manifest.toml` + Updating `~/.julia/environments/v1.0/Manifest.toml` [7876af07] ~ Example v0.5.1+ #master )https://github.com/JuliaLang/Example.jl.git) ⇒ v0.5.1 ``` @@ -297,13 +297,13 @@ To go back to tracking the registry version of `Example`, the command `free` is If a package is not in a registry, it can still be added by instead of the package name giving the URL to the repository to `add`. ``` -(v0.7) pkg> add https://github.com/fredrikekre/ImportMacros.jl +(v1.0) pkg> add https://github.com/fredrikekre/ImportMacros.jl Updating git-repo `https://github.com/fredrikekre/ImportMacros.jl` Resolving package versions... Downloaded MacroTools ─ v0.4.1 - Updating `~/.julia/environments/v0.7/Project.toml` + Updating `~/.julia/environments/v1.0/Project.toml` [e6797606] + ImportMacros v0.0.0 # (https://github.com/fredrikekre/ImportMacros.jl) - Updating `~/.julia/environments/v0.7/Manifest.toml` + Updating `~/.julia/environments/v1.0/Manifest.toml` [e6797606] + ImportMacros v0.0.0 # (https://github.com/fredrikekre/ImportMacros.jl) [1914dd2f] + MacroTools v0.4.1 ``` @@ -330,12 +330,12 @@ However, when you are developing a package, it is more convenient to load packag Let's try to `dev` a registered package: ``` -(v0.7) pkg> dev Example +(v1.0) pkg> dev Example Updating git-repo `https://github.com/JuliaLang/Example.jl.git` Resolving package versions... - Updating `~/.julia/environments/v0.7/Project.toml` + Updating `~/.julia/environments/v1.0/Project.toml` [7876af07] + Example v0.5.1+ [`~/.julia/dev/Example`] - Updating `~/.julia/environments/v0.7/Manifest.toml` + Updating `~/.julia/environments/v1.0/Manifest.toml` [7876af07] + Example v0.5.1+ [`~/.julia/dev/Example`] ``` @@ -347,7 +347,7 @@ If we try to `dev` a package at some branch that already exists at `~/.julia/dev For example: ``` -(v0.7) pkg> dev Example +(v1.0) pkg> dev Example Updating git-repo `https://github.com/JuliaLang/Example.jl.git` [ Info: Path `/Users/kristoffer/.julia/dev/Example` exists and looks like the correct package, using existing path instead of cloning ``` @@ -361,11 +361,11 @@ The path will be recorded relative to the project file, unless it is given as an To stop tracking a path and use the registered version again, use `free` ``` -(v0.7) pkg> free Example +(v1.0) pkg> free Example Resolving package versions... - Updating `~/.julia/environments/v0.7/Project.toml` + Updating `~/.julia/environments/v1.0/Project.toml` [7876af07] ↓ Example v0.5.1+ [`~/.julia/dev/Example`] ⇒ v0.5.1 - Updating `~/.julia/environments/v0.7/Manifest.toml` + Updating `~/.julia/environments/v1.0/Manifest.toml` [7876af07] ↓ Example v0.5.1+ [`~/.julia/dev/Example`] ⇒ v0.5.1 ``` @@ -390,13 +390,13 @@ When new versions of packages the project is using are released, it is a good id to the latest compatible version. Sometimes this is not what you want. You can specify a subset of the dependencies to upgrade by giving them as arguments to `up`, e.g: ``` -(v0.7) pkg> up Example +(v1.0) pkg> up Example ``` The version of all other packages direct dependencies will stay the same. If you only want to update the minor version of packages, to reduce the risk that your project breaks, you can give the `--minor` flag, e.g: ``` -(v0.7) pkg> up --minor Example +(v1.0) pkg> up --minor Example ``` Packages that track a repository are not updated when a minor upgrade is done. @@ -407,21 +407,21 @@ Packages that track a path are never touched by the package manager. A pinned package will never be updated. A package can be pinned using `pin` as for example ``` -(v0.7) pkg> pin Example +(v1.0) pkg> pin Example Resolving package versions... - Updating `~/.julia/environments/v0.7/Project.toml` + Updating `~/.julia/environments/v1.0/Project.toml` [7876af07] ~ Example v0.5.1 ⇒ v0.5.1 ⚲ - Updating `~/.julia/environments/v0.7/Manifest.toml` + Updating `~/.julia/environments/v1.0/Manifest.toml` [7876af07] ~ Example v0.5.1 ⇒ v0.5.1 ⚲ ``` Note the pin symbol `⚲` showing that the package is pinned. Removing the pin is done using `free` ``` -(v0.7) pkg> free Example - Updating `~/.julia/environments/v0.7/Project.toml` +(v1.0) pkg> free Example + Updating `~/.julia/environments/v1.0/Project.toml` [7876af07] ~ Example v0.5.1 ⚲ ⇒ v0.5.1 - Updating `~/.julia/environments/v0.7/Manifest.toml` + Updating `~/.julia/environments/v1.0/Manifest.toml` [7876af07] ~ Example v0.5.1 ⚲ ⇒ v0.5.1 ``` @@ -430,7 +430,7 @@ Note the pin symbol `⚲` showing that the package is pinned. Removing the pin i The tests for a package can be run using `test`command: ``` -(v0.7) pkg> test Example +(v1.0) pkg> test Example Testing Example Testing Example tests passed ``` @@ -442,7 +442,7 @@ The output of the build process is directed to a file. To explicitly run the build step for a package the `build` command is used: ``` -(v0.7) pkg> build MbedTLS +(v1.0) pkg> build MbedTLS Building MbedTLS → `~/.julia/packages/MbedTLS/h1Vu/deps/build.log` shell> cat ~/.julia/packages/MbedTLS/h1Vu/deps/build.log @@ -455,7 +455,7 @@ shell> cat ~/.julia/packages/MbedTLS/h1Vu/deps/build.log ## Creating your own projects -So far we have added packages to the default project at `~/.julia/environments/v0.7`, it is, however, easy to create other, independent, projects. +So far we have added packages to the default project at `~/.julia/environments/v1.0`, it is, however, easy to create other, independent, projects. It should be pointed out if two projects uses the same package at the same version, the content of this package is not duplicated. In order to create a new project, create a directory for it and then activate that directory to make it the "active project" which package operations manipulate: @@ -465,7 +465,7 @@ shell> mkdir MyProject shell> cd MyProject /Users/kristoffer/MyProject -(v0.7) pkg> activate . +(v1.0) pkg> activate . (MyProject) pkg> st Status `Project.toml` @@ -518,7 +518,7 @@ and what packages those projects used. The rest can be deleted. This is done with the `gc` command: ``` -(v0.7) pkg> gc +(v1.0) pkg> gc Active manifests at: `/Users/kristoffer/BinaryProvider/Manifest.toml` ... @@ -542,7 +542,7 @@ This file is executed when the package is loaded. To generate files for a new package, use `pkg> generate`. ``` -(v0.7) pkg> generate HelloWorld +(v1.0) pkg> generate HelloWorld ``` This creates a new project `HelloWorld` with the following files (visualized with the external [`tree` command](https://linux.die.net/man/1/tree)): @@ -828,7 +828,7 @@ However, nothing would be installed and your `Project.toml` and `Manifest.toml` Simply clone their project using e.g. `git clone`, `cd` to the project directory and call ``` -(v0.7) pkg> activate . +(v1.0) pkg> activate . (SomeProject) pkg> instantiate ``` From 246972cb6c2e4de26beb1ddde0f1302b3f6ccc4a Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Mon, 10 Sep 2018 13:43:41 +0900 Subject: [PATCH 058/153] update Julia Commit 97864d39ea --- codex/manual/embedding.md | 48 +++++++++++++++++++ .../integers-and-floating-point-numbers.md | 2 +- codex/manual/interfaces.md | 4 +- codex/manual/performance-tips.md | 2 +- codex/manual/variables-and-scoping.md | 9 ++-- src/manual/embedding.md | 48 +++++++++++++++++++ .../integers-and-floating-point-numbers.md | 2 +- src/manual/interfaces.md | 4 +- src/manual/performance-tips.md | 2 +- src/manual/variables-and-scoping.md | 9 ++-- 10 files changed, 116 insertions(+), 14 deletions(-) diff --git a/codex/manual/embedding.md b/codex/manual/embedding.md index 496d0f1..90850b7 100644 --- a/codex/manual/embedding.md +++ b/codex/manual/embedding.md @@ -9,6 +9,9 @@ further language bridges (e.g. calling Julia from Python or C#). ## High-Level Embedding +__Note__: This section covers embedding Julia code in C on Unix-like operating systems. For doing +this on Windows, please see the section following this. + We start with a simple C program that initializes Julia and calls some Julia code: ```c @@ -136,6 +139,51 @@ all: embed_example Now the build command is simply `make`. +## High-Level Embedding on Windows with Visual Studio + +If the `JULIA_DIR` environment variable hasn't been setup, add it using the System panel before +starting Visual Studio. The `bin` folder under JULIA_DIR should be on the system PATH. + +We start by opening Visual Studio and creating a new Console Application project. To the 'stdafx.h' +header file, add the following lines at the end: + +```c +#define JULIA_ENABLE_THREADING +#include +``` + +Then, replace the main() function in the project with this code: + +```c +int main(int argc, char *argv[]) +{ + /* required: setup the Julia context */ + jl_init(); + + /* run Julia commands */ + jl_eval_string("print(sqrt(2.0))"); + + /* strongly recommended: notify Julia that the + program is about to terminate. this allows + Julia time to cleanup pending write requests + and run all finalizers + */ + jl_atexit_hook(0); + return 0; +} +``` + +The next step is to set up the project to find the Julia include files and the libraries. It's important to +know whether the Julia installation is 32- or 64-bits. Remove any platform configuration that doesn't correspond +to the Julia installation before proceeding. + +Using the project Properties dialog, go to `C/C++` | `General` and add `$(JULIA_DIR)\include\julia\` to the +Additional Include Directories property. Then, go to the `Linker` | `General` section and add `$(JULIA_DIR)\lib` +to the Additional Library Directories property. Finally, under `Linker` | `Input`, add `libjulia.dll.a;libopenlibm.dll.a;` +to the list of libraries. + +At this point, the project should build and run. + ## Converting Types Real applications will not just need to execute expressions, but also return their values to the diff --git a/codex/manual/integers-and-floating-point-numbers.md b/codex/manual/integers-and-floating-point-numbers.md index 8478d49..b4d82c3 100644 --- a/codex/manual/integers-and-floating-point-numbers.md +++ b/codex/manual/integers-and-floating-point-numbers.md @@ -178,7 +178,7 @@ of the binary data item is the minimal needed size, if the leading digit of the `0`. In the case of leading zeros, the size is determined by the minimal needed size for a literal, which has the same length but leading digit `1`. That allows the user to control the size. -Values, which cannot be stored in `UInt128` cannot be written as such literals. +Values which cannot be stored in `UInt128` cannot be written as such literals. Binary, octal, and hexadecimal literals may be signed by a `-` immediately preceding the unsigned literal. They produce an unsigned integer of the same size as the unsigned literal diff --git a/codex/manual/interfaces.md b/codex/manual/interfaces.md index d21c493..5b52902 100644 --- a/codex/manual/interfaces.md +++ b/codex/manual/interfaces.md @@ -16,12 +16,12 @@ to generically build upon those behaviors. | `IteratorEltype(IterType)` | `HasEltype()` | Either `EltypeUnknown()` or `HasEltype()` as appropriate | | `eltype(IterType)` | `Any` | The type of the first entry of the tuple returned by `iterate()` | | `length(iter)` | (*undefined*) | The number of items, if known | -| `size(iter, [dim...])` | (*undefined*) | The number of items in each dimension, 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)`](@ref) | -| `HasShape{N}()` | `length(iter)` and `size(iter, [dim...])` | +| `HasShape{N}()` | `length(iter)` and `size(iter, [dim])` | | `IsInfinite()` | (*none*) | | `SizeUnknown()` | (*none*) | diff --git a/codex/manual/performance-tips.md b/codex/manual/performance-tips.md index b830f34..ce86bc9 100644 --- a/codex/manual/performance-tips.md +++ b/codex/manual/performance-tips.md @@ -1231,7 +1231,7 @@ function mynorm(u::Vector) @fastmath @inbounds @simd for i in 1:n s += u[i]^2 end - @fastmath @inbounds return sqrt(s/n) + @fastmath @inbounds return sqrt(s) end function main() diff --git a/codex/manual/variables-and-scoping.md b/codex/manual/variables-and-scoping.md index ab6f196..82d84f2 100644 --- a/codex/manual/variables-and-scoping.md +++ b/codex/manual/variables-and-scoping.md @@ -449,7 +449,7 @@ julia> f() 0 ``` -However, it is occasionally useful to reuse an existing variable as the iteration variable. +However, it is occasionally useful to reuse an existing local variable as the iteration variable. This can be done conveniently by adding the keyword `outer`: ```jldoctest @@ -555,8 +555,11 @@ WARNING: redefining constant a 1 ``` -Note that although possible, changing the value of a variable that is declared as constant -is strongly discouraged. For instance, if a method references a constant and is already +Note that although sometimes possible, changing the value of a `const` variable +is strongly discouraged, and is intended only for convenience during +interactive use. +Changing constants can cause various problems or unexpected behaviors. +For instance, if a method references a constant and is already compiled before the constant is changed then it might keep using the old value: ```jldoctest julia> const x = 1 diff --git a/src/manual/embedding.md b/src/manual/embedding.md index 496d0f1..90850b7 100644 --- a/src/manual/embedding.md +++ b/src/manual/embedding.md @@ -9,6 +9,9 @@ further language bridges (e.g. calling Julia from Python or C#). ## High-Level Embedding +__Note__: This section covers embedding Julia code in C on Unix-like operating systems. For doing +this on Windows, please see the section following this. + We start with a simple C program that initializes Julia and calls some Julia code: ```c @@ -136,6 +139,51 @@ all: embed_example Now the build command is simply `make`. +## High-Level Embedding on Windows with Visual Studio + +If the `JULIA_DIR` environment variable hasn't been setup, add it using the System panel before +starting Visual Studio. The `bin` folder under JULIA_DIR should be on the system PATH. + +We start by opening Visual Studio and creating a new Console Application project. To the 'stdafx.h' +header file, add the following lines at the end: + +```c +#define JULIA_ENABLE_THREADING +#include +``` + +Then, replace the main() function in the project with this code: + +```c +int main(int argc, char *argv[]) +{ + /* required: setup the Julia context */ + jl_init(); + + /* run Julia commands */ + jl_eval_string("print(sqrt(2.0))"); + + /* strongly recommended: notify Julia that the + program is about to terminate. this allows + Julia time to cleanup pending write requests + and run all finalizers + */ + jl_atexit_hook(0); + return 0; +} +``` + +The next step is to set up the project to find the Julia include files and the libraries. It's important to +know whether the Julia installation is 32- or 64-bits. Remove any platform configuration that doesn't correspond +to the Julia installation before proceeding. + +Using the project Properties dialog, go to `C/C++` | `General` and add `$(JULIA_DIR)\include\julia\` to the +Additional Include Directories property. Then, go to the `Linker` | `General` section and add `$(JULIA_DIR)\lib` +to the Additional Library Directories property. Finally, under `Linker` | `Input`, add `libjulia.dll.a;libopenlibm.dll.a;` +to the list of libraries. + +At this point, the project should build and run. + ## Converting Types Real applications will not just need to execute expressions, but also return their values to the diff --git a/src/manual/integers-and-floating-point-numbers.md b/src/manual/integers-and-floating-point-numbers.md index 35c831c..ce15204 100644 --- a/src/manual/integers-and-floating-point-numbers.md +++ b/src/manual/integers-and-floating-point-numbers.md @@ -167,7 +167,7 @@ of the binary data item is the minimal needed size, if the leading digit of the `0`. In the case of leading zeros, the size is determined by the minimal needed size for a literal, which has the same length but leading digit `1`. That allows the user to control the size. -Values, which cannot be stored in `UInt128` cannot be written as such literals. +Values which cannot be stored in `UInt128` cannot be written as such literals. Binary, octal, and hexadecimal literals may be signed by a `-` immediately preceding the unsigned literal. They produce an unsigned integer of the same size as the unsigned literal diff --git a/src/manual/interfaces.md b/src/manual/interfaces.md index d21c493..5b52902 100644 --- a/src/manual/interfaces.md +++ b/src/manual/interfaces.md @@ -16,12 +16,12 @@ to generically build upon those behaviors. | `IteratorEltype(IterType)` | `HasEltype()` | Either `EltypeUnknown()` or `HasEltype()` as appropriate | | `eltype(IterType)` | `Any` | The type of the first entry of the tuple returned by `iterate()` | | `length(iter)` | (*undefined*) | The number of items, if known | -| `size(iter, [dim...])` | (*undefined*) | The number of items in each dimension, 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)`](@ref) | -| `HasShape{N}()` | `length(iter)` and `size(iter, [dim...])` | +| `HasShape{N}()` | `length(iter)` and `size(iter, [dim])` | | `IsInfinite()` | (*none*) | | `SizeUnknown()` | (*none*) | diff --git a/src/manual/performance-tips.md b/src/manual/performance-tips.md index b830f34..ce86bc9 100644 --- a/src/manual/performance-tips.md +++ b/src/manual/performance-tips.md @@ -1231,7 +1231,7 @@ function mynorm(u::Vector) @fastmath @inbounds @simd for i in 1:n s += u[i]^2 end - @fastmath @inbounds return sqrt(s/n) + @fastmath @inbounds return sqrt(s) end function main() diff --git a/src/manual/variables-and-scoping.md b/src/manual/variables-and-scoping.md index ab6f196..82d84f2 100644 --- a/src/manual/variables-and-scoping.md +++ b/src/manual/variables-and-scoping.md @@ -449,7 +449,7 @@ julia> f() 0 ``` -However, it is occasionally useful to reuse an existing variable as the iteration variable. +However, it is occasionally useful to reuse an existing local variable as the iteration variable. This can be done conveniently by adding the keyword `outer`: ```jldoctest @@ -555,8 +555,11 @@ WARNING: redefining constant a 1 ``` -Note that although possible, changing the value of a variable that is declared as constant -is strongly discouraged. For instance, if a method references a constant and is already +Note that although sometimes possible, changing the value of a `const` variable +is strongly discouraged, and is intended only for convenience during +interactive use. +Changing constants can cause various problems or unexpected behaviors. +For instance, if a method references a constant and is already compiled before the constant is changed then it might keep using the old value: ```jldoctest julia> const x = 1 From 0f23f0d9717e2c141bebcf22ffe0705d8642bc1b Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Thu, 13 Sep 2018 11:47:03 +0900 Subject: [PATCH 059/153] update Julia Commit b4c370dd05 --- README.md | 6 +++++- codex/manual/interfaces.md | 6 +++--- codex/manual/parallel-computing.md | 22 +++++++++++----------- src/manual/interfaces.md | 6 +++--- src/manual/parallel-computing.md | 22 +++++++++++----------- 5 files changed, 33 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index ff71232..914e50b 100644 --- a/README.md +++ b/README.md @@ -3,4 +3,8 @@ ### 최근 번역 빌드한 것 보기 (HTML) - - https://juliakorea.github.io/ko/ + - https://juliakorea.github.io/ko/latest/ + + +### Julia Documentation 구글 번역 보기 + - [중국어 -> 한국어](https://translate.google.com/translate?sl=zh-CN&tl=ko&js=y&hl=en&ie=UTF-8&u=http%3A%2F%2Fdocs.juliacn.com%2Flatest%2F) diff --git a/codex/manual/interfaces.md b/codex/manual/interfaces.md index 5b52902..db69514 100644 --- a/codex/manual/interfaces.md +++ b/codex/manual/interfaces.md @@ -231,11 +231,11 @@ ourselves, we can officially define it as a subtype of an [`AbstractArray`](@ref | `length(A)` | `prod(size(A))` | Number of elements | | `similar(A)` | `similar(A, eltype(A), size(A))` | Return a mutable array with the same shape and element type | | `similar(A, ::Type{S})` | `similar(A, S, size(A))` | Return a mutable array with the same shape and the specified element type | -| `similar(A, dims::NTuple{Int})` | `similar(A, eltype(A), dims)` | Return a mutable array with the same element type and size *dims* | -| `similar(A, ::Type{S}, dims::NTuple{Int})` | `Array{S}(undef, dims)` | Return a mutable array with the specified element type and size | +| `similar(A, dims::Dims)` | `similar(A, eltype(A), dims)` | Return a mutable array with the same element type and size *dims* | +| `similar(A, ::Type{S}, dims::Dims)` | `Array{S}(undef, dims)` | Return a mutable array with the specified element type and size | | **Non-traditional indices** | **Default definition** | **Brief description** | | `axes(A)` | `map(OneTo, size(A))` | Return the `AbstractUnitRange` of valid indices | -| `Base.similar(A, ::Type{S}, inds::NTuple{Ind})` | `similar(A, S, Base.to_shape(inds))` | Return a mutable array with the specified indices `inds` (see below) | +| `Base.similar(A, ::Type{S}, inds)` | `similar(A, S, Base.to_shape(inds))` | Return a mutable array with the specified indices `inds` (see below) | | `Base.similar(T::Union{Type,Function}, inds)` | `T(Base.to_shape(inds))` | Return an array similar to `T` with the specified indices `inds` (see below) | If a type is defined as a subtype of `AbstractArray`, it inherits a very large set of rich behaviors diff --git a/codex/manual/parallel-computing.md b/codex/manual/parallel-computing.md index 08addb8..aa9b43b 100644 --- a/codex/manual/parallel-computing.md +++ b/codex/manual/parallel-computing.md @@ -7,22 +7,22 @@ the different levels of parallelism offered by Julia. We can divide them in thre 2. Multi-Threading 3. Multi-Core or Distributed Processing -We will first consider Julia [Tasks (aka Coroutines)](@ref man-tasks) and other modules that rely on the Julia runtime library, that allow to suspend and resume computations with full control of inter-`Tasks` communication without having to manually interface with the operative system's scheduler. -Julia also allows to communicate between `Tasks` through operations like [`wait`](@ref) and [`fetch`](@ref). -Communication and data synchronization is managed through [`Channel`](@ref)s, which are the conduit -that allows inter-`Tasks` communication. +We will first consider Julia [Tasks (aka Coroutines)](@ref man-tasks) and other modules that rely on the Julia runtime library, that allow us to suspend and resume computations with full control of inter-`Tasks` communication without having to manually interface with the operating system's scheduler. +Julia also supports communication between `Tasks` through operations like [`wait`](@ref) and [`fetch`](@ref). +Communication and data synchronization is managed through [`Channel`](@ref)s, which are the conduits +that provide inter-`Tasks` communication. Julia also supports experimental multi-threading, where execution is forked and an anonymous function is run across all threads. -Described as a fork-join approach, parallel threads are branched off and they all have to join the Julia main thread to make serial execution continue. +Known as the fork-join approach, parallel threads execute independently, and must ultimately be joined in Julia's main thread to allow serial execution to continue. Multi-threading is supported using the `Base.Threads` module that is still considered experimental, as Julia is -not fully thread-safe yet. In particular segfaults seem to emerge for I\O operations and task switching. -As an un up-to-date reference, keep an eye on [the issue tracker](https://github.com/JuliaLang/julia/issues?q=is%3Aopen+is%3Aissue+label%3Amultithreading). +not yet fully thread-safe. In particular segfaults seem to occur during I\O operations and task switching. +As an up-to-date reference, keep an eye on [the issue tracker](https://github.com/JuliaLang/julia/issues?q=is%3Aopen+is%3Aissue+label%3Amultithreading). Multi-Threading should only be used if you take into consideration global variables, locks and -atomics, so we will explain it later. +atomics, all of which are explained later. -In the end we will present Julia's way to distributed and parallel computing. With scientific computing -in mind, Julia natively implements interfaces to distribute a process through multiple cores or machines. +In the end we will present Julia's approach to distributed and parallel computing. With scientific computing +in mind, Julia natively implements interfaces to distribute a process across multiple cores or machines. Also we will mention useful external packages for distributed programming like `MPI.jl` and `DistributedArrays.jl`. # Coroutines @@ -1595,7 +1595,7 @@ requirements for the inbuilt `LocalManager` and `SSHManager`: running the Julia REPL (i.e., the master) with the rest of the cluster on the cloud, say on Amazon EC2. In this case only port 22 needs to be opened at the remote cluster coupled with SSH client authenticated via public key infrastructure (PKI). Authentication credentials can be supplied - via `sshflags`, for example ```sshflags=`-e ` ```. + via `sshflags`, for example ```sshflags=`-i ` ```. In an all-to-all topology (the default), all workers connect to each other via plain TCP sockets. The security policy on the cluster nodes must thus ensure free connectivity between workers for diff --git a/src/manual/interfaces.md b/src/manual/interfaces.md index 5b52902..db69514 100644 --- a/src/manual/interfaces.md +++ b/src/manual/interfaces.md @@ -231,11 +231,11 @@ ourselves, we can officially define it as a subtype of an [`AbstractArray`](@ref | `length(A)` | `prod(size(A))` | Number of elements | | `similar(A)` | `similar(A, eltype(A), size(A))` | Return a mutable array with the same shape and element type | | `similar(A, ::Type{S})` | `similar(A, S, size(A))` | Return a mutable array with the same shape and the specified element type | -| `similar(A, dims::NTuple{Int})` | `similar(A, eltype(A), dims)` | Return a mutable array with the same element type and size *dims* | -| `similar(A, ::Type{S}, dims::NTuple{Int})` | `Array{S}(undef, dims)` | Return a mutable array with the specified element type and size | +| `similar(A, dims::Dims)` | `similar(A, eltype(A), dims)` | Return a mutable array with the same element type and size *dims* | +| `similar(A, ::Type{S}, dims::Dims)` | `Array{S}(undef, dims)` | Return a mutable array with the specified element type and size | | **Non-traditional indices** | **Default definition** | **Brief description** | | `axes(A)` | `map(OneTo, size(A))` | Return the `AbstractUnitRange` of valid indices | -| `Base.similar(A, ::Type{S}, inds::NTuple{Ind})` | `similar(A, S, Base.to_shape(inds))` | Return a mutable array with the specified indices `inds` (see below) | +| `Base.similar(A, ::Type{S}, inds)` | `similar(A, S, Base.to_shape(inds))` | Return a mutable array with the specified indices `inds` (see below) | | `Base.similar(T::Union{Type,Function}, inds)` | `T(Base.to_shape(inds))` | Return an array similar to `T` with the specified indices `inds` (see below) | If a type is defined as a subtype of `AbstractArray`, it inherits a very large set of rich behaviors diff --git a/src/manual/parallel-computing.md b/src/manual/parallel-computing.md index 08addb8..aa9b43b 100644 --- a/src/manual/parallel-computing.md +++ b/src/manual/parallel-computing.md @@ -7,22 +7,22 @@ the different levels of parallelism offered by Julia. We can divide them in thre 2. Multi-Threading 3. Multi-Core or Distributed Processing -We will first consider Julia [Tasks (aka Coroutines)](@ref man-tasks) and other modules that rely on the Julia runtime library, that allow to suspend and resume computations with full control of inter-`Tasks` communication without having to manually interface with the operative system's scheduler. -Julia also allows to communicate between `Tasks` through operations like [`wait`](@ref) and [`fetch`](@ref). -Communication and data synchronization is managed through [`Channel`](@ref)s, which are the conduit -that allows inter-`Tasks` communication. +We will first consider Julia [Tasks (aka Coroutines)](@ref man-tasks) and other modules that rely on the Julia runtime library, that allow us to suspend and resume computations with full control of inter-`Tasks` communication without having to manually interface with the operating system's scheduler. +Julia also supports communication between `Tasks` through operations like [`wait`](@ref) and [`fetch`](@ref). +Communication and data synchronization is managed through [`Channel`](@ref)s, which are the conduits +that provide inter-`Tasks` communication. Julia also supports experimental multi-threading, where execution is forked and an anonymous function is run across all threads. -Described as a fork-join approach, parallel threads are branched off and they all have to join the Julia main thread to make serial execution continue. +Known as the fork-join approach, parallel threads execute independently, and must ultimately be joined in Julia's main thread to allow serial execution to continue. Multi-threading is supported using the `Base.Threads` module that is still considered experimental, as Julia is -not fully thread-safe yet. In particular segfaults seem to emerge for I\O operations and task switching. -As an un up-to-date reference, keep an eye on [the issue tracker](https://github.com/JuliaLang/julia/issues?q=is%3Aopen+is%3Aissue+label%3Amultithreading). +not yet fully thread-safe. In particular segfaults seem to occur during I\O operations and task switching. +As an up-to-date reference, keep an eye on [the issue tracker](https://github.com/JuliaLang/julia/issues?q=is%3Aopen+is%3Aissue+label%3Amultithreading). Multi-Threading should only be used if you take into consideration global variables, locks and -atomics, so we will explain it later. +atomics, all of which are explained later. -In the end we will present Julia's way to distributed and parallel computing. With scientific computing -in mind, Julia natively implements interfaces to distribute a process through multiple cores or machines. +In the end we will present Julia's approach to distributed and parallel computing. With scientific computing +in mind, Julia natively implements interfaces to distribute a process across multiple cores or machines. Also we will mention useful external packages for distributed programming like `MPI.jl` and `DistributedArrays.jl`. # Coroutines @@ -1595,7 +1595,7 @@ requirements for the inbuilt `LocalManager` and `SSHManager`: running the Julia REPL (i.e., the master) with the rest of the cluster on the cloud, say on Amazon EC2. In this case only port 22 needs to be opened at the remote cluster coupled with SSH client authenticated via public key infrastructure (PKI). Authentication credentials can be supplied - via `sshflags`, for example ```sshflags=`-e ` ```. + via `sshflags`, for example ```sshflags=`-i ` ```. In an all-to-all topology (the default), all workers connect to each other via plain TCP sockets. The security policy on the cluster nodes must thus ensure free connectivity between workers for From f910719e0cae78ef028a1d926935bfe07c44c743 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Fri, 21 Sep 2018 20:28:59 +0900 Subject: [PATCH 060/153] update Julia Commit ce6454642c --- codex/base/base.md | 17 +++++++++++++++++ codex/manual/arrays.md | 4 ++-- codex/manual/calling-c-and-fortran-code.md | 6 +++--- codex/manual/documentation.md | 6 +++--- codex/manual/networking-and-streams.md | 14 +++++++------- codex/manual/noteworthy-differences.md | 11 +++++------ codex/manual/parallel-computing.md | 6 +++--- codex/stdlib/LinearAlgebra.md | 2 +- codex/stdlib/Pkg.md | 5 +++-- src/base/base.md | 17 +++++++++++++++++ src/manual/calling-c-and-fortran-code.md | 6 +++--- src/manual/documentation.md | 6 +++--- src/manual/networking-and-streams.md | 14 +++++++------- src/manual/noteworthy-differences.md | 11 +++++------ src/manual/parallel-computing.md | 6 +++--- src/stdlib/LinearAlgebra.md | 2 +- src/stdlib/Pkg.md | 5 +++-- 17 files changed, 86 insertions(+), 52 deletions(-) diff --git a/codex/base/base.md b/codex/base/base.md index 6ba58b7..8763167 100644 --- a/codex/base/base.md +++ b/codex/base/base.md @@ -37,6 +37,22 @@ ans ## Keywords +This is the list of reserved keywords in Julia: +`baremodule`, `begin`, `break`, `catch`, `const`, `continue`, `do`, +`else`, `elseif`, `end`, `export`, `false`, `finally`, `for`, `function`, +`global`, `if`, `import`, `let`, `local`, `macro`, `module`, `quote`, +`return`, `struct`, `true`, `try`, `using`, `while`. +Those keywords are not allowed to be used as variable names. + +The following two word sequences are reserved: +`abstract type`, `mutable struct`, `primitive type`. +However, you can create variables with names: +`abstract`, `mutable`, `primitive` and `type`. + +Finally `where` is parsed as an infix operator for writing parametric method +and type definitions. Also `in` and `isa` are parsed as infix operators. +Creation of variable named `where`, `is` or `isa` is allowed though. + ```@docs module export @@ -65,6 +81,7 @@ struct mutable struct abstract type primitive type +where ... ; ``` diff --git a/codex/manual/arrays.md b/codex/manual/arrays.md index 4b4c4be..d209686 100644 --- a/codex/manual/arrays.md +++ b/codex/manual/arrays.md @@ -777,7 +777,7 @@ julia> string.(1:3, ". ", ["First", "Second", "Third"]) ## Implementation -The base array type in Julia is the abstract type [`AbstractArray{T,N}`](@ref). It is parametrized by +The base array type in Julia is the abstract type [`AbstractArray{T,N}`](@ref). It is parameterized by the number of dimensions `N` and the element type `T`. [`AbstractVector`](@ref) and [`AbstractMatrix`](@ref) are aliases for the 1-d and 2-d cases. Operations on `AbstractArray` objects are defined using higher level operators and functions, in a way that is independent of the underlying storage. These operations @@ -828,7 +828,7 @@ index of dimension `k` by `1` should increase the index `i` of [`getindex(A,i)`] [`stride(A,k)`](@ref). If a pointer conversion method [`Base.unsafe_convert(Ptr{T}, A)`](@ref) is provided, the memory layout must correspond in the same way to these strides. `DenseArray` is a very specific example of a strided array where the elements are arranged contiguously, thus it -provides its subtypes with the approporiate definition of `strides`. More concrete examples +provides its subtypes with the appropriate definition of `strides`. More concrete examples can be found within the [interface guide for strided arrays](@ref man-interface-strided-arrays). [`StridedVector`](@ref) and [`StridedMatrix`](@ref) are convenient aliases for many of the builtin array types that are considered strided arrays, allowing them to dispatch to select specialized implementations that diff --git a/codex/manual/calling-c-and-fortran-code.md b/codex/manual/calling-c-and-fortran-code.md index dfd82b4..6155952 100644 --- a/codex/manual/calling-c-and-fortran-code.md +++ b/codex/manual/calling-c-and-fortran-code.md @@ -130,7 +130,7 @@ Here is a slightly more complex example that discovers the local machine's hostn ```julia function gethostname() - hostname = Vector{UInt8}(128) + hostname = Vector{UInt8}(undef, 128) ccall((:gethostname, "libc"), Int32, (Ptr{UInt8}, Csize_t), hostname, sizeof(hostname)) @@ -820,7 +820,7 @@ function sf_bessel_Jn_array(nmin::Integer, nmax::Integer, x::Real) if nmax < nmin throw(DomainError()) end - result_array = Vector{Cdouble}(nmax - nmin + 1) + result_array = Vector{Cdouble}(undef, nmax - nmin + 1) errorcode = ccall( (:gsl_sf_bessel_Jn_array, :libgsl), # name of C function and library Cint, # output type @@ -973,7 +973,7 @@ Other supported conventions are: `stdcall`, `cdecl`, `fastcall`, and `thiscall` signature for Windows: ```julia -hn = Vector{UInt8}(256) +hn = Vector{UInt8}(undef, 256) err = ccall(:gethostname, stdcall, Int32, (Ptr{UInt8}, UInt32), hn, length(hn)) ``` diff --git a/codex/manual/documentation.md b/codex/manual/documentation.md index 195df3e..41ac5e4 100644 --- a/codex/manual/documentation.md +++ b/codex/manual/documentation.md @@ -181,7 +181,7 @@ As in the example above, we recommend following some simple conventions when wri 9. Respect the line length limit used in the surrounding code. Docstrings are edited using the same tools as code. Therefore, the same conventions should apply. - It it advised to add line breaks after 92 characters. + It is advised to add line breaks after 92 characters. 6. Provide information allowing custom types to implement the function in an `# Implementation` section. These implementation details intended for developers rather than users, explaining e.g. which functions should be overridden and which functions @@ -568,7 +568,7 @@ A paragraph containing a **bold** word. Surround words with one asterisk, `*`, to display the enclosed text in italics. ``` -A paragraph containing an *emphasised* word. +A paragraph containing an *emphasized* word. ``` #### Literals @@ -665,7 +665,7 @@ in the [Inline elements](@ref) section above, with one or more blank lines above ``` This is a paragraph. -And this is *another* one containing some emphasised text. +And this is *another* one containing some emphasized text. A new line, but still part of the same paragraph. ``` diff --git a/codex/manual/networking-and-streams.md b/codex/manual/networking-and-streams.md index bb86c3b..dada5e5 100644 --- a/codex/manual/networking-and-streams.md +++ b/codex/manual/networking-and-streams.md @@ -210,25 +210,25 @@ same function may also be used to create various other kinds of servers: ```julia-repl julia> listen(2000) # Listens on localhost:2000 (IPv4) -Base.TCPServer(active) +Sockets.TCPServer(active) julia> listen(ip"127.0.0.1",2000) # Equivalent to the first -Base.TCPServer(active) +Sockets.TCPServer(active) julia> listen(ip"::1",2000) # Listens on localhost:2000 (IPv6) -Base.TCPServer(active) +Sockets.TCPServer(active) julia> listen(IPv4(0),2001) # Listens on port 2001 on all IPv4 interfaces -Base.TCPServer(active) +Sockets.TCPServer(active) julia> listen(IPv6(0),2001) # Listens on port 2001 on all IPv6 interfaces -Base.TCPServer(active) +Sockets.TCPServer(active) julia> listen("testsocket") # Listens on a UNIX domain socket -Base.PipeServer(active) +Sockets.PipeServer(active) julia> listen("\\\\.\\pipe\\testsocket") # Listens on a Windows named pipe -Base.PipeServer(active) +Sockets.PipeServer(active) ``` Note that the return type of the last invocation is different. This is because this server does not diff --git a/codex/manual/noteworthy-differences.md b/codex/manual/noteworthy-differences.md index c45d7b1..ad0ef24 100644 --- a/codex/manual/noteworthy-differences.md +++ b/codex/manual/noteworthy-differences.md @@ -50,12 +50,12 @@ may trip up Julia users accustomed to MATLAB: over every element of an array when called with a single argument, as in `sum(A)`, even if `A` has more than one dimension. * In Julia, parentheses must be used to call a function with zero arguments, like in [`rand()`](@ref). - * Julia discourages the used of semicolons to end statements. The results of statements are not + * Julia discourages the use of semicolons to end statements. The results of statements are not automatically printed (except at the interactive prompt), and lines of code do not need to end with semicolons. [`println`](@ref) or [`@printf`](@ref) can be used to print specific output. * In Julia, if `A` and `B` are arrays, logical comparison operations like `A == B` do not return an array of booleans. Instead, use `A .== B`, and similarly for the other boolean operators like - [`<`](@ref), [`>`](@ref) and `=`. + [`<`](@ref), [`>`](@ref). * In Julia, the operators [`&`](@ref), [`|`](@ref), and [`⊻`](@ref xor) ([`xor`](@ref)) perform the bitwise operations equivalent to `and`, `or`, and `xor` respectively in MATLAB, and have precedence similar to Python's bitwise operators (unlike C). They can operate on scalars or element-wise @@ -164,8 +164,7 @@ For users coming to Julia from R, these are some noteworthy differences: in R, but both arguments need to have the same dimensions. While [`maximum`](@ref) and [`minimum`](@ref) replace `max` and `min` in R, there are important differences. * Julia's [`sum`](@ref), [`prod`](@ref), [`maximum`](@ref), and [`minimum`](@ref) are different - from their counterparts in R. They all accept one or two arguments. The first argument is an iterable - collection such as an array. If there is a second argument, then this argument indicates the + from their counterparts in R. They all accept an optional keyword argument `dims`, which indicates the dimensions, over which the operation is carried out. For instance, let `A = [1 2; 3 4]` in Julia and `B <- rbind(c(1,2),c(3,4))` be the same matrix in R. Then `sum(A)` gives the same result as `sum(B)`, but `sum(A, dims=1)` is a row vector containing the sum over each column and `sum(A, dims=2)` @@ -181,7 +180,7 @@ For users coming to Julia from R, these are some noteworthy differences: * Julia is eagerly evaluated and does not support R-style lazy evaluation. For most users, this means that there are very few unquoted expressions or column names. * Julia does not support the `NULL` type. The closest equivalent is [`nothing`](@ref), but it - behaves like a scalar value rather than like a list. Use `x == nothing` instead of `is.null(x)`. + behaves like a scalar value rather than like a list. Use `x === nothing` instead of `is.null(x)`. * In Julia, missing values are represented by the [`missing`](@ref) object rather than by `NA`. Use [`ismissing(x)`](@ref) instead of `isna(x)`. The [`skipmissing`](@ref) function is generally used instead of `na.rm=TRUE` (though in some particular cases functions take a `skipmissing` @@ -297,7 +296,7 @@ For users coming to Julia from R, these are some noteworthy differences: useful if the macro appears within another expression, and is often clearest. The statement-like form is often used to annotate blocks, as in the distributed `for` construct: `@distributed for i in 1:n; #= body =#; end`. Where the end of the macro construct may be unclear, use the function-like form. - * Julia now has an enumeration type, expressed using the macro `@enum(name, value1, value2, ...)` + * Julia has an enumeration type, expressed using the macro `@enum(name, value1, value2, ...)` For example: `@enum(Fruit, banana=1, apple, pear)` * By convention, functions that modify their arguments have a `!` at the end of the name, for example `push!`. diff --git a/codex/manual/parallel-computing.md b/codex/manual/parallel-computing.md index aa9b43b..2dbbd6b 100644 --- a/codex/manual/parallel-computing.md +++ b/codex/manual/parallel-computing.md @@ -16,7 +16,7 @@ Julia also supports experimental multi-threading, where execution is forked and threads. Known as the fork-join approach, parallel threads execute independently, and must ultimately be joined in Julia's main thread to allow serial execution to continue. Multi-threading is supported using the `Base.Threads` module that is still considered experimental, as Julia is -not yet fully thread-safe. In particular segfaults seem to occur during I\O operations and task switching. +not yet fully thread-safe. In particular segfaults seem to occur during I/O operations and task switching. As an up-to-date reference, keep an eye on [the issue tracker](https://github.com/JuliaLang/julia/issues?q=is%3Aopen+is%3Aissue+label%3Amultithreading). Multi-Threading should only be used if you take into consideration global variables, locks and atomics, all of which are explained later. @@ -1649,13 +1649,13 @@ in future releases. Outside of Julia parallelism there are plenty of external packages that should be mentioned. For example [MPI.jl](https://github.com/JuliaParallel/MPI.jl) is a Julia wrapper for the `MPI` protocol, or [DistributedArrays.jl](https://github.com/JuliaParallel/Distributedarrays.jl), as presented in [Shared Arrays](@ref). -A mention must be done to the Julia's GPU programming ecosystem, which includes : +A mention must be made of Julia's GPU programming ecosystem, which includes: 1. Low-level (C kernel) based operations [OpenCL.jl](https://github.com/JuliaGPU/OpenCL.jl) and [CUDAdrv.jl](https://github.com/JuliaGPU/CUDAdrv.jl) which are respectively an OpenCL interface and a CUDA wrapper. 2. Low-level (Julia Kernel) interfaces like [CUDAnative.jl](https://github.com/JuliaGPU/CUDAnative.jl) which is a Julia native CUDA implementation. -3. High-level vendor specific abstractions like [CuArrays.jl](https://github.com/JuliaGPU/CuArrays.jl) and [CLArrays.jl](https://github.com/JuliaGPU/CLArrays.jl) +3. High-level vendor-specific abstractions like [CuArrays.jl](https://github.com/JuliaGPU/CuArrays.jl) and [CLArrays.jl](https://github.com/JuliaGPU/CLArrays.jl) 4. High-level libraries like [ArrayFire.jl](https://github.com/JuliaComputing/ArrayFire.jl) and [GPUArrays.jl](https://github.com/JuliaGPU/GPUArrays.jl) diff --git a/codex/stdlib/LinearAlgebra.md b/codex/stdlib/LinearAlgebra.md index bc32753..7717baa 100644 --- a/codex/stdlib/LinearAlgebra.md +++ b/codex/stdlib/LinearAlgebra.md @@ -5,7 +5,7 @@ DocTestSetup = :(using LinearAlgebra) ``` In addition to (and as part of) its support for multi-dimensional arrays, Julia provides native implementations -of many common and useful linear algebra operations. Basic operations, such as [`tr`](@ref), [`det`](@ref), +of many common and useful linear algebra operations which can be loaded with `using LinearAlgebra`. Basic operations, such as [`tr`](@ref), [`det`](@ref), and [`inv`](@ref) are all supported: ```jldoctest diff --git a/codex/stdlib/Pkg.md b/codex/stdlib/Pkg.md index c76941e..562fc5d 100644 --- a/codex/stdlib/Pkg.md +++ b/codex/stdlib/Pkg.md @@ -81,7 +81,7 @@ identify the package in projects that depend on it. **Application:** a project which provides standalone functionality not intended to be reused by other Julia projects. For example a web application or a -commmand-line utility, or simulation/analytics code accompanying a scientific paper. +command-line utility, or simulation/analytics code accompanying a scientific paper. An application may have a UUID but does not need one. An application may also provide global configuration options for packages it depends on. Packages, on the other hand, may not provide global configuration @@ -427,7 +427,7 @@ Note the pin symbol `⚲` showing that the package is pinned. Removing the pin i ### Testing packages -The tests for a package can be run using `test`command: +The tests for a package can be run using `test` command: ``` (v1.0) pkg> test Example @@ -734,6 +734,7 @@ Compatibility for a dependency is entered in the `Project.toml` file as for exam ```toml [compat] +julia = "1.0" Example = "0.4.3" ``` diff --git a/src/base/base.md b/src/base/base.md index 6ba58b7..8763167 100644 --- a/src/base/base.md +++ b/src/base/base.md @@ -37,6 +37,22 @@ ans ## Keywords +This is the list of reserved keywords in Julia: +`baremodule`, `begin`, `break`, `catch`, `const`, `continue`, `do`, +`else`, `elseif`, `end`, `export`, `false`, `finally`, `for`, `function`, +`global`, `if`, `import`, `let`, `local`, `macro`, `module`, `quote`, +`return`, `struct`, `true`, `try`, `using`, `while`. +Those keywords are not allowed to be used as variable names. + +The following two word sequences are reserved: +`abstract type`, `mutable struct`, `primitive type`. +However, you can create variables with names: +`abstract`, `mutable`, `primitive` and `type`. + +Finally `where` is parsed as an infix operator for writing parametric method +and type definitions. Also `in` and `isa` are parsed as infix operators. +Creation of variable named `where`, `is` or `isa` is allowed though. + ```@docs module export @@ -65,6 +81,7 @@ struct mutable struct abstract type primitive type +where ... ; ``` diff --git a/src/manual/calling-c-and-fortran-code.md b/src/manual/calling-c-and-fortran-code.md index dfd82b4..6155952 100644 --- a/src/manual/calling-c-and-fortran-code.md +++ b/src/manual/calling-c-and-fortran-code.md @@ -130,7 +130,7 @@ Here is a slightly more complex example that discovers the local machine's hostn ```julia function gethostname() - hostname = Vector{UInt8}(128) + hostname = Vector{UInt8}(undef, 128) ccall((:gethostname, "libc"), Int32, (Ptr{UInt8}, Csize_t), hostname, sizeof(hostname)) @@ -820,7 +820,7 @@ function sf_bessel_Jn_array(nmin::Integer, nmax::Integer, x::Real) if nmax < nmin throw(DomainError()) end - result_array = Vector{Cdouble}(nmax - nmin + 1) + result_array = Vector{Cdouble}(undef, nmax - nmin + 1) errorcode = ccall( (:gsl_sf_bessel_Jn_array, :libgsl), # name of C function and library Cint, # output type @@ -973,7 +973,7 @@ Other supported conventions are: `stdcall`, `cdecl`, `fastcall`, and `thiscall` signature for Windows: ```julia -hn = Vector{UInt8}(256) +hn = Vector{UInt8}(undef, 256) err = ccall(:gethostname, stdcall, Int32, (Ptr{UInt8}, UInt32), hn, length(hn)) ``` diff --git a/src/manual/documentation.md b/src/manual/documentation.md index 195df3e..41ac5e4 100644 --- a/src/manual/documentation.md +++ b/src/manual/documentation.md @@ -181,7 +181,7 @@ As in the example above, we recommend following some simple conventions when wri 9. Respect the line length limit used in the surrounding code. Docstrings are edited using the same tools as code. Therefore, the same conventions should apply. - It it advised to add line breaks after 92 characters. + It is advised to add line breaks after 92 characters. 6. Provide information allowing custom types to implement the function in an `# Implementation` section. These implementation details intended for developers rather than users, explaining e.g. which functions should be overridden and which functions @@ -568,7 +568,7 @@ A paragraph containing a **bold** word. Surround words with one asterisk, `*`, to display the enclosed text in italics. ``` -A paragraph containing an *emphasised* word. +A paragraph containing an *emphasized* word. ``` #### Literals @@ -665,7 +665,7 @@ in the [Inline elements](@ref) section above, with one or more blank lines above ``` This is a paragraph. -And this is *another* one containing some emphasised text. +And this is *another* one containing some emphasized text. A new line, but still part of the same paragraph. ``` diff --git a/src/manual/networking-and-streams.md b/src/manual/networking-and-streams.md index bb86c3b..dada5e5 100644 --- a/src/manual/networking-and-streams.md +++ b/src/manual/networking-and-streams.md @@ -210,25 +210,25 @@ same function may also be used to create various other kinds of servers: ```julia-repl julia> listen(2000) # Listens on localhost:2000 (IPv4) -Base.TCPServer(active) +Sockets.TCPServer(active) julia> listen(ip"127.0.0.1",2000) # Equivalent to the first -Base.TCPServer(active) +Sockets.TCPServer(active) julia> listen(ip"::1",2000) # Listens on localhost:2000 (IPv6) -Base.TCPServer(active) +Sockets.TCPServer(active) julia> listen(IPv4(0),2001) # Listens on port 2001 on all IPv4 interfaces -Base.TCPServer(active) +Sockets.TCPServer(active) julia> listen(IPv6(0),2001) # Listens on port 2001 on all IPv6 interfaces -Base.TCPServer(active) +Sockets.TCPServer(active) julia> listen("testsocket") # Listens on a UNIX domain socket -Base.PipeServer(active) +Sockets.PipeServer(active) julia> listen("\\\\.\\pipe\\testsocket") # Listens on a Windows named pipe -Base.PipeServer(active) +Sockets.PipeServer(active) ``` Note that the return type of the last invocation is different. This is because this server does not diff --git a/src/manual/noteworthy-differences.md b/src/manual/noteworthy-differences.md index c45d7b1..ad0ef24 100644 --- a/src/manual/noteworthy-differences.md +++ b/src/manual/noteworthy-differences.md @@ -50,12 +50,12 @@ may trip up Julia users accustomed to MATLAB: over every element of an array when called with a single argument, as in `sum(A)`, even if `A` has more than one dimension. * In Julia, parentheses must be used to call a function with zero arguments, like in [`rand()`](@ref). - * Julia discourages the used of semicolons to end statements. The results of statements are not + * Julia discourages the use of semicolons to end statements. The results of statements are not automatically printed (except at the interactive prompt), and lines of code do not need to end with semicolons. [`println`](@ref) or [`@printf`](@ref) can be used to print specific output. * In Julia, if `A` and `B` are arrays, logical comparison operations like `A == B` do not return an array of booleans. Instead, use `A .== B`, and similarly for the other boolean operators like - [`<`](@ref), [`>`](@ref) and `=`. + [`<`](@ref), [`>`](@ref). * In Julia, the operators [`&`](@ref), [`|`](@ref), and [`⊻`](@ref xor) ([`xor`](@ref)) perform the bitwise operations equivalent to `and`, `or`, and `xor` respectively in MATLAB, and have precedence similar to Python's bitwise operators (unlike C). They can operate on scalars or element-wise @@ -164,8 +164,7 @@ For users coming to Julia from R, these are some noteworthy differences: in R, but both arguments need to have the same dimensions. While [`maximum`](@ref) and [`minimum`](@ref) replace `max` and `min` in R, there are important differences. * Julia's [`sum`](@ref), [`prod`](@ref), [`maximum`](@ref), and [`minimum`](@ref) are different - from their counterparts in R. They all accept one or two arguments. The first argument is an iterable - collection such as an array. If there is a second argument, then this argument indicates the + from their counterparts in R. They all accept an optional keyword argument `dims`, which indicates the dimensions, over which the operation is carried out. For instance, let `A = [1 2; 3 4]` in Julia and `B <- rbind(c(1,2),c(3,4))` be the same matrix in R. Then `sum(A)` gives the same result as `sum(B)`, but `sum(A, dims=1)` is a row vector containing the sum over each column and `sum(A, dims=2)` @@ -181,7 +180,7 @@ For users coming to Julia from R, these are some noteworthy differences: * Julia is eagerly evaluated and does not support R-style lazy evaluation. For most users, this means that there are very few unquoted expressions or column names. * Julia does not support the `NULL` type. The closest equivalent is [`nothing`](@ref), but it - behaves like a scalar value rather than like a list. Use `x == nothing` instead of `is.null(x)`. + behaves like a scalar value rather than like a list. Use `x === nothing` instead of `is.null(x)`. * In Julia, missing values are represented by the [`missing`](@ref) object rather than by `NA`. Use [`ismissing(x)`](@ref) instead of `isna(x)`. The [`skipmissing`](@ref) function is generally used instead of `na.rm=TRUE` (though in some particular cases functions take a `skipmissing` @@ -297,7 +296,7 @@ For users coming to Julia from R, these are some noteworthy differences: useful if the macro appears within another expression, and is often clearest. The statement-like form is often used to annotate blocks, as in the distributed `for` construct: `@distributed for i in 1:n; #= body =#; end`. Where the end of the macro construct may be unclear, use the function-like form. - * Julia now has an enumeration type, expressed using the macro `@enum(name, value1, value2, ...)` + * Julia has an enumeration type, expressed using the macro `@enum(name, value1, value2, ...)` For example: `@enum(Fruit, banana=1, apple, pear)` * By convention, functions that modify their arguments have a `!` at the end of the name, for example `push!`. diff --git a/src/manual/parallel-computing.md b/src/manual/parallel-computing.md index aa9b43b..2dbbd6b 100644 --- a/src/manual/parallel-computing.md +++ b/src/manual/parallel-computing.md @@ -16,7 +16,7 @@ Julia also supports experimental multi-threading, where execution is forked and threads. Known as the fork-join approach, parallel threads execute independently, and must ultimately be joined in Julia's main thread to allow serial execution to continue. Multi-threading is supported using the `Base.Threads` module that is still considered experimental, as Julia is -not yet fully thread-safe. In particular segfaults seem to occur during I\O operations and task switching. +not yet fully thread-safe. In particular segfaults seem to occur during I/O operations and task switching. As an up-to-date reference, keep an eye on [the issue tracker](https://github.com/JuliaLang/julia/issues?q=is%3Aopen+is%3Aissue+label%3Amultithreading). Multi-Threading should only be used if you take into consideration global variables, locks and atomics, all of which are explained later. @@ -1649,13 +1649,13 @@ in future releases. Outside of Julia parallelism there are plenty of external packages that should be mentioned. For example [MPI.jl](https://github.com/JuliaParallel/MPI.jl) is a Julia wrapper for the `MPI` protocol, or [DistributedArrays.jl](https://github.com/JuliaParallel/Distributedarrays.jl), as presented in [Shared Arrays](@ref). -A mention must be done to the Julia's GPU programming ecosystem, which includes : +A mention must be made of Julia's GPU programming ecosystem, which includes: 1. Low-level (C kernel) based operations [OpenCL.jl](https://github.com/JuliaGPU/OpenCL.jl) and [CUDAdrv.jl](https://github.com/JuliaGPU/CUDAdrv.jl) which are respectively an OpenCL interface and a CUDA wrapper. 2. Low-level (Julia Kernel) interfaces like [CUDAnative.jl](https://github.com/JuliaGPU/CUDAnative.jl) which is a Julia native CUDA implementation. -3. High-level vendor specific abstractions like [CuArrays.jl](https://github.com/JuliaGPU/CuArrays.jl) and [CLArrays.jl](https://github.com/JuliaGPU/CLArrays.jl) +3. High-level vendor-specific abstractions like [CuArrays.jl](https://github.com/JuliaGPU/CuArrays.jl) and [CLArrays.jl](https://github.com/JuliaGPU/CLArrays.jl) 4. High-level libraries like [ArrayFire.jl](https://github.com/JuliaComputing/ArrayFire.jl) and [GPUArrays.jl](https://github.com/JuliaGPU/GPUArrays.jl) diff --git a/src/stdlib/LinearAlgebra.md b/src/stdlib/LinearAlgebra.md index bc32753..7717baa 100644 --- a/src/stdlib/LinearAlgebra.md +++ b/src/stdlib/LinearAlgebra.md @@ -5,7 +5,7 @@ DocTestSetup = :(using LinearAlgebra) ``` In addition to (and as part of) its support for multi-dimensional arrays, Julia provides native implementations -of many common and useful linear algebra operations. Basic operations, such as [`tr`](@ref), [`det`](@ref), +of many common and useful linear algebra operations which can be loaded with `using LinearAlgebra`. Basic operations, such as [`tr`](@ref), [`det`](@ref), and [`inv`](@ref) are all supported: ```jldoctest diff --git a/src/stdlib/Pkg.md b/src/stdlib/Pkg.md index c76941e..562fc5d 100644 --- a/src/stdlib/Pkg.md +++ b/src/stdlib/Pkg.md @@ -81,7 +81,7 @@ identify the package in projects that depend on it. **Application:** a project which provides standalone functionality not intended to be reused by other Julia projects. For example a web application or a -commmand-line utility, or simulation/analytics code accompanying a scientific paper. +command-line utility, or simulation/analytics code accompanying a scientific paper. An application may have a UUID but does not need one. An application may also provide global configuration options for packages it depends on. Packages, on the other hand, may not provide global configuration @@ -427,7 +427,7 @@ Note the pin symbol `⚲` showing that the package is pinned. Removing the pin i ### Testing packages -The tests for a package can be run using `test`command: +The tests for a package can be run using `test` command: ``` (v1.0) pkg> test Example @@ -734,6 +734,7 @@ Compatibility for a dependency is entered in the `Project.toml` file as for exam ```toml [compat] +julia = "1.0" Example = "0.4.3" ``` From a0923db156c00790ef1019ade131db5ccd773ee8 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Fri, 28 Sep 2018 04:08:54 +0900 Subject: [PATCH 061/153] update Julia Commit 8d5c109706 --- codex/base/base.md | 2 +- codex/base/file.md | 1 + codex/manual/arrays.md | 8 +++--- codex/manual/constructors.md | 28 +++++++++---------- .../handling-operating-system-variation.md | 15 +++++----- codex/manual/metaprogramming.md | 6 ++-- codex/manual/missing.md | 4 +-- codex/manual/noteworthy-differences.md | 3 +- codex/manual/parallel-computing.md | 2 +- codex/stdlib/UUIDs.md | 1 + src/base/base.md | 2 +- src/base/file.md | 1 + src/manual/arrays.md | 4 +-- src/manual/constructors.md | 28 +++++++++---------- .../handling-operating-system-variation.md | 15 +++++----- src/manual/metaprogramming.md | 6 ++-- src/manual/missing.md | 4 +-- src/manual/noteworthy-differences.md | 3 +- src/manual/parallel-computing.md | 2 +- src/stdlib/UUIDs.md | 1 + 20 files changed, 72 insertions(+), 64 deletions(-) diff --git a/codex/base/base.md b/codex/base/base.md index 8763167..c885e14 100644 --- a/codex/base/base.md +++ b/codex/base/base.md @@ -51,7 +51,7 @@ However, you can create variables with names: Finally `where` is parsed as an infix operator for writing parametric method and type definitions. Also `in` and `isa` are parsed as infix operators. -Creation of variable named `where`, `is` or `isa` is allowed though. +Creation of variable named `where`, `in` or `isa` is allowed though. ```@docs module diff --git a/codex/base/file.md b/codex/base/file.md index d2f57e2..9e0ac19 100644 --- a/codex/base/file.md +++ b/codex/base/file.md @@ -62,4 +62,5 @@ Base.Filesystem.expanduser Base.Filesystem.splitdir Base.Filesystem.splitdrive Base.Filesystem.splitext +Base.Filesystem.splitpath ``` diff --git a/codex/manual/arrays.md b/codex/manual/arrays.md index d209686..73241e3 100644 --- a/codex/manual/arrays.md +++ b/codex/manual/arrays.md @@ -9,7 +9,7 @@ from [`AbstractArray`](@ref). See the [manual section on the AbstractArray inter on implementing a custom array type. An array is a collection of objects stored in a multi-dimensional grid. In the most general case, -an array may contain objects of type `Any`. For most computational purposes, arrays should contain +an array may contain objects of type [`Any`](@ref). For most computational purposes, arrays should contain objects of a more specific type, such as [`Float64`](@ref) or [`Int32`](@ref). In general, unlike many other technical computing languages, Julia does not expect programs to @@ -23,7 +23,7 @@ sharing](https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing) while this prevents accidental modification by callees of a value in the caller, it makes avoiding unwanted copying of arrays difficult. By convention, a function name ending with a `!` indicates that it will mutate or destroy the -value of one or more of its arguments (see, for example, [`sort`](@ref) and [`sort!`](@ref). +value of one or more of its arguments (see, for example, [`sort`](@ref) and [`sort!`](@ref)). Callees must make explicit copies to ensure that they don't modify inputs that they don't intend to change. Many non- mutating functions are implemented by calling a function of the same name with an added `!` at the end on an explicit @@ -38,8 +38,8 @@ copy of the input, and returning that copy. | [`ndims(A)`](@ref) | the number of dimensions of `A` | | [`size(A)`](@ref) | a tuple containing the dimensions of `A` | | [`size(A,n)`](@ref) | the size of `A` along dimension `n` | -| [`axes(A)`](@ref) | a tuple containing the valid indices of `A` | -| [`axes(A,n)`](@ref) | a range expressing the valid indices along dimension `n` | +| [`axes(A)`](@ref) | a tuple containing the valid indices of `A` | +| [`axes(A,n)`](@ref) | a range expressing the valid indices along dimension `n` | | [`eachindex(A)`](@ref) | an efficient iterator for visiting each position in `A` | | [`stride(A,k)`](@ref) | the stride (linear index distance between adjacent elements) along dimension `k` | | [`strides(A)`](@ref) | a tuple of the strides in each dimension | diff --git a/codex/manual/constructors.md b/codex/manual/constructors.md index 287ff21..9f41aca 100644 --- a/codex/manual/constructors.md +++ b/codex/manual/constructors.md @@ -22,7 +22,7 @@ julia> foo.baz ``` For many types, forming new objects by binding their field values together is all that is ever -needed to create instances. There are, however, cases where more functionality is required when +needed to create instances. However, in some cases more functionality is required when creating composite objects. Sometimes invariants must be enforced, either by checking arguments or by transforming them. [Recursive data structures](https://en.wikipedia.org/wiki/Recursion_%28computer_science%29#Recursive_data_structures_.28structural_recursion.29), especially those that may be self-referential, often cannot be constructed cleanly without first @@ -34,7 +34,7 @@ addresses all of these cases and more. [^1]: Nomenclature: while the term "constructor" generally refers to the entire function which constructs objects of a type, it is common to abuse terminology slightly and refer to specific constructor - methods as "constructors". In such situations, it is generally clear from context that the term + methods as "constructors". In such situations, it is generally clear from the context that the term is used to mean "constructor method" rather than "constructor function", especially as it is often used in the sense of singling out a particular method of the constructor from all of the others. @@ -77,7 +77,7 @@ While outer constructor methods succeed in addressing the problem of providing a methods for constructing objects, they fail to address the other two use cases mentioned in the introduction of this chapter: enforcing invariants, and allowing construction of self-referential objects. For these problems, one needs *inner* constructor methods. An inner constructor method -is much like an outer constructor method, with two differences: +is like an outer constructor method, except for two differences: 1. It is declared inside the block of a type declaration, rather than outside of it like normal methods. 2. It has access to a special locally existent function called [`new`](@ref) that creates objects of the @@ -110,7 +110,7 @@ Stacktrace: ``` If the type were declared `mutable`, you could reach in and directly change the field values to -violate this invariant, but messing around with an object's internals uninvited is considered poor form. +violate this invariant. Of course, messing around with an object's internals uninvited is bad practice. You (or someone else) can also provide additional outer constructor methods at any later point, but once a type is declared, there is no way to add more inner constructor methods. Since outer constructor methods can only create objects by calling other constructor methods, ultimately, some inner constructor @@ -160,7 +160,7 @@ julia> T2(1.0) T2(1) ``` -It is considered good form to provide as few inner constructor methods as possible: only those +It is good practice to provide as few inner constructor methods as possible: only those taking all arguments explicitly and enforcing essential error checking and transformation. Additional convenience constructor methods, supplying default values or auxiliary transformations, should be provided as outer constructors that call the inner constructors to do the heavy lifting. This @@ -194,8 +194,8 @@ value for the `obj` field of another instance, such as, for example, itself. To allow for the creation of incompletely initialized objects, Julia allows the [`new`](@ref) function to be called with fewer than the number of fields that the type has, returning an object with the unspecified fields uninitialized. The inner constructor method can then use the incomplete -object, finishing its initialization before returning it. Here, for example, we take another crack -at defining the `SelfReferential` type, with a zero-argument inner constructor returning instances +object, finishing its initialization before returning it. Here, for example, is another attempt +at defining the `SelfReferential` type, this time using a zero-argument inner constructor returning instances having `obj` fields pointing to themselves: ```jldoctest selfrefer2 @@ -222,11 +222,11 @@ true ``` Although it is generally a good idea to return a fully initialized object from an inner constructor, -incompletely initialized objects can be returned: +it is possible to return incompletely initialized objects: ```jldoctest incomplete julia> mutable struct Incomplete - xx + data Incomplete() = new() end @@ -237,7 +237,7 @@ While you are allowed to create objects with uninitialized fields, any access to reference is an immediate error: ```jldoctest incomplete -julia> z.xx +julia> z.data ERROR: UndefRefError: access to undefined reference ``` @@ -263,13 +263,13 @@ You can pass incomplete objects to other functions from inner constructors to de ```jldoctest julia> mutable struct Lazy - xx + data Lazy(v) = complete_me(new(), v) end ``` As with incomplete objects returned from constructors, if `complete_me` or any of its callees -try to access the `xx` field of the `Lazy` object before it has been initialized, an error will +try to access the `data` field of the `Lazy` object before it has been initialized, an error will be thrown immediately. ## Parametric Constructors @@ -513,8 +513,8 @@ it is short, self-contained, and implements an entire basic Julia type. As we have seen, a typical parametric type has inner constructors that are called when type parameters are known; e.g. they apply to `Point{Int}` but not to `Point`. Optionally, outer constructors that determine type parameters automatically can be added, for example constructing a `Point{Int}` -from the call `Point(1,2)`. Outer constructors call inner constructors to do the core work of -making an instance. However, in some cases one would rather not provide inner constructors, so +from the call `Point(1,2)`. Outer constructors call inner constructors to actually +make instances. However, in some cases one would rather not provide inner constructors, so that specific type parameters cannot be requested manually. For example, say we define a type that stores a vector along with an accurate representation of diff --git a/codex/manual/handling-operating-system-variation.md b/codex/manual/handling-operating-system-variation.md index 46ee1ae..155d303 100644 --- a/codex/manual/handling-operating-system-variation.md +++ b/codex/manual/handling-operating-system-variation.md @@ -1,13 +1,13 @@ # Handling Operating System Variation -When dealing with platform libraries, it is often necessary to provide special cases for various -platforms. The variable `Sys.KERNEL` can be used to write these special cases. There are several -functions in the `Sys` module intended to make this easier: `isunix`, `islinux`, `isapple`, -`isbsd`, and `iswindows`. These may be used as follows: +When writing cross-platform applications or libraries, it is often necessary to allow for +differences between operating systems. The variable `Sys.KERNEL` can be used to handle such +cases. There are several functions in the `Sys` module intended to make this easier: +`isunix`, `islinux`, `isapple`, `isbsd`, and `iswindows`. These may be used as follows: ```julia if Sys.iswindows() - some_complicated_thing(a) + windows_specific_thing(a) end ``` @@ -25,9 +25,9 @@ Complex blocks: ```julia @static if Sys.islinux() - some_complicated_thing(a) + linux_specific_thing(a) else - some_different_thing(a) + generic_thing(a) end ``` @@ -37,3 +37,4 @@ each level (parentheses optional, but recommended for readability): ```julia @static Sys.iswindows() ? :a : (@static Sys.isapple() ? :b : :c) ``` + diff --git a/codex/manual/metaprogramming.md b/codex/manual/metaprogramming.md index 4d07565..917102c 100644 --- a/codex/manual/metaprogramming.md +++ b/codex/manual/metaprogramming.md @@ -89,7 +89,7 @@ julia> ex3 = Meta.parse("(4 + 4) / 2") :((4 + 4) / 2) ``` -Another way to view expressions is with Meta.show_sexpr, which displays the [S-expression](https://en.wikipedia.org/wiki/S-expression) +Another way to view expressions is with `Meta.show_sexpr`, which displays the [S-expression](https://en.wikipedia.org/wiki/S-expression) form of a given `Expr`, which may look very familiar to users of Lisp. Here's an example illustrating the display on a nested `Expr`: @@ -1070,7 +1070,7 @@ syntax tree. ## Generated functions -A very special macro is `@generated`, which allows you to define so-called *generated functions*. +A very special macro is [`@generated`](@ref), which allows you to define so-called *generated functions*. These have the capability to generate specialized code depending on the types of their arguments with more flexibility and/or less code than what can be achieved with multiple dispatch. While macros work with expressions at parse time and cannot access the types of their inputs, a generated @@ -1269,7 +1269,7 @@ run during inference, it must respect all of the limitations of that code. Some operations that should not be attempted include: 1. Caching of native pointers. -2. Interacting with the contents or methods of Core.Compiler in any way. +2. Interacting with the contents or methods of `Core.Compiler` in any way. 3. Observing any mutable state. * Inference on the generated function may be run at *any* time, including while your code is attempting diff --git a/codex/manual/missing.md b/codex/manual/missing.md index 67b349f..647434f 100644 --- a/codex/manual/missing.md +++ b/codex/manual/missing.md @@ -35,7 +35,7 @@ which propagate them (like standard operators). Packages should consider whether it makes sense to propagate missing values when defining new functions, and define methods appropriately if that is the case. Passing a `missing` value to a function for which no method accepting arguments of type `Missing` is defined -throws a `MethodError`, just like for any other type. +throws a [`MethodError`](@ref), just like for any other type. ## Equality and Comparison Operators @@ -191,7 +191,7 @@ Control flow operators including [`if`](@ref), [`while`](@ref) and the [ternary operator](@ref man-conditional-evaluation) `x ? y : z` do not allow for missing values. This is because of the uncertainty about whether the actual value would be `true` or `false` if we could observe it, -which implies that we do not know how the program should behave. A `TypeError` +which implies that we do not know how the program should behave. A [`TypeError`](@ref) is thrown as soon as a `missing` value is encountered in this context ```jldoctest julia> if missing diff --git a/codex/manual/noteworthy-differences.md b/codex/manual/noteworthy-differences.md index ad0ef24..fb3d166 100644 --- a/codex/manual/noteworthy-differences.md +++ b/codex/manual/noteworthy-differences.md @@ -182,7 +182,8 @@ For users coming to Julia from R, these are some noteworthy differences: * Julia does not support the `NULL` type. The closest equivalent is [`nothing`](@ref), but it behaves like a scalar value rather than like a list. Use `x === nothing` instead of `is.null(x)`. * In Julia, missing values are represented by the [`missing`](@ref) object rather than by `NA`. - Use [`ismissing(x)`](@ref) instead of `isna(x)`. The [`skipmissing`](@ref) function is generally + Use [`ismissing(x)`](@ref) (or `ismissing.(x)` for element-wise operation on vectors) instead of + `is.na(x)`. The [`skipmissing`](@ref) function is generally used instead of `na.rm=TRUE` (though in some particular cases functions take a `skipmissing` argument). * Julia lacks the equivalent of R's `assign` or `get`. diff --git a/codex/manual/parallel-computing.md b/codex/manual/parallel-computing.md index 2dbbd6b..b2a9628 100644 --- a/codex/manual/parallel-computing.md +++ b/codex/manual/parallel-computing.md @@ -1727,7 +1727,7 @@ function power_method(M, v) end ``` -`power_method` repeteavely creates a new vector and normalizes it. We have not specified any type signature in +`power_method` repeatedly creates a new vector and normalizes it. We have not specified any type signature in function declaration, let's see if it works with the aforementioned datatypes: ```julia-repl diff --git a/codex/stdlib/UUIDs.md b/codex/stdlib/UUIDs.md index 3b936e7..4c2f6a5 100644 --- a/codex/stdlib/UUIDs.md +++ b/codex/stdlib/UUIDs.md @@ -7,6 +7,7 @@ DocTestSetup = :(using UUIDs, Random) ```@docs UUIDs.uuid1 UUIDs.uuid4 +UUIDs.uuid5 UUIDs.uuid_version ``` diff --git a/src/base/base.md b/src/base/base.md index 8763167..c885e14 100644 --- a/src/base/base.md +++ b/src/base/base.md @@ -51,7 +51,7 @@ However, you can create variables with names: Finally `where` is parsed as an infix operator for writing parametric method and type definitions. Also `in` and `isa` are parsed as infix operators. -Creation of variable named `where`, `is` or `isa` is allowed though. +Creation of variable named `where`, `in` or `isa` is allowed though. ```@docs module diff --git a/src/base/file.md b/src/base/file.md index d2f57e2..9e0ac19 100644 --- a/src/base/file.md +++ b/src/base/file.md @@ -62,4 +62,5 @@ Base.Filesystem.expanduser Base.Filesystem.splitdir Base.Filesystem.splitdrive Base.Filesystem.splitext +Base.Filesystem.splitpath ``` diff --git a/src/manual/arrays.md b/src/manual/arrays.md index 071ec87..294ae05 100644 --- a/src/manual/arrays.md +++ b/src/manual/arrays.md @@ -8,7 +8,7 @@ Julia는 배열을 특별하게 취급하지는 않는다. 커스텀 배열 타입을 구현하는 것의 세부사항은 [manual section on the AbstractArray interface](@ref man-interface-array) 를 참조하기 바란다. 배열은 다차원 그리드에 저장된 객체들의 모음이다. -가장 일반적인 경우, 배열은 `Any` 타입의 객체들을 담을 수 있다. +가장 일반적인 경우, 배열은 [`Any`](@ref) 타입의 객체들을 담을 수 있다. 대부분의 계산 목적을 위해서는, 배열은 [`Float64`](@ref) 혹은 [`Int32`](@ref)와 같이 더 구체적인 타입의 객체를 담는 것이 좋다. 다른 많은 기술 계산 언어에서는 성능을 위해 프로그램을 벡터화된 스타일로 작성할 필요가 있지만, Julia에서는 일반적으로 그럴 필요가 없다. @@ -21,7 +21,7 @@ sharing](https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing) while this prevents accidental modification by callees of a value in the caller, it makes avoiding unwanted copying of arrays difficult. By convention, a function name ending with a `!` indicates that it will mutate or destroy the -value of one or more of its arguments (see, for example, [`sort`](@ref) and [`sort!`](@ref). +value of one or more of its arguments (see, for example, [`sort`](@ref) and [`sort!`](@ref)). Callees must make explicit copies to ensure that they don't modify inputs that they don't intend to change. Many non- mutating functions are implemented by calling a function of the same name with an added `!` at the end on an explicit diff --git a/src/manual/constructors.md b/src/manual/constructors.md index 287ff21..9f41aca 100644 --- a/src/manual/constructors.md +++ b/src/manual/constructors.md @@ -22,7 +22,7 @@ julia> foo.baz ``` For many types, forming new objects by binding their field values together is all that is ever -needed to create instances. There are, however, cases where more functionality is required when +needed to create instances. However, in some cases more functionality is required when creating composite objects. Sometimes invariants must be enforced, either by checking arguments or by transforming them. [Recursive data structures](https://en.wikipedia.org/wiki/Recursion_%28computer_science%29#Recursive_data_structures_.28structural_recursion.29), especially those that may be self-referential, often cannot be constructed cleanly without first @@ -34,7 +34,7 @@ addresses all of these cases and more. [^1]: Nomenclature: while the term "constructor" generally refers to the entire function which constructs objects of a type, it is common to abuse terminology slightly and refer to specific constructor - methods as "constructors". In such situations, it is generally clear from context that the term + methods as "constructors". In such situations, it is generally clear from the context that the term is used to mean "constructor method" rather than "constructor function", especially as it is often used in the sense of singling out a particular method of the constructor from all of the others. @@ -77,7 +77,7 @@ While outer constructor methods succeed in addressing the problem of providing a methods for constructing objects, they fail to address the other two use cases mentioned in the introduction of this chapter: enforcing invariants, and allowing construction of self-referential objects. For these problems, one needs *inner* constructor methods. An inner constructor method -is much like an outer constructor method, with two differences: +is like an outer constructor method, except for two differences: 1. It is declared inside the block of a type declaration, rather than outside of it like normal methods. 2. It has access to a special locally existent function called [`new`](@ref) that creates objects of the @@ -110,7 +110,7 @@ Stacktrace: ``` If the type were declared `mutable`, you could reach in and directly change the field values to -violate this invariant, but messing around with an object's internals uninvited is considered poor form. +violate this invariant. Of course, messing around with an object's internals uninvited is bad practice. You (or someone else) can also provide additional outer constructor methods at any later point, but once a type is declared, there is no way to add more inner constructor methods. Since outer constructor methods can only create objects by calling other constructor methods, ultimately, some inner constructor @@ -160,7 +160,7 @@ julia> T2(1.0) T2(1) ``` -It is considered good form to provide as few inner constructor methods as possible: only those +It is good practice to provide as few inner constructor methods as possible: only those taking all arguments explicitly and enforcing essential error checking and transformation. Additional convenience constructor methods, supplying default values or auxiliary transformations, should be provided as outer constructors that call the inner constructors to do the heavy lifting. This @@ -194,8 +194,8 @@ value for the `obj` field of another instance, such as, for example, itself. To allow for the creation of incompletely initialized objects, Julia allows the [`new`](@ref) function to be called with fewer than the number of fields that the type has, returning an object with the unspecified fields uninitialized. The inner constructor method can then use the incomplete -object, finishing its initialization before returning it. Here, for example, we take another crack -at defining the `SelfReferential` type, with a zero-argument inner constructor returning instances +object, finishing its initialization before returning it. Here, for example, is another attempt +at defining the `SelfReferential` type, this time using a zero-argument inner constructor returning instances having `obj` fields pointing to themselves: ```jldoctest selfrefer2 @@ -222,11 +222,11 @@ true ``` Although it is generally a good idea to return a fully initialized object from an inner constructor, -incompletely initialized objects can be returned: +it is possible to return incompletely initialized objects: ```jldoctest incomplete julia> mutable struct Incomplete - xx + data Incomplete() = new() end @@ -237,7 +237,7 @@ While you are allowed to create objects with uninitialized fields, any access to reference is an immediate error: ```jldoctest incomplete -julia> z.xx +julia> z.data ERROR: UndefRefError: access to undefined reference ``` @@ -263,13 +263,13 @@ You can pass incomplete objects to other functions from inner constructors to de ```jldoctest julia> mutable struct Lazy - xx + data Lazy(v) = complete_me(new(), v) end ``` As with incomplete objects returned from constructors, if `complete_me` or any of its callees -try to access the `xx` field of the `Lazy` object before it has been initialized, an error will +try to access the `data` field of the `Lazy` object before it has been initialized, an error will be thrown immediately. ## Parametric Constructors @@ -513,8 +513,8 @@ it is short, self-contained, and implements an entire basic Julia type. As we have seen, a typical parametric type has inner constructors that are called when type parameters are known; e.g. they apply to `Point{Int}` but not to `Point`. Optionally, outer constructors that determine type parameters automatically can be added, for example constructing a `Point{Int}` -from the call `Point(1,2)`. Outer constructors call inner constructors to do the core work of -making an instance. However, in some cases one would rather not provide inner constructors, so +from the call `Point(1,2)`. Outer constructors call inner constructors to actually +make instances. However, in some cases one would rather not provide inner constructors, so that specific type parameters cannot be requested manually. For example, say we define a type that stores a vector along with an accurate representation of diff --git a/src/manual/handling-operating-system-variation.md b/src/manual/handling-operating-system-variation.md index 46ee1ae..155d303 100644 --- a/src/manual/handling-operating-system-variation.md +++ b/src/manual/handling-operating-system-variation.md @@ -1,13 +1,13 @@ # Handling Operating System Variation -When dealing with platform libraries, it is often necessary to provide special cases for various -platforms. The variable `Sys.KERNEL` can be used to write these special cases. There are several -functions in the `Sys` module intended to make this easier: `isunix`, `islinux`, `isapple`, -`isbsd`, and `iswindows`. These may be used as follows: +When writing cross-platform applications or libraries, it is often necessary to allow for +differences between operating systems. The variable `Sys.KERNEL` can be used to handle such +cases. There are several functions in the `Sys` module intended to make this easier: +`isunix`, `islinux`, `isapple`, `isbsd`, and `iswindows`. These may be used as follows: ```julia if Sys.iswindows() - some_complicated_thing(a) + windows_specific_thing(a) end ``` @@ -25,9 +25,9 @@ Complex blocks: ```julia @static if Sys.islinux() - some_complicated_thing(a) + linux_specific_thing(a) else - some_different_thing(a) + generic_thing(a) end ``` @@ -37,3 +37,4 @@ each level (parentheses optional, but recommended for readability): ```julia @static Sys.iswindows() ? :a : (@static Sys.isapple() ? :b : :c) ``` + diff --git a/src/manual/metaprogramming.md b/src/manual/metaprogramming.md index 4d07565..917102c 100644 --- a/src/manual/metaprogramming.md +++ b/src/manual/metaprogramming.md @@ -89,7 +89,7 @@ julia> ex3 = Meta.parse("(4 + 4) / 2") :((4 + 4) / 2) ``` -Another way to view expressions is with Meta.show_sexpr, which displays the [S-expression](https://en.wikipedia.org/wiki/S-expression) +Another way to view expressions is with `Meta.show_sexpr`, which displays the [S-expression](https://en.wikipedia.org/wiki/S-expression) form of a given `Expr`, which may look very familiar to users of Lisp. Here's an example illustrating the display on a nested `Expr`: @@ -1070,7 +1070,7 @@ syntax tree. ## Generated functions -A very special macro is `@generated`, which allows you to define so-called *generated functions*. +A very special macro is [`@generated`](@ref), which allows you to define so-called *generated functions*. These have the capability to generate specialized code depending on the types of their arguments with more flexibility and/or less code than what can be achieved with multiple dispatch. While macros work with expressions at parse time and cannot access the types of their inputs, a generated @@ -1269,7 +1269,7 @@ run during inference, it must respect all of the limitations of that code. Some operations that should not be attempted include: 1. Caching of native pointers. -2. Interacting with the contents or methods of Core.Compiler in any way. +2. Interacting with the contents or methods of `Core.Compiler` in any way. 3. Observing any mutable state. * Inference on the generated function may be run at *any* time, including while your code is attempting diff --git a/src/manual/missing.md b/src/manual/missing.md index 67b349f..647434f 100644 --- a/src/manual/missing.md +++ b/src/manual/missing.md @@ -35,7 +35,7 @@ which propagate them (like standard operators). Packages should consider whether it makes sense to propagate missing values when defining new functions, and define methods appropriately if that is the case. Passing a `missing` value to a function for which no method accepting arguments of type `Missing` is defined -throws a `MethodError`, just like for any other type. +throws a [`MethodError`](@ref), just like for any other type. ## Equality and Comparison Operators @@ -191,7 +191,7 @@ Control flow operators including [`if`](@ref), [`while`](@ref) and the [ternary operator](@ref man-conditional-evaluation) `x ? y : z` do not allow for missing values. This is because of the uncertainty about whether the actual value would be `true` or `false` if we could observe it, -which implies that we do not know how the program should behave. A `TypeError` +which implies that we do not know how the program should behave. A [`TypeError`](@ref) is thrown as soon as a `missing` value is encountered in this context ```jldoctest julia> if missing diff --git a/src/manual/noteworthy-differences.md b/src/manual/noteworthy-differences.md index ad0ef24..fb3d166 100644 --- a/src/manual/noteworthy-differences.md +++ b/src/manual/noteworthy-differences.md @@ -182,7 +182,8 @@ For users coming to Julia from R, these are some noteworthy differences: * Julia does not support the `NULL` type. The closest equivalent is [`nothing`](@ref), but it behaves like a scalar value rather than like a list. Use `x === nothing` instead of `is.null(x)`. * In Julia, missing values are represented by the [`missing`](@ref) object rather than by `NA`. - Use [`ismissing(x)`](@ref) instead of `isna(x)`. The [`skipmissing`](@ref) function is generally + Use [`ismissing(x)`](@ref) (or `ismissing.(x)` for element-wise operation on vectors) instead of + `is.na(x)`. The [`skipmissing`](@ref) function is generally used instead of `na.rm=TRUE` (though in some particular cases functions take a `skipmissing` argument). * Julia lacks the equivalent of R's `assign` or `get`. diff --git a/src/manual/parallel-computing.md b/src/manual/parallel-computing.md index 2dbbd6b..b2a9628 100644 --- a/src/manual/parallel-computing.md +++ b/src/manual/parallel-computing.md @@ -1727,7 +1727,7 @@ function power_method(M, v) end ``` -`power_method` repeteavely creates a new vector and normalizes it. We have not specified any type signature in +`power_method` repeatedly creates a new vector and normalizes it. We have not specified any type signature in function declaration, let's see if it works with the aforementioned datatypes: ```julia-repl diff --git a/src/stdlib/UUIDs.md b/src/stdlib/UUIDs.md index 3b936e7..4c2f6a5 100644 --- a/src/stdlib/UUIDs.md +++ b/src/stdlib/UUIDs.md @@ -7,6 +7,7 @@ DocTestSetup = :(using UUIDs, Random) ```@docs UUIDs.uuid1 UUIDs.uuid4 +UUIDs.uuid5 UUIDs.uuid_version ``` From b63cd9347866e81b81e6adbb3963344a9b57f22e Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Thu, 4 Oct 2018 08:56:45 +0900 Subject: [PATCH 062/153] update Julia Commit 8b5f5da736 --- codex/base/base.md | 4 +- codex/manual/arrays.md | 46 +++++++++++----------- codex/manual/calling-c-and-fortran-code.md | 7 ++-- codex/manual/conversion-and-promotion.md | 2 +- codex/manual/faq.md | 37 +++++++++++++++++ codex/manual/getting-started.md | 2 + codex/manual/types.md | 6 +-- codex/manual/variables-and-scoping.md | 37 ++++++++--------- src/base/base.md | 4 +- src/manual/arrays.md | 42 ++++++++++---------- src/manual/calling-c-and-fortran-code.md | 7 ++-- src/manual/conversion-and-promotion.md | 2 +- src/manual/faq.md | 37 +++++++++++++++++ src/manual/getting-started.md | 2 + src/manual/types.md | 6 +-- src/manual/variables-and-scoping.md | 37 ++++++++--------- 16 files changed, 180 insertions(+), 98 deletions(-) diff --git a/codex/base/base.md b/codex/base/base.md index c885e14..0567e93 100644 --- a/codex/base/base.md +++ b/codex/base/base.md @@ -44,14 +44,14 @@ This is the list of reserved keywords in Julia: `return`, `struct`, `true`, `try`, `using`, `while`. Those keywords are not allowed to be used as variable names. -The following two word sequences are reserved: +The following two-word sequences are reserved: `abstract type`, `mutable struct`, `primitive type`. However, you can create variables with names: `abstract`, `mutable`, `primitive` and `type`. Finally `where` is parsed as an infix operator for writing parametric method and type definitions. Also `in` and `isa` are parsed as infix operators. -Creation of variable named `where`, `in` or `isa` is allowed though. +Creation of a variable named `where`, `in` or `isa` is allowed though. ```@docs module diff --git a/codex/manual/arrays.md b/codex/manual/arrays.md index 73241e3..6119c49 100644 --- a/codex/manual/arrays.md +++ b/codex/manual/arrays.md @@ -23,7 +23,7 @@ sharing](https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing) while this prevents accidental modification by callees of a value in the caller, it makes avoiding unwanted copying of arrays difficult. By convention, a function name ending with a `!` indicates that it will mutate or destroy the -value of one or more of its arguments (see, for example, [`sort`](@ref) and [`sort!`](@ref)). +value of one or more of its arguments (compare, for example, [`sort`](@ref) and [`sort!`](@ref)). Callees must make explicit copies to ensure that they don't modify inputs that they don't intend to change. Many non- mutating functions are implemented by calling a function of the same name with an added `!` at the end on an explicit @@ -73,28 +73,28 @@ omitted it will default to [`Float64`](@ref). [^1]: *iid*, independently and identically distributed. -The syntax `[A, B, C, ...]` constructs a 1-d array (vector) of its arguments. If all +The syntax `[A, B, C, ...]` constructs a 1-d array (i.e., a vector) of its arguments. If all arguments have a common [promotion type](@ref conversion-and-promotion) then they get converted to that type using [`convert`](@ref). To see the various ways we can pass dimensions to these constructors, consider the following examples: ```jldoctest -julia> zeros(Int8, 2, 2) -2×2 Array{Int8,2}: - 0 0 - 0 0 +julia> zeros(Int8, 2, 3) +2×3 Array{Int8,2}: + 0 0 0 + 0 0 0 -julia> zeros(Int8, (2, 2)) -2×2 Array{Int8,2}: - 0 0 - 0 0 +julia> zeros(Int8, (2, 3)) +2×3 Array{Int8,2}: + 0 0 0 + 0 0 0 -julia> zeros((2, 2)) -2×2 Array{Float64,2}: - 0.0 0.0 - 0.0 0.0 +julia> zeros((2, 3)) +2×3 Array{Float64,2}: + 0.0 0.0 0.0 + 0.0 0.0 0.0 ``` -Here, `(2, 2)` is a [`Tuple`](@ref). +Here, `(2, 3)` is a [`Tuple`](@ref). ## Concatenation @@ -244,11 +244,11 @@ julia> map(tuple, (1/(i+j) for i=1:2, j=1:2), [1 3; 2 4]) (0.333333, 2) (0.25, 4) ``` -Generators are implemented via inner functions. As in other cases of -inner functions in the language, variables from the enclosing scope can be +Generators are implemented via inner functions. Just like +inner functions used elsewhere in the language, variables from the enclosing scope can be "captured" in the inner function. For example, `sum(p[i] - q[i] for i=1:n)` captures the three variables `p`, `q` and `n` from the enclosing scope. -Captured variables can present performance challenges described in +Captured variables can present performance challenges; see [performance tips](@ref man-performance-tips). @@ -404,7 +404,7 @@ the insertion point of a value not found in a sorted array: ```jldoctest julia> a = [1,2,5,6,7]; -julia> searchsorted(a, 3) +julia> searchsorted(a, 4) 3:2 ``` @@ -538,7 +538,7 @@ true Considered alone, this may seem relatively trivial; `CartesianIndex` simply gathers multiple integers together into one object that represents a single multidimensional index. When combined with other indexing forms and iterators -that yield `CartesianIndex`es, however, this can lead directly to very elegant +that yield `CartesianIndex`es, however, this can produce very elegant and efficient code. See [Iteration](@ref) below, and for some more advanced examples, see [this blog post on multidimensional algorithms and iteration](https://julialang.org/blog/2016/02/iteration). @@ -725,7 +725,7 @@ julia> repeat(a,1,3)+A 1.56851 1.86401 1.67846 ``` -This is wasteful when dimensions get large, so Julia offers [`broadcast`](@ref), which expands +This is wasteful when dimensions get large, so Julia provides [`broadcast`](@ref), which expands singleton dimensions in array arguments to match the corresponding dimension in the other array without using extra memory, and applies the given function elementwise: @@ -748,7 +748,7 @@ julia> broadcast(+, a, b) [Dotted operators](@ref man-dot-operators) such as `.+` and `.*` are equivalent to `broadcast` calls (except that they fuse, as described below). There is also a [`broadcast!`](@ref) function to specify an explicit destination (which can also -be accessed in a fusing fashion by `.=` assignment). Moreover, `f.(args...)` +be accessed in a fusing fashion by `.=` assignment). In fact, `f.(args...)` is equivalent to `broadcast(f, args...)`, providing a convenient syntax to broadcast any function ([dot syntax](@ref man-vectorized)). Nested "dot calls" `f.(...)` (including calls to `.+` etcetera) [automatically fuse](@ref man-dot-operators) into a single `broadcast` call. @@ -799,7 +799,7 @@ the length of the tuple returned by [`size`](@ref). For more details on defining `DenseArray` is an abstract subtype of `AbstractArray` intended to include all arrays where elements are stored contiguously in column-major order (see additional notes in [Performance Tips](@ref man-performance-tips)). The [`Array`](@ref) type is a specific instance -of `DenseArray` [`Vector`](@ref) and [`Matrix`](@ref) are aliases for the 1-d and 2-d cases. +of `DenseArray`; [`Vector`](@ref) and [`Matrix`](@ref) are aliases for the 1-d and 2-d cases. Very few operations are implemented specifically for `Array` beyond those that are required for all `AbstractArrays`s; much of the array library is implemented in a generic manner that allows all custom arrays to behave similarly. diff --git a/codex/manual/calling-c-and-fortran-code.md b/codex/manual/calling-c-and-fortran-code.md index 6155952..8c35495 100644 --- a/codex/manual/calling-c-and-fortran-code.md +++ b/codex/manual/calling-c-and-fortran-code.md @@ -277,7 +277,7 @@ First, a review of some relevant Julia type terminology: | Syntax / Keyword | Example | Description | |:----------------------------- |:------------------------------------------- |:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `mutable struct` | `String` | "Leaf Type" :: A group of related data that includes a type-tag, is managed by the Julia GC, and is defined by object-identity. The type parameters of a leaf type must be fully defined (no `TypeVars` are allowed) in order for the instance to be constructed. | +| `mutable struct` | `BitSet` | "Leaf Type" :: A group of related data that includes a type-tag, is managed by the Julia GC, and is defined by object-identity. The type parameters of a leaf type must be fully defined (no `TypeVars` are allowed) in order for the instance to be constructed. | | `abstract type` | `Any`, `AbstractArray{T, N}`, `Complex{T}` | "Super Type" :: A super-type (not a leaf-type) that cannot be instantiated, but can be used to describe a group of types. | | `T{A}` | `Vector{Int}` | "Type Parameter" :: A specialization of a type (typically used for dispatch or storage optimization). | | | | "TypeVar" :: The `T` in the type parameter declaration is referred to as a TypeVar (short for type variable). | @@ -486,14 +486,15 @@ the Julia field to be only of that type. Arrays of parameters can be expressed with `NTuple`: -``` in C: +```c struct B { int A[3]; }; b_a_2 = B.A[2]; - +``` in Julia: +```julia struct B A::NTuple{3, CInt} end diff --git a/codex/manual/conversion-and-promotion.md b/codex/manual/conversion-and-promotion.md index 7345334..a193100 100644 --- a/codex/manual/conversion-and-promotion.md +++ b/codex/manual/conversion-and-promotion.md @@ -300,7 +300,7 @@ be promoted to 64-bit floating-point. The promotion type does not need to be one types, however; the following promotion rules both occur in Julia Base: ```julia -promote_rule(::Type{UInt8}, ::Type{Int8}) = Int +promote_rule(::Type{BigInt}, ::Type{Float64}) = BigFloat promote_rule(::Type{BigInt}, ::Type{Int8}) = BigInt ``` diff --git a/codex/manual/faq.md b/codex/manual/faq.md index 6301192..5b4fa2f 100644 --- a/codex/manual/faq.md +++ b/codex/manual/faq.md @@ -41,12 +41,49 @@ obj3 = MyModule.someotherfunction(obj2, c) ... ``` +## [Scripting](@id man-scripting) + ### How do I check if the current file is being run as the main script? When a file is run as the main script using `julia file.jl` one might want to activate extra functionality like command line argument handling. A way to determine that a file is run in this fashion is to check if `abspath(PROGRAM_FILE) == @__FILE__` is `true`. +### How do I catch CTRL-C in a script? + +Running a Julia script using `julia file.jl` does not throw +[`InterruptException`](@ref) when you try to terminate it with CTRL-C +(SIGINT). To run a certain code before terminating a Julia script, +which may or may not be caused by CTRL-C, use [`atexit`](@ref). +Alternatively, you can use `julia -e 'include(popfirst!(ARGS))' +file.jl` to execute a script while being able to catch +`InterruptException` in the [`try`](@ref) block. + +### How do I pass options to `julia` using `#!/usr/bin/env`? + +Passing options to `julia` in so-called shebang by, e.g., +`#!/usr/bin/env julia --startup-file=no` may not work in some +platforms such as Linux. This is because argument parsing in shebang +is platform-dependent and not well-specified. In a Unix-like +environment, a reliable way to pass options to `julia` in an +executable script would be to start the script as a `bash` script and +use `exec` to replace the process to `julia`: + +```julia +#!/bin/bash +#= +exec julia --color=yes --startup-file=no -e 'include(popfirst!(ARGS))' \ + "${BASH_SOURCE[0]}" "$@" +=# + +@show ARGS # put any Julia code here +``` + +In the example above, the code between `#=` and `=#` is run as a `bash` +script. Julia ignores this part since it is a multi-line comment for +Julia. The Julia code after `=#` is ignored by `bash` since it stops +parsing the file once it reaches to the `exec` statement. + ## Functions ### I passed an argument `x` to a function, modified it inside that function, but on the outside, the variable `x` is still unchanged. Why? diff --git a/codex/manual/getting-started.md b/codex/manual/getting-started.md index b648cf8..530fe44 100644 --- a/codex/manual/getting-started.md +++ b/codex/manual/getting-started.md @@ -62,6 +62,8 @@ The `--` delimiter can be used to separate command-line arguments intended for t $ julia --color=yes -O -- foo.jl arg1 arg2.. ``` +See also [Scripting](@ref man-scripting) for more information on writing Julia scripts. + Julia can be started in parallel mode with either the `-p` or the `--machine-file` options. `-p n` will launch an additional `n` worker processes, while `--machine-file file` will launch a worker for each line in file `file`. The machines defined in `file` must be accessible via a password-less diff --git a/codex/manual/types.md b/codex/manual/types.md index 5f307ed..cd0fdd0 100644 --- a/codex/manual/types.md +++ b/codex/manual/types.md @@ -1123,9 +1123,9 @@ Of course, this depends on what `Int` is aliased to -- but that is predefined to type -- either [`Int32`](@ref) or [`Int64`](@ref). (Note that unlike `Int`, `Float` does not exist as a type alias for a specific sized -[`AbstractFloat`](@ref). Unlike with integer registers, the floating point register sizes -are specified by the IEEE-754 standard. Whereas the size of `Int` reflects the size of a -native pointer on that machine.) +[`AbstractFloat`](@ref). Unlike with integer registers, where the size of `Int` +reflects the size of a native pointer on that machine, the floating point register sizes +are specified by the IEEE-754 standard.) ## Operations on Types diff --git a/codex/manual/variables-and-scoping.md b/codex/manual/variables-and-scoping.md index 82d84f2..40bed25 100644 --- a/codex/manual/variables-and-scoping.md +++ b/codex/manual/variables-and-scoping.md @@ -2,7 +2,7 @@ The *scope* of a variable is the region of code within which a variable is visible. Variable scoping helps avoid variable naming conflicts. The concept is intuitive: two functions can both have arguments -called `x` without the two `x`'s referring to the same thing. Similarly there are many other cases +called `x` without the two `x`'s referring to the same thing. Similarly, there are many other cases where different blocks of code can use the same name without referring to the same thing. The rules for when the same variable name does or doesn't refer to the same thing are called scope rules; this section spells them out in detail. @@ -10,7 +10,7 @@ rules; this section spells them out in detail. Certain constructs in the language introduce *scope blocks*, which are regions of code that are eligible to be the scope of some set of variables. The scope of a variable cannot be an arbitrary set of source lines; instead, it will always line up with one of these blocks. There are two -main types of scopes in Julia, *global scope* and *local scope*, the latter can be nested. The +main types of scopes in Julia, *global scope* and *local scope*. The latter can be nested. The constructs introducing scope blocks are: # [](@id man-scope-table) @@ -19,19 +19,19 @@ constructs introducing scope blocks are: - global scope - + module, baremodule + + [`module`](@ref), [`baremodule`](@ref) + at interactive prompt (REPL) - local scope (don't allow nesting) - + (mutable) struct, macro + + (mutable) [`struct`](@ref), [`macro`](@ref) * Scope blocks which may nest anywhere (in global or local scope): - local scope - + for, while, try-catch-finally, let + + [`for`](@ref), [`while`](@ref), [`try-catch-finally`](@ref try), [`let`](@ref) + functions (either syntax, anonymous & do-blocks) @@ -110,8 +110,8 @@ A new local scope is introduced by most code blocks (see above [table](@ref man-scope-table) for a complete list). A local scope inherits all the variables from a parent local scope, both for reading and writing. -Additionally, the local scope inherits all globals that are assigned -to in its parent global scope block (if it is surrounded by a global `if` or `begin` scope). +Additionally, the local scope inherits all global variables that are assigned +in its parent global scope block (if it is surrounded by a global `if` or `begin` scope). Unlike global scopes, local scopes are not namespaces, thus variables in an inner scope cannot be retrieved from the parent scope through some sort of qualified access. @@ -130,10 +130,11 @@ julia> z ERROR: UndefVarError: z not defined ``` -(Note, in this and all following examples it is assumed that their top-level is a global scope -with a clean workspace, for instance a newly started REPL.) +!!! note + In this and all following examples it is assumed that their top-level is a global scope + with a clean workspace, for instance a newly started REPL. -Inside a local scope a variable can be forced to be a new local variable using the `local` keyword: +Inside a local scope a variable can be forced to be a new local variable using the [`local`](@ref) keyword: ```jldoctest julia> x = 0; @@ -147,7 +148,7 @@ julia> x 0 ``` -Inside a local scope a global variable can be assigned to by using the keyword `global`: +Inside a local scope a global variable can be assigned to by using the keyword [`global`](@ref): ```jldoctest julia> for i = 1:10 @@ -184,7 +185,7 @@ global scope block unless: * an assignment would result in a modified *global* variable, or * a variable is specifically marked with the keyword `local`. -Thus global variables are only inherited for reading but not for writing: +Thus global variables are only inherited for reading, not for writing: ```jldoctest julia> x, y = 1, 2; @@ -208,7 +209,7 @@ An explicit `global` is needed to assign to a global variable: to be a programming best-practice. One reason for this is that remotely changing the state of global variables in other modules should be done with care as it makes the local behavior of the program hard to reason about. - This is why the scope blocks that introduce local scope require the ``global`` + This is why the scope blocks that introduce local scope require the `global` keyword to declare the intent to modify a global variable. ```jldoctest @@ -247,7 +248,7 @@ julia> x, y # verify that global x and y are unchanged The reason to allow *modifying local* variables of parent scopes in nested functions is to allow constructing [`closures`](https://en.wikipedia.org/wiki/Closure_%28computer_programming%29) -which have a private state, for instance the ``state`` variable in the +which have a private state, for instance the `state` variable in the following example: ```jldoctest @@ -262,15 +263,15 @@ julia> counter() 2 ``` -See also the closures in the examples in the next two sections. A variable -such as `x` in the first example and `state` in the second that is inherited +See also the closures in the examples in the next two sections. A variable, +such as `x` in the first example and `state` in the second, that is inherited from the enclosing scope by the inner function is sometimes called a *captured* variable. Captured variables can present performance challenges discussed in [performance tips](@ref man-performance-tips). The distinction between inheriting global scope and nesting local scope can lead to some slight differences between functions -defined in local vs. global scopes for variable assignments. +defined in local versus global scopes for variable assignments. Consider the modification of the last example by moving `bar` to the global scope: ```jldoctest @@ -467,7 +468,7 @@ julia> f() ## Constants A common use of variables is giving names to specific, unchanging values. Such variables are only -assigned once. This intent can be conveyed to the compiler using the `const` keyword: +assigned once. This intent can be conveyed to the compiler using the [`const`](@ref) keyword: ```jldoctest julia> const e = 2.71828182845904523536; diff --git a/src/base/base.md b/src/base/base.md index c885e14..0567e93 100644 --- a/src/base/base.md +++ b/src/base/base.md @@ -44,14 +44,14 @@ This is the list of reserved keywords in Julia: `return`, `struct`, `true`, `try`, `using`, `while`. Those keywords are not allowed to be used as variable names. -The following two word sequences are reserved: +The following two-word sequences are reserved: `abstract type`, `mutable struct`, `primitive type`. However, you can create variables with names: `abstract`, `mutable`, `primitive` and `type`. Finally `where` is parsed as an infix operator for writing parametric method and type definitions. Also `in` and `isa` are parsed as infix operators. -Creation of variable named `where`, `in` or `isa` is allowed though. +Creation of a variable named `where`, `in` or `isa` is allowed though. ```@docs module diff --git a/src/manual/arrays.md b/src/manual/arrays.md index 294ae05..ace483f 100644 --- a/src/manual/arrays.md +++ b/src/manual/arrays.md @@ -21,7 +21,7 @@ sharing](https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing) while this prevents accidental modification by callees of a value in the caller, it makes avoiding unwanted copying of arrays difficult. By convention, a function name ending with a `!` indicates that it will mutate or destroy the -value of one or more of its arguments (see, for example, [`sort`](@ref) and [`sort!`](@ref)). +value of one or more of its arguments (compare, for example, [`sort`](@ref) and [`sort!`](@ref)). Callees must make explicit copies to ensure that they don't modify inputs that they don't intend to change. Many non- mutating functions are implemented by calling a function of the same name with an added `!` at the end on an explicit @@ -68,27 +68,27 @@ copy of the input, and returning that copy. | [`fill!(A, x)`](@ref) | 배열 `A` 를 `x` 값으로 채우기 | | [`fill(x, dims...)`](@ref) | `x` 값으로 차 있는 `Array` | -`[A, B, C, ...]` 문법은 주어진 인수들의 일차원 배열(벡터)을 생성한다. +`[A, B, C, ...]` 문법은 주어진 인수들의 일차원 배열(이를테면 벡터)을 생성한다. 만약 모든 인수가 공통의 [확장 타입(promotion type)](@ref conversion-and-promotion)을 가진다면, 이들은 [`convert`](@ref)를 통해 공통의 확장 타입으로 변환된다. To see the various ways we can pass dimensions to these constructors, consider the following examples: ```jldoctest -julia> zeros(Int8, 2, 2) -2×2 Array{Int8,2}: - 0 0 - 0 0 +julia> zeros(Int8, 2, 3) +2×3 Array{Int8,2}: + 0 0 0 + 0 0 0 -julia> zeros(Int8, (2, 2)) -2×2 Array{Int8,2}: - 0 0 - 0 0 +julia> zeros(Int8, (2, 3)) +2×3 Array{Int8,2}: + 0 0 0 + 0 0 0 -julia> zeros((2, 2)) -2×2 Array{Float64,2}: - 0.0 0.0 - 0.0 0.0 +julia> zeros((2, 3)) +2×3 Array{Float64,2}: + 0.0 0.0 0.0 + 0.0 0.0 0.0 ``` -Here, `(2, 2)` is a [`Tuple`](@ref). +Here, `(2, 3)` is a [`Tuple`](@ref). ## 병합(Concatenation) @@ -232,11 +232,11 @@ julia> map(tuple, (1/(i+j) for i=1:2, j=1:2), [1 3; 2 4]) (0.333333, 2) (0.25, 4) ``` -Generators are implemented via inner functions. As in other cases of -inner functions in the language, variables from the enclosing scope can be +Generators are implemented via inner functions. Just like +inner functions used elsewhere in the language, variables from the enclosing scope can be "captured" in the inner function. For example, `sum(p[i] - q[i] for i=1:n)` captures the three variables `p`, `q` and `n` from the enclosing scope. -Captured variables can present performance challenges described in +Captured variables can present performance challenges; see [performance tips](@ref man-performance-tips). 제너레이터와 컴프리헨션에서 `for` 키워드를 여러번 사용함으로써 범위가 앞선 범위에 의존하도록 할 수 있다. @@ -384,7 +384,7 @@ julia> x[1, [2 3; 4 1]] ```jldoctest julia> a = [1,2,5,6,7]; -julia> searchsorted(a, 3) +julia> searchsorted(a, 4) 3:2 ``` @@ -699,7 +699,7 @@ julia> broadcast(+, a, b) `.+` 와 `.*` 같은 [점찍은 연산자](@ref man-dot-operators)는 `broadcast` 호출과 (아래에 설명할 융합을 제외한다면) 동일하다. 또한 명시적으로 목적지를 지정하는 [`broadcast!`](@ref)도 있다. (`.=` 대입을 사용하여 융합하여서도 액세스할 수 있다.) -게다가, `f.(args...)`는 `broadcast(f, args...)`와 동일하며, 어떤 함수든 [점 문법](@ref man-vectorized)을 통하여 편리하게 브로드캐스팅 할 수 있는 문법을 제공한다. +사실, `f.(args...)`는 `broadcast(f, args...)`와 동일하며, 어떤 함수든 [점 문법](@ref man-vectorized)을 통하여 편리하게 브로드캐스팅 할 수 있는 문법을 제공한다. 중첩된 "점 호출" `f.(...)`은 (`.+` 등의 연산자도 포함하여) 하나의 `broadcast` 호출로 [자동으로 융합](@ref man-dot-operators)한다. 추가적으로, [`broadcast`](@ref)는 배열에 국한되지 않고 (함수 문서 참조) 투플 또한 지원하며, @@ -746,7 +746,7 @@ For more details on defining custom `DenseArray` is an abstract subtype of `AbstractArray` intended to include all arrays where elements are stored contiguously in column-major order (see additional notes in [Performance Tips](@ref man-performance-tips)). The [`Array`](@ref) type is a specific instance -of `DenseArray` [`Vector`](@ref) and [`Matrix`](@ref) are aliases for the 1-d and 2-d cases. +of `DenseArray`; [`Vector`](@ref) and [`Matrix`](@ref) are aliases for the 1-d and 2-d cases. Very few operations are implemented specifically for `Array` beyond those that are required for all `AbstractArrays`s; much of the array library is implemented in a generic manner that allows all custom arrays to behave similarly. diff --git a/src/manual/calling-c-and-fortran-code.md b/src/manual/calling-c-and-fortran-code.md index 6155952..8c35495 100644 --- a/src/manual/calling-c-and-fortran-code.md +++ b/src/manual/calling-c-and-fortran-code.md @@ -277,7 +277,7 @@ First, a review of some relevant Julia type terminology: | Syntax / Keyword | Example | Description | |:----------------------------- |:------------------------------------------- |:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `mutable struct` | `String` | "Leaf Type" :: A group of related data that includes a type-tag, is managed by the Julia GC, and is defined by object-identity. The type parameters of a leaf type must be fully defined (no `TypeVars` are allowed) in order for the instance to be constructed. | +| `mutable struct` | `BitSet` | "Leaf Type" :: A group of related data that includes a type-tag, is managed by the Julia GC, and is defined by object-identity. The type parameters of a leaf type must be fully defined (no `TypeVars` are allowed) in order for the instance to be constructed. | | `abstract type` | `Any`, `AbstractArray{T, N}`, `Complex{T}` | "Super Type" :: A super-type (not a leaf-type) that cannot be instantiated, but can be used to describe a group of types. | | `T{A}` | `Vector{Int}` | "Type Parameter" :: A specialization of a type (typically used for dispatch or storage optimization). | | | | "TypeVar" :: The `T` in the type parameter declaration is referred to as a TypeVar (short for type variable). | @@ -486,14 +486,15 @@ the Julia field to be only of that type. Arrays of parameters can be expressed with `NTuple`: -``` in C: +```c struct B { int A[3]; }; b_a_2 = B.A[2]; - +``` in Julia: +```julia struct B A::NTuple{3, CInt} end diff --git a/src/manual/conversion-and-promotion.md b/src/manual/conversion-and-promotion.md index 7345334..a193100 100644 --- a/src/manual/conversion-and-promotion.md +++ b/src/manual/conversion-and-promotion.md @@ -300,7 +300,7 @@ be promoted to 64-bit floating-point. The promotion type does not need to be one types, however; the following promotion rules both occur in Julia Base: ```julia -promote_rule(::Type{UInt8}, ::Type{Int8}) = Int +promote_rule(::Type{BigInt}, ::Type{Float64}) = BigFloat promote_rule(::Type{BigInt}, ::Type{Int8}) = BigInt ``` diff --git a/src/manual/faq.md b/src/manual/faq.md index 6301192..5b4fa2f 100644 --- a/src/manual/faq.md +++ b/src/manual/faq.md @@ -41,12 +41,49 @@ obj3 = MyModule.someotherfunction(obj2, c) ... ``` +## [Scripting](@id man-scripting) + ### How do I check if the current file is being run as the main script? When a file is run as the main script using `julia file.jl` one might want to activate extra functionality like command line argument handling. A way to determine that a file is run in this fashion is to check if `abspath(PROGRAM_FILE) == @__FILE__` is `true`. +### How do I catch CTRL-C in a script? + +Running a Julia script using `julia file.jl` does not throw +[`InterruptException`](@ref) when you try to terminate it with CTRL-C +(SIGINT). To run a certain code before terminating a Julia script, +which may or may not be caused by CTRL-C, use [`atexit`](@ref). +Alternatively, you can use `julia -e 'include(popfirst!(ARGS))' +file.jl` to execute a script while being able to catch +`InterruptException` in the [`try`](@ref) block. + +### How do I pass options to `julia` using `#!/usr/bin/env`? + +Passing options to `julia` in so-called shebang by, e.g., +`#!/usr/bin/env julia --startup-file=no` may not work in some +platforms such as Linux. This is because argument parsing in shebang +is platform-dependent and not well-specified. In a Unix-like +environment, a reliable way to pass options to `julia` in an +executable script would be to start the script as a `bash` script and +use `exec` to replace the process to `julia`: + +```julia +#!/bin/bash +#= +exec julia --color=yes --startup-file=no -e 'include(popfirst!(ARGS))' \ + "${BASH_SOURCE[0]}" "$@" +=# + +@show ARGS # put any Julia code here +``` + +In the example above, the code between `#=` and `=#` is run as a `bash` +script. Julia ignores this part since it is a multi-line comment for +Julia. The Julia code after `=#` is ignored by `bash` since it stops +parsing the file once it reaches to the `exec` statement. + ## Functions ### I passed an argument `x` to a function, modified it inside that function, but on the outside, the variable `x` is still unchanged. Why? diff --git a/src/manual/getting-started.md b/src/manual/getting-started.md index 201f325..9e0d9a1 100644 --- a/src/manual/getting-started.md +++ b/src/manual/getting-started.md @@ -51,6 +51,8 @@ bar $ julia --color=yes -O -- foo.jl arg1 arg2.. ``` +See also [Scripting](@ref man-scripting) for more information on writing Julia scripts. + Julia는 `-p` 옵션이나 `--machine-file` 옵션을 이용하여 병렬 환경에서 실행시킬 수 있다. `-p n` 옵션은 n개의 worker 프로세스를 생성하지만, `--machine-file file` 옵션은 file의 각 행에 지정된 노드마다 worker를 생성한다. `file` 에 지정된 노드(machine)들은 `ssh` 로그인을 통해 패스워드가 필요없이 실행할 수 있어야 하며, Julia는 현재 호스트와 같은 경로에 설치가 되어 있어야 한다. `file` 에 작성되는 노드는 `[count*][user@]host[:port] [bind_addr[:port]]` 와 같은 형식으로 작성한다. `user` 는 현재 user id를 나타내고, `port` 는 기본 ssh port, `count` 는 각 노드당 생성하는 worker의 개수 (기본값 : 1) `bin-to bind_addr[:port]` 은 선택적인 옵션으로 다른 worker들이 현재의 worker로 연결하기 위해 필요한 특정 IP 주소와 포트를 지정한다. 만약 Julia가 실행할 때마다 실행되는 코드가 있다면, 그 코드를 `~/.juliarc.ji` 에 넣으면 된다. diff --git a/src/manual/types.md b/src/manual/types.md index 5f307ed..cd0fdd0 100644 --- a/src/manual/types.md +++ b/src/manual/types.md @@ -1123,9 +1123,9 @@ Of course, this depends on what `Int` is aliased to -- but that is predefined to type -- either [`Int32`](@ref) or [`Int64`](@ref). (Note that unlike `Int`, `Float` does not exist as a type alias for a specific sized -[`AbstractFloat`](@ref). Unlike with integer registers, the floating point register sizes -are specified by the IEEE-754 standard. Whereas the size of `Int` reflects the size of a -native pointer on that machine.) +[`AbstractFloat`](@ref). Unlike with integer registers, where the size of `Int` +reflects the size of a native pointer on that machine, the floating point register sizes +are specified by the IEEE-754 standard.) ## Operations on Types diff --git a/src/manual/variables-and-scoping.md b/src/manual/variables-and-scoping.md index 82d84f2..40bed25 100644 --- a/src/manual/variables-and-scoping.md +++ b/src/manual/variables-and-scoping.md @@ -2,7 +2,7 @@ The *scope* of a variable is the region of code within which a variable is visible. Variable scoping helps avoid variable naming conflicts. The concept is intuitive: two functions can both have arguments -called `x` without the two `x`'s referring to the same thing. Similarly there are many other cases +called `x` without the two `x`'s referring to the same thing. Similarly, there are many other cases where different blocks of code can use the same name without referring to the same thing. The rules for when the same variable name does or doesn't refer to the same thing are called scope rules; this section spells them out in detail. @@ -10,7 +10,7 @@ rules; this section spells them out in detail. Certain constructs in the language introduce *scope blocks*, which are regions of code that are eligible to be the scope of some set of variables. The scope of a variable cannot be an arbitrary set of source lines; instead, it will always line up with one of these blocks. There are two -main types of scopes in Julia, *global scope* and *local scope*, the latter can be nested. The +main types of scopes in Julia, *global scope* and *local scope*. The latter can be nested. The constructs introducing scope blocks are: # [](@id man-scope-table) @@ -19,19 +19,19 @@ constructs introducing scope blocks are: - global scope - + module, baremodule + + [`module`](@ref), [`baremodule`](@ref) + at interactive prompt (REPL) - local scope (don't allow nesting) - + (mutable) struct, macro + + (mutable) [`struct`](@ref), [`macro`](@ref) * Scope blocks which may nest anywhere (in global or local scope): - local scope - + for, while, try-catch-finally, let + + [`for`](@ref), [`while`](@ref), [`try-catch-finally`](@ref try), [`let`](@ref) + functions (either syntax, anonymous & do-blocks) @@ -110,8 +110,8 @@ A new local scope is introduced by most code blocks (see above [table](@ref man-scope-table) for a complete list). A local scope inherits all the variables from a parent local scope, both for reading and writing. -Additionally, the local scope inherits all globals that are assigned -to in its parent global scope block (if it is surrounded by a global `if` or `begin` scope). +Additionally, the local scope inherits all global variables that are assigned +in its parent global scope block (if it is surrounded by a global `if` or `begin` scope). Unlike global scopes, local scopes are not namespaces, thus variables in an inner scope cannot be retrieved from the parent scope through some sort of qualified access. @@ -130,10 +130,11 @@ julia> z ERROR: UndefVarError: z not defined ``` -(Note, in this and all following examples it is assumed that their top-level is a global scope -with a clean workspace, for instance a newly started REPL.) +!!! note + In this and all following examples it is assumed that their top-level is a global scope + with a clean workspace, for instance a newly started REPL. -Inside a local scope a variable can be forced to be a new local variable using the `local` keyword: +Inside a local scope a variable can be forced to be a new local variable using the [`local`](@ref) keyword: ```jldoctest julia> x = 0; @@ -147,7 +148,7 @@ julia> x 0 ``` -Inside a local scope a global variable can be assigned to by using the keyword `global`: +Inside a local scope a global variable can be assigned to by using the keyword [`global`](@ref): ```jldoctest julia> for i = 1:10 @@ -184,7 +185,7 @@ global scope block unless: * an assignment would result in a modified *global* variable, or * a variable is specifically marked with the keyword `local`. -Thus global variables are only inherited for reading but not for writing: +Thus global variables are only inherited for reading, not for writing: ```jldoctest julia> x, y = 1, 2; @@ -208,7 +209,7 @@ An explicit `global` is needed to assign to a global variable: to be a programming best-practice. One reason for this is that remotely changing the state of global variables in other modules should be done with care as it makes the local behavior of the program hard to reason about. - This is why the scope blocks that introduce local scope require the ``global`` + This is why the scope blocks that introduce local scope require the `global` keyword to declare the intent to modify a global variable. ```jldoctest @@ -247,7 +248,7 @@ julia> x, y # verify that global x and y are unchanged The reason to allow *modifying local* variables of parent scopes in nested functions is to allow constructing [`closures`](https://en.wikipedia.org/wiki/Closure_%28computer_programming%29) -which have a private state, for instance the ``state`` variable in the +which have a private state, for instance the `state` variable in the following example: ```jldoctest @@ -262,15 +263,15 @@ julia> counter() 2 ``` -See also the closures in the examples in the next two sections. A variable -such as `x` in the first example and `state` in the second that is inherited +See also the closures in the examples in the next two sections. A variable, +such as `x` in the first example and `state` in the second, that is inherited from the enclosing scope by the inner function is sometimes called a *captured* variable. Captured variables can present performance challenges discussed in [performance tips](@ref man-performance-tips). The distinction between inheriting global scope and nesting local scope can lead to some slight differences between functions -defined in local vs. global scopes for variable assignments. +defined in local versus global scopes for variable assignments. Consider the modification of the last example by moving `bar` to the global scope: ```jldoctest @@ -467,7 +468,7 @@ julia> f() ## Constants A common use of variables is giving names to specific, unchanging values. Such variables are only -assigned once. This intent can be conveyed to the compiler using the `const` keyword: +assigned once. This intent can be conveyed to the compiler using the [`const`](@ref) keyword: ```jldoctest julia> const e = 2.71828182845904523536; From 1ca32e2abcd903ff7690703267894f9b1a5b167d Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Tue, 9 Oct 2018 09:35:30 +0900 Subject: [PATCH 063/153] update Julia Commit 38612e03bc --- codex/devdocs/init.md | 14 +++--- codex/manual/code-loading.md | 50 ++++++++++---------- codex/manual/complex-and-rational-numbers.md | 17 ++++--- codex/manual/parallel-computing.md | 4 +- codex/manual/performance-tips.md | 2 +- src/devdocs/init.md | 14 +++--- src/manual/code-loading.md | 50 ++++++++++---------- src/manual/complex-and-rational-numbers.md | 17 ++++--- src/manual/parallel-computing.md | 4 +- src/manual/performance-tips.md | 2 +- 10 files changed, 86 insertions(+), 88 deletions(-) diff --git a/codex/devdocs/init.md b/codex/devdocs/init.md index 056186d..6264fcf 100644 --- a/codex/devdocs/init.md +++ b/codex/devdocs/init.md @@ -2,7 +2,7 @@ How does the Julia runtime execute `julia -e 'println("Hello World!")'` ? -## main() +## `main()` Execution starts at [`main()` in `ui/repl.c`](https://github.com/JuliaLang/julia/blob/master/ui/repl.c). @@ -16,7 +16,7 @@ or early initialization. Other options are handled later by [`process_options()` `jl_parse_opts()` stores command line options in the [global `jl_options` struct](https://github.com/JuliaLang/julia/blob/master/src/julia.h). -## julia_init() +## `julia_init()` [`julia_init()` in `task.c`](https://github.com/JuliaLang/julia/blob/master/src/task.c) is called by `main()` and calls [`_julia_init()` in `init.c`](https://github.com/JuliaLang/julia/blob/master/src/init.c). @@ -137,7 +137,7 @@ and `main()` calls `true_main(argc, (char**)argv)`. Note: [`jl_restore_system_image()` (and `staticdata.c` in general)](https://github.com/JuliaLang/julia/blob/master/src/staticdata.c) uses the [Legacy `ios.c` library](@ref). -## true_main() +## `true_main()` [`true_main()`](https://github.com/JuliaLang/julia/blob/master/ui/repl.c) loads the contents of `argv[]` into [`Base.ARGS`](@ref). @@ -152,13 +152,13 @@ However, in our example (`julia -e 'println("Hello World!")'`), [`jl_get_global( looks up [`Base._start`](https://github.com/JuliaLang/julia/blob/master/base/client.jl) and [`jl_apply()`](https://github.com/JuliaLang/julia/blob/master/src/julia.h) executes it. -## Base._start +## `Base._start` [`Base._start`](https://github.com/JuliaLang/julia/blob/master/base/client.jl) calls [`Base.process_options`](https://github.com/JuliaLang/julia/blob/master/base/client.jl) which calls [`jl_parse_input_line("println("Hello World!")")`](https://github.com/JuliaLang/julia/blob/master/src/ast.c) to create an expression object and [`Base.eval()`](@ref eval) to execute it. -## Base.eval +## `Base.eval` [`Base.eval()`](@ref eval) was [mapped to `jl_f_top_eval`](https://github.com/JuliaLang/julia/blob/master/src/builtins.c) by `jl_init_primitives()`. @@ -217,13 +217,13 @@ Hello World! Since our example has just one function call, which has done its job of printing "Hello World!", the stack now rapidly unwinds back to `main()`. -## jl_atexit_hook() +## `jl_atexit_hook()` `main()` calls [`jl_atexit_hook()`](https://github.com/JuliaLang/julia/blob/master/src/init.c). This calls `_atexit` for each module, then calls [`jl_gc_run_all_finalizers()`](https://github.com/JuliaLang/julia/blob/master/src/gc.c) and cleans up libuv handles. -## julia_save() +## `julia_save()` Finally, `main()` calls [`julia_save()`](https://github.com/JuliaLang/julia/blob/master/src/init.c), which if requested on the command line, saves the runtime state to a new system image. See [`jl_compile_all()`](https://github.com/JuliaLang/julia/blob/master/src/gf.c) diff --git a/codex/manual/code-loading.md b/codex/manual/code-loading.md index 603e3cc..e88dbdc 100644 --- a/codex/manual/code-loading.md +++ b/codex/manual/code-loading.md @@ -3,12 +3,12 @@ Julia has two mechanisms for loading code: 1. **Code inclusion:** e.g. `include("source.jl")`. Inclusion allows you to split a single program across multiple source files. The expression `include("source.jl")` causes the contents of the file `source.jl` to be evaluated in the global scope of the module where the `include` call occurs. If `include("source.jl")` is called multiple times, `source.jl` is evaluated multiple times. The included path, `source.jl`, is interpreted relative to the file where the `include` call occurs. This makes it simple to relocate a subtree of source files. In the REPL, included paths are interpreted relative to the current working directory, `pwd()`. -2. **Package loading:** e.g. `import X` or `using X`. The import mechanism allows you to load a package—i.e. an independent, reusable collection of Julia code, wrapped in a module—and makes the resulting module available by the name `X` inside of the importing module. If the same `X` package is imported multiple times in the same Julia session, it is only loaded the first time—on subsequent imports, the importing module gets a reference to the same module. It should be noted, however, that `import X` can load different packages in different contexts: `X` can refer to one package named `X` in the main project but potentially different packages named `X` in each dependency. More on this below. +2. **Package loading:** e.g. `import X` or `using X`. The import mechanism allows you to load a package—i.e. an independent, reusable collection of Julia code, wrapped in a module—and makes the resulting module available by the name `X` inside of the importing module. If the same `X` package is imported multiple times in the same Julia session, it is only loaded the first time—on subsequent imports, the importing module gets a reference to the same module. Note though, that `import X` can load different packages in different contexts: `X` can refer to one package named `X` in the main project but potentially different packages named `X` in each dependency. More on this below. -Code inclusion is quite straightforward: it simply parses and evaluates a source file in the context of the caller. Package loading is built on top of code inclusion and is quite a bit more complex. The rest of this chapter, therefore, focuses on the behavior and mechanics of package loading. +Code inclusion is quite straightforward: it simply parses and evaluates a source file in the context of the caller. Package loading is built on top of code inclusion and is a lot more complex. Therefore, the rest of this chapter focuses on the behavior and mechanics of package loading. !!! note - You only need to read this chapter if you want to understand the technical details of package loading in Julia. If you just want to install and use packages, simply use Julia's built-in package manager to add packages to your environment and write `import X` or `using X` in your code to load packages that you've added. + You only need to read this chapter if you want to understand the technical details of package loading. If you just want to install and use packages, simply use Julia's built-in package manager to add packages to your environment and write `import X` or `using X` in your code to load packages that you've added. A *package* is a source tree with a standard layout providing functionality that can be reused by other Julia projects. A package is loaded by `import X` or `using X` statements. These statements also make the module named `X`, which results from loading the package code, available within the module where the import statement occurs. The meaning of `X` in `import X` is context-dependent: which `X` package is loaded depends on what code the statement occurs in. The effect of `import X` depends on two questions: @@ -19,9 +19,9 @@ Understanding how Julia answers these questions is key to understanding package ## Federation of packages -Julia supports federated management of packages. This means that multiple independent parties can maintain both public and private packages and registries of them, and that projects can depend on a mix of public and private packages from different registries. Packages from various registries are installed and managed using a common set of tools and workflows. The `Pkg` package manager ships with Julia 0.7/1.0 and lets you install and manage dependencies of your projects, by creating and manipulating project files, which describe what your project depends on, and manifest files that snapshot exact versions of your project's complete dependency graph. +Julia supports federated management of packages. This means that multiple independent parties can maintain both public and private packages and registries of them, and that projects can depend on a mix of public and private packages from different registries. Packages from various registries are installed and managed using a common set of tools and workflows. The `Pkg` package manager ships with Julia 0.7/1.0 and lets you install and manage your projects' dependencies. It does this by creating and manipulating project files that describe what your project depends on, and manifest files that snapshot exact versions of your project's complete dependency graph. -One consequence of federation is that there cannot be a central authority for package naming. Different entities may use the same name to refer to unrelated packages. This possibility is unavoidable since these entities do not coordinate and may not even know about each other. Because of the lack of a central naming authority, a single project can quite possibly end up depending on different packages with the same name. Julia's package loading mechanism handles this by not requiring package names to be globally unique, even within the dependency graph of a single project. Instead, packages are identified by [universally unique identifiers](https://en.wikipedia.org/wiki/Universally_unique_identifier) (UUIDs) which are assigned to them before they are registered. The question *"what is `X`?"* is answered by determining the UUID of `X`. +One consequence of federation is that there cannot be a central authority for package naming. Different entities may use the same name to refer to unrelated packages. This possibility is unavoidable since these entities do not coordinate and may not even know about each other. Because of the lack of a central naming authority, a single project can quite possibly end up depending on different packages that have the same name. Julia's package loading mechanism handles this by not requiring package names to be globally unique, even within the dependency graph of a single project. Instead, packages are identified by [universally unique identifiers](https://en.wikipedia.org/wiki/Universally_unique_identifier) (UUIDs) which are assigned to them before they are registered. The question *"what is `X`?"* is answered by determining the UUID of `X`. Since the decentralized naming problem is somewhat abstract, it may help to walk through a concrete scenario to understand the issue. Suppose you're developing an application called `App`, which uses two packages: `Pub` and `Priv`. `Priv` is a private package that you created, whereas `Pub` is a public package that you use but don't control. When you created `Priv`, there was no public package by that name. Subsequently, however, an unrelated package also named `Priv` has been published and become popular. In fact, the `Pub` package has started to use it. Therefore, when you next upgrade `Pub` to get the latest bug fixes and features, `App` will end up—through no action of yours other than upgrading—depending on two different packages named `Priv`. `App` has a direct dependency on your private `Priv` package, and an indirect dependency, through `Pub`, on the new public `Priv` package. Since these two `Priv` packages are different but both required for `App` to continue working correctly, the expression `import Priv` must refer to different `Priv` packages depending on whether it occurs in `App`'s code or in `Pub`'s code. Julia's package loading mechanism allows this by distinguishing the two `Priv` packages by context and UUID. How this distinction works is determined by environments, as explained in the following sections. @@ -35,9 +35,9 @@ An *environment* determines what `import X` and `using X` mean in various code c These three kinds of environment each serve a different purpose: -* Project environments provide **reproducibility.** By checking a project environment into version control—e.g. a git repository—along with the rest of the project's source code, you can reproduce the exact state of the project _and_ all of its dependencies since the manifest file captures the exact version of every dependency and can be rematerialized easily. -* Package directories provide low-overhead **convenience** when a project environment would be overkill: are handy when you have a set of packages and just want to put them somewhere and use them as they are without having to create and maintain a project environment for them. -* Stacked environments allow for **augmentation** of the primary environment with additional tools. You can push an environment including development tools onto the stack and they will be available from the REPL and scripts but not from inside of packages. +* Project environments provide **reproducibility.** By checking a project environment into version control—e.g. a git repository—along with the rest of the project's source code, you can reproduce the exact state of the project _and_ all of its dependencies since the manifest file captures the exact version of every dependency. +* Package directories provide low-overhead **convenience** when a project environment isn't needed. Package directories are handy when you have a set of packages that you just want to put somewhere and use them as they are, without having to create and maintain a project environment for them. +* Stacked environments allow for **augmentation** of the primary environment with additional tools. You can push an environment including development tools onto the stack and they will be available from the REPL and scripts but not from inside packages. As an abstraction, an environment provides three maps: `roots`, `graph` and `paths`. When resolving the meaning of `import X`, `roots` and `graph` are used to determine the identity of `X` and answer the question *"what is `X`?"*, while the `paths` map is used to locate the source code of `X` and answer the question *"where is `X`?"* The specific roles of the three maps are: @@ -51,18 +51,18 @@ As an abstraction, an environment provides three maps: `roots`, `graph` and `pat - **paths:** `uuid::UUID` × `name::Symbol` ⟶ `path::String` - The `paths` map assigns to each package UUID-name pair, the location of the entry-point source file of that package. After the identity of `X` in `import X` has been resolved to a UUID via `roots` or `graph` (depending on whether it is loaded from the main project or an dependency), Julia determines what file to load to acquire `X` by looking up `paths[uuid,:X]` in the environment. Including this file should create a module named `X`. After the first time this package is loaded, any import resolving to the same `uuid` will simply create a new binding to the same already-loaded package module. + The `paths` map assigns to each package UUID-name pair, the location of that package's entry-point source file. After the identity of `X` in `import X` has been resolved to a UUID via `roots` or `graph` (depending on whether it is loaded from the main project or a dependency), Julia determines what file to load to acquire `X` by looking up `paths[uuid,:X]` in the environment. Including this file should create a module named `X`. Once this package is loaded, i.e. after its first import, any subsequent import resolving to the same `uuid` will simply create a new binding to the original already-loaded package module. Each kind of environment defines these three maps differently, as detailed in the following sections. !!! note - For clarity of exposition, the examples throughout this chapter include fully materialized data structures for `roots`, `graph` and `paths`. However, these maps are really only abstractions—for efficiency, Julia's package loading code does not actually materialize them. Instead, it queries them through internal APIs and lazily computes only as much of each structure as is necessary to load a given package. + For ease of understanding, the examples throughout this chapter show full data structures for `roots`, `graph` and `paths`. However, for efficiency, Julia's package loading code does not actually create them. Instead, it queries them through internal APIs and lazily computes only as much of each structure as it needs to load a given package. ### Project environments -A project environment is determined by a directory containing a project file, `Project.toml`, and optionally a manifest file, `Manifest.toml`. These files can also be named `JuliaProject.toml` and `JuliaManifest.toml`, in which case `Project.toml` and `Manifest.toml` are ignored; this allows for coexistence with other tools that might consider files named `Project.toml` and `Manifest.toml` significant. For pure Julia projects, however, the names `Project.toml` and `Manifest.toml` should be preferred. The `roots`, `graph` and `paths` maps of a project environment are defined as follows. +A project environment is determined by a directory containing a project file called `Project.toml`, and optionally a manifest file called `Manifest.toml`. These files may also be called `JuliaProject.toml` and `JuliaManifest.toml`, in which case `Project.toml` and `Manifest.toml` are ignored. (This allows for coexistence with other tools that might consider files called `Project.toml` and `Manifest.toml` significant.) For pure Julia projects, however, the names `Project.toml` and `Manifest.toml` are preferred. The `roots`, `graph` and `paths` maps of a project environment are defined as follows. -**The roots map** of the environment is determined by the contents of the project file, specifically, its top-level `name` and `uuid` entries and its `[deps]` section (all optional). Consider the following example project file for the hypothetical application, `App`, as described above: +**The roots map** of the environment is determined by the contents of the project file, specifically, its top-level `name` and `uuid` entries and its `[deps]` section (all optional). Consider the following example project file for the hypothetical application, `App`, as described earlier: ```toml name = "App" @@ -73,7 +73,7 @@ Priv = "ba13f791-ae1d-465a-978b-69c3ad90f72b" Pub = "c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1" ``` -This project file implies the following `roots` map, if it were materialized as a Julia dictionary: +This project file implies the following `roots` map, if it was represented by a Julia dictionary: ```julia roots = Dict( @@ -83,9 +83,9 @@ roots = Dict( ) ``` -Given this `roots` map, in the code of `App` the statement `import Priv` will cause Julia to look up `roots[:Priv]`, which yields `ba13f791-ae1d-465a-978b-69c3ad90f72b`, the UUID of the `Priv` package that is to be loaded in that context. This UUID identifies which `Priv` package to load and use when the main application evaluates `import Priv`. +Given this `roots` map, in `App`'s code the statement `import Priv` will cause Julia to look up `roots[:Priv]`, which yields `ba13f791-ae1d-465a-978b-69c3ad90f72b`, the UUID of the `Priv` package that is to be loaded in that context. This UUID identifies which `Priv` package to load and use when the main application evaluates `import Priv`. -**The dependency graph** of a project environment is determined by the contents of the manifest file, if present, or if there is no manifest file, `graph` is empty. A manifest file contains a stanza for each direct or indirect dependency of a project, including for each one, its UUID and a source tree hash or an explicit path to the source code. Consider the following example manifest file for `App`: +**The dependency graph** of a project environment is determined by the contents of the manifest file, if present. If there is no manifest file, `graph` is empty. A manifest file contains a stanza for each of a project's direct or indirect dependencies, including for each one, its UUID and a source tree hash or an explicit path to the source code. Consider the following example manifest file for `App`: ```toml [[Priv]] # the private one @@ -120,7 +120,7 @@ This manifest file describes a possible complete dependency graph for the `App` * The public `Priv` has no dependencies. - The application also depends on the `Pub` package, which in turn depends on the public `Priv ` and the same `Zebra` package which the private `Priv` package depends on. -A materialized representation of this dependency `graph` looks like this: +This dependency `graph` represented as a dictionary, looks like this: ```julia graph = Dict{UUID,Dict{Symbol,UUID}}( @@ -147,7 +147,7 @@ Given this dependency `graph`, when Julia sees `import Priv` in the `Pub` packag graph[UUID("c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1")][:Priv] ``` -and gets `2d15fe94-a1f7-436c-a4d8-07a9a496e01c` , which indicates that in the context of the `Pub` package, `import Priv` refers to the public `Priv` package, rather than the private one which the app depends on directly. This is how the name `Priv` can refer to different packages in the main project than it does in one of the packages dependencies, which allows for name collisions in the package ecosystem. +and gets `2d15fe94-a1f7-436c-a4d8-07a9a496e01c`, which indicates that in the context of the `Pub` package, `import Priv` refers to the public `Priv` package, rather than the private one which the app depends on directly. This is how the name `Priv` can refer to different packages in the main project than it does in one of its package's dependencies, which allows for duplicate names in the package ecosystem. What happens if `import Zebra` is evaluated in the main `App` code base? Since `Zebra` does not appear in the project file, the import will fail even though `Zebra` *does* appear in the manifest file. Moreover, if `import Zebra` occurs in the public `Priv` package—the one with UUID `2d15fe94-a1f7-436c-a4d8-07a9a496e01c`—then that would also fail since that `Priv` package has no declared dependencies in the manifest file and therefore cannot load any packages. The `Zebra` package can only be loaded by packages for which it appear as an explicit dependency in the manifest file: the `Pub` package and one of the `Priv` packages. @@ -167,7 +167,7 @@ If, on the other hand, Julia was loading the *other* `Priv` package—the one wi Julia uses the first of these that exists to load the public `Priv` package. -Here is a materialized `paths` map for the `App` project environment: +Here is a representation of the `paths` map for the `App` project environment: ```julia paths = Dict{Tuple{UUID,Symbol},String}( @@ -192,13 +192,13 @@ paths = Dict{Tuple{UUID,Symbol},String}( This example map includes three different kinds of package locations: -1. The private `Priv` package is "[vendored](https://stackoverflow.com/a/35109534/659248)" inside of `App` repository. +1. The private `Priv` package is "[vendored](https://stackoverflow.com/a/35109534/659248)" inside the `App` repository. 2. The public `Priv` and `Zebra` packages are in the system depot, where packages installed and managed by the system administrator live. These are available to all users on the system. 3. The `Pub` package is in the user depot, where packages installed by the user live. These are only available to the user who installed them. ### Package directories -Package directories provide a kind of environment that approximates package loading in Julia 0.6 and earlier, and which resembles package loading in many other dynamic languages. The set of packages available in a package directory corresponds to the set of subdirectories it contains that look like packages: if `X/src/X.jl` is a file in a package directory, then `X` is considered to be a package and `X/src/X.jl` is the file you load to get `X`. Which packages can "see" each other as dependencies depends on whether they contain project files or not and what appears in the `[deps]` sections of those project files. +Package directories provide a kind of environment that approximates package loading in Julia 0.6 and earlier, and which resembles package loading in many other dynamic languages. The set of packages available in a package directory corresponds to the set of subdirectories it contains that look like packages: if `X/src/X.jl` is a file in a package directory, then `X` is considered to be a package and `X/src/X.jl` is the file Julia loads to get `X`. Which packages can "see" each other as dependencies depends on whether they contain project files, and if they do, on what appears in those project files' `[deps]` sections. **The roots map** is determined by the subdirectories `X` of a package directory for which `X/src/X.jl` exists and whether `X/Project.toml` exists and has a top-level `uuid` entry. Specifically `:X => uuid` goes in `roots` for each such `X` where `uuid` is defined as: @@ -246,7 +246,7 @@ Dingo/ # no imports ``` -Here is a corresponding `roots` structure, materialized as a dictionary: +Here is a corresponding `roots` structure, represented as a dictionary: ```julia roots = Dict{Symbol,UUID}( @@ -257,7 +257,7 @@ roots = Dict{Symbol,UUID}( ) ``` -Here is the corresponding `graph` structure, materialized as a dictionary: +Here is the corresponding `graph` structure, represented as a dictionary: ```julia graph = Dict{UUID,Dict{Symbol,UUID}}( @@ -285,12 +285,12 @@ Observe the following specific instances of these rules in our example: * `Aardvark` can import on any of `Bobcat`, `Cobra` or `Dingo`; it does import `Bobcat` and `Cobra`. * `Bobcat` can and does import both `Cobra` and `Dingo`, which both have project files with UUIDs and are declared as dependencies in `Bobcat`'s `[deps]` section. -* `Bobcat` cannot possibly depend on `Aardvark` since `Aardvark` does not have a project file. +* `Bobcat` cannot depend on `Aardvark` since `Aardvark` does not have a project file. * `Cobra` can and does import `Dingo`, which has a project file and UUID, and is declared as a dependency in `Cobra`'s `[deps]` section. * `Cobra` cannot depend on `Aardvark` or `Bobcat` since neither have real UUIDs. * `Dingo` cannot import anything because it has a project file without a `[deps]` section. -**The paths map** in a package directory is simple: it maps subdirectory names to their corresponding entry-point paths. In other words, if the path to our example project directory is `/home/me/animals` then the `paths` map would be materialized as this dictionary: +**The paths map** in a package directory is simple: it maps subdirectory names to their corresponding entry-point paths. In other words, if the path to our example project directory is `/home/me/animals` then the `paths` map could be represented by this dictionary: ```julia paths = Dict{Tuple{UUID,Symbol},String}( @@ -321,7 +321,7 @@ paths = reduce(merge, reverse([paths₁, paths₂, …])) The subscripted `rootsᵢ`, `graphᵢ` and `pathsᵢ` variables correspond to the subscripted environments, `envᵢ`, contained `stack`. The `reverse` is present because `merge` favors the last argument rather than first when there are collisions between keys in its argument dictionaries. That's all there is to stacked environments. There are a couple of noteworthy features of this design: -1. The *primary environment*—i.e.the first environment in a stack—is faithfully embedded in a stacked environment. The full dependency graph of the first environment in a stack is guaranteed to be included intact in the stacked environment including the same versions of all dependencies. +1. The *primary environment*—i.e. the first environment in a stack—is faithfully embedded in a stacked environment. The full dependency graph of the first environment in a stack is guaranteed to be included intact in the stacked environment including the same versions of all dependencies. 2. Packages in non-primary environments can end up using incompatible versions of their dependencies even if their own environments are entirely compatible. This can happen when one of their dependencies is shadowed by a version in an earlier environment in the stack. Since the primary environment is typically the environment of a project you're working on, while environments later in the stack contain additional tools, this is the right tradeoff: it's better to break your dev tools but keep the project working. When such incompatibilities occur, you'll typically want to upgrade your dev tools to versions that are compatible with the main project. diff --git a/codex/manual/complex-and-rational-numbers.md b/codex/manual/complex-and-rational-numbers.md index 9f49aa0..6f2bfaf 100644 --- a/codex/manual/complex-and-rational-numbers.md +++ b/codex/manual/complex-and-rational-numbers.md @@ -1,20 +1,19 @@ # Complex and Rational Numbers -Julia ships with predefined types representing both complex and rational numbers, and supports -all standard [Mathematical Operations and Elementary Functions](@ref) on them. [Conversion and Promotion](@ref conversion-and-promotion) are defined +Julia includes predefined types for both complex and rational numbers, and supports +all the standard [Mathematical Operations and Elementary Functions](@ref) on them. [Conversion and Promotion](@ref conversion-and-promotion) are defined so that operations on any combination of predefined numeric types, whether primitive or composite, behave as expected. ## Complex Numbers The global constant [`im`](@ref) is bound to the complex number *i*, representing the principal -square root of -1. It was deemed harmful to co-opt the name `i` for a global constant, since it -is such a popular index variable name. Since Julia allows numeric literals to be [juxtaposed with identifiers as coefficients](@ref man-numeric-literal-coefficients), +square root of -1. (Using mathematicians' `i` or engineers' `j` for this global constant were rejected since they are such popular index variable names.) Since Julia allows numeric literals to be [juxtaposed with identifiers as coefficients](@ref man-numeric-literal-coefficients), this binding suffices to provide convenient syntax for complex numbers, similar to the traditional mathematical notation: ```jldoctest -julia> 1 + 2im +julia> 1+2im 1 + 2im ``` @@ -113,7 +112,7 @@ julia> angle(1 + 2im) # phase angle in radians As usual, the absolute value ([`abs`](@ref)) of a complex number is its distance from zero. [`abs2`](@ref) gives the square of the absolute value, and is of particular use for complex -numbers where it avoids taking a square root. [`angle`](@ref) returns the phase angle in radians +numbers since it avoids taking a square root. [`angle`](@ref) returns the phase angle in radians (also known as the *argument* or *arg* function). The full gamut of other [Elementary Functions](@ref) is also defined for complex numbers: @@ -157,7 +156,7 @@ julia> a = 1; b = 2; a + b*im 1 + 2im ``` -However, this is *not* recommended; Use the [`complex`](@ref) function instead to construct +However, this is *not* recommended. Instead, use the more efficient [`complex`](@ref) function to construct a complex value directly from its real and imaginary parts: ```jldoctest @@ -247,7 +246,7 @@ julia> 6//5 / 10//7 21//25 ``` -Rationals can be easily converted to floating-point numbers: +Rationals can easily be converted to floating-point numbers: ```jldoctest julia> float(3//4) @@ -277,7 +276,7 @@ julia> typeof(ans) Rational{Int64} ``` -Trying to construct a [`NaN`](@ref) rational value, however, is not: +Trying to construct a [`NaN`](@ref) rational value, however, is invalid: ```jldoctest julia> 0//0 diff --git a/codex/manual/parallel-computing.md b/codex/manual/parallel-computing.md index b2a9628..415def3 100644 --- a/codex/manual/parallel-computing.md +++ b/codex/manual/parallel-computing.md @@ -65,7 +65,7 @@ A channel can be visualized as a pipe, i.e., it has a write end and a read end : c1 = Channel(32) c2 = Channel(32) - # and a function `foo` which reads items from from c1, processes the item read + # and a function `foo` which reads items from c1, processes the item read # and writes a result to c2, function foo() while true @@ -629,7 +629,7 @@ As for v0.7 and beyond, the feeder tasks are able to share state via `nextidx` b they all run on the same process. Even if `Tasks` are scheduled cooperatively, locking may still be required in some contexts, as in [asynchronous I\O](https://docs.julialang.org/en/stable/manual/faq/#Asynchronous-IO-and-concurrent-synchronous-writes-1). This means context switches only occur at well-defined points: in this case, -when [`remotecall_fetch`](@ref) is called. This is the current state of implementation (dev v0.7) and it may change +when [`remotecall_fetch`](@ref) is called. This is the current state of implementation and it may change for future Julia versions, as it is intended to make it possible to run up to N `Tasks` on M `Process`, aka [M:N Threading](https://en.wikipedia.org/wiki/Thread_(computing)#Models). Then a lock acquiring\releasing model for `nextidx` will be needed, as it is not safe to let multiple processes read-write a resource at diff --git a/codex/manual/performance-tips.md b/codex/manual/performance-tips.md index ce86bc9..aaf809e 100644 --- a/codex/manual/performance-tips.md +++ b/codex/manual/performance-tips.md @@ -1091,7 +1091,7 @@ using Distributed responses = Vector{Any}(undef, nworkers()) @sync begin for (idx, pid) in enumerate(workers()) - @async responses[idx] = remotecall_fetch(pid, foo, args...) + @async responses[idx] = remotecall_fetch(foo, pid, args...) end end ``` diff --git a/src/devdocs/init.md b/src/devdocs/init.md index 056186d..6264fcf 100644 --- a/src/devdocs/init.md +++ b/src/devdocs/init.md @@ -2,7 +2,7 @@ How does the Julia runtime execute `julia -e 'println("Hello World!")'` ? -## main() +## `main()` Execution starts at [`main()` in `ui/repl.c`](https://github.com/JuliaLang/julia/blob/master/ui/repl.c). @@ -16,7 +16,7 @@ or early initialization. Other options are handled later by [`process_options()` `jl_parse_opts()` stores command line options in the [global `jl_options` struct](https://github.com/JuliaLang/julia/blob/master/src/julia.h). -## julia_init() +## `julia_init()` [`julia_init()` in `task.c`](https://github.com/JuliaLang/julia/blob/master/src/task.c) is called by `main()` and calls [`_julia_init()` in `init.c`](https://github.com/JuliaLang/julia/blob/master/src/init.c). @@ -137,7 +137,7 @@ and `main()` calls `true_main(argc, (char**)argv)`. Note: [`jl_restore_system_image()` (and `staticdata.c` in general)](https://github.com/JuliaLang/julia/blob/master/src/staticdata.c) uses the [Legacy `ios.c` library](@ref). -## true_main() +## `true_main()` [`true_main()`](https://github.com/JuliaLang/julia/blob/master/ui/repl.c) loads the contents of `argv[]` into [`Base.ARGS`](@ref). @@ -152,13 +152,13 @@ However, in our example (`julia -e 'println("Hello World!")'`), [`jl_get_global( looks up [`Base._start`](https://github.com/JuliaLang/julia/blob/master/base/client.jl) and [`jl_apply()`](https://github.com/JuliaLang/julia/blob/master/src/julia.h) executes it. -## Base._start +## `Base._start` [`Base._start`](https://github.com/JuliaLang/julia/blob/master/base/client.jl) calls [`Base.process_options`](https://github.com/JuliaLang/julia/blob/master/base/client.jl) which calls [`jl_parse_input_line("println("Hello World!")")`](https://github.com/JuliaLang/julia/blob/master/src/ast.c) to create an expression object and [`Base.eval()`](@ref eval) to execute it. -## Base.eval +## `Base.eval` [`Base.eval()`](@ref eval) was [mapped to `jl_f_top_eval`](https://github.com/JuliaLang/julia/blob/master/src/builtins.c) by `jl_init_primitives()`. @@ -217,13 +217,13 @@ Hello World! Since our example has just one function call, which has done its job of printing "Hello World!", the stack now rapidly unwinds back to `main()`. -## jl_atexit_hook() +## `jl_atexit_hook()` `main()` calls [`jl_atexit_hook()`](https://github.com/JuliaLang/julia/blob/master/src/init.c). This calls `_atexit` for each module, then calls [`jl_gc_run_all_finalizers()`](https://github.com/JuliaLang/julia/blob/master/src/gc.c) and cleans up libuv handles. -## julia_save() +## `julia_save()` Finally, `main()` calls [`julia_save()`](https://github.com/JuliaLang/julia/blob/master/src/init.c), which if requested on the command line, saves the runtime state to a new system image. See [`jl_compile_all()`](https://github.com/JuliaLang/julia/blob/master/src/gf.c) diff --git a/src/manual/code-loading.md b/src/manual/code-loading.md index 603e3cc..e88dbdc 100644 --- a/src/manual/code-loading.md +++ b/src/manual/code-loading.md @@ -3,12 +3,12 @@ Julia has two mechanisms for loading code: 1. **Code inclusion:** e.g. `include("source.jl")`. Inclusion allows you to split a single program across multiple source files. The expression `include("source.jl")` causes the contents of the file `source.jl` to be evaluated in the global scope of the module where the `include` call occurs. If `include("source.jl")` is called multiple times, `source.jl` is evaluated multiple times. The included path, `source.jl`, is interpreted relative to the file where the `include` call occurs. This makes it simple to relocate a subtree of source files. In the REPL, included paths are interpreted relative to the current working directory, `pwd()`. -2. **Package loading:** e.g. `import X` or `using X`. The import mechanism allows you to load a package—i.e. an independent, reusable collection of Julia code, wrapped in a module—and makes the resulting module available by the name `X` inside of the importing module. If the same `X` package is imported multiple times in the same Julia session, it is only loaded the first time—on subsequent imports, the importing module gets a reference to the same module. It should be noted, however, that `import X` can load different packages in different contexts: `X` can refer to one package named `X` in the main project but potentially different packages named `X` in each dependency. More on this below. +2. **Package loading:** e.g. `import X` or `using X`. The import mechanism allows you to load a package—i.e. an independent, reusable collection of Julia code, wrapped in a module—and makes the resulting module available by the name `X` inside of the importing module. If the same `X` package is imported multiple times in the same Julia session, it is only loaded the first time—on subsequent imports, the importing module gets a reference to the same module. Note though, that `import X` can load different packages in different contexts: `X` can refer to one package named `X` in the main project but potentially different packages named `X` in each dependency. More on this below. -Code inclusion is quite straightforward: it simply parses and evaluates a source file in the context of the caller. Package loading is built on top of code inclusion and is quite a bit more complex. The rest of this chapter, therefore, focuses on the behavior and mechanics of package loading. +Code inclusion is quite straightforward: it simply parses and evaluates a source file in the context of the caller. Package loading is built on top of code inclusion and is a lot more complex. Therefore, the rest of this chapter focuses on the behavior and mechanics of package loading. !!! note - You only need to read this chapter if you want to understand the technical details of package loading in Julia. If you just want to install and use packages, simply use Julia's built-in package manager to add packages to your environment and write `import X` or `using X` in your code to load packages that you've added. + You only need to read this chapter if you want to understand the technical details of package loading. If you just want to install and use packages, simply use Julia's built-in package manager to add packages to your environment and write `import X` or `using X` in your code to load packages that you've added. A *package* is a source tree with a standard layout providing functionality that can be reused by other Julia projects. A package is loaded by `import X` or `using X` statements. These statements also make the module named `X`, which results from loading the package code, available within the module where the import statement occurs. The meaning of `X` in `import X` is context-dependent: which `X` package is loaded depends on what code the statement occurs in. The effect of `import X` depends on two questions: @@ -19,9 +19,9 @@ Understanding how Julia answers these questions is key to understanding package ## Federation of packages -Julia supports federated management of packages. This means that multiple independent parties can maintain both public and private packages and registries of them, and that projects can depend on a mix of public and private packages from different registries. Packages from various registries are installed and managed using a common set of tools and workflows. The `Pkg` package manager ships with Julia 0.7/1.0 and lets you install and manage dependencies of your projects, by creating and manipulating project files, which describe what your project depends on, and manifest files that snapshot exact versions of your project's complete dependency graph. +Julia supports federated management of packages. This means that multiple independent parties can maintain both public and private packages and registries of them, and that projects can depend on a mix of public and private packages from different registries. Packages from various registries are installed and managed using a common set of tools and workflows. The `Pkg` package manager ships with Julia 0.7/1.0 and lets you install and manage your projects' dependencies. It does this by creating and manipulating project files that describe what your project depends on, and manifest files that snapshot exact versions of your project's complete dependency graph. -One consequence of federation is that there cannot be a central authority for package naming. Different entities may use the same name to refer to unrelated packages. This possibility is unavoidable since these entities do not coordinate and may not even know about each other. Because of the lack of a central naming authority, a single project can quite possibly end up depending on different packages with the same name. Julia's package loading mechanism handles this by not requiring package names to be globally unique, even within the dependency graph of a single project. Instead, packages are identified by [universally unique identifiers](https://en.wikipedia.org/wiki/Universally_unique_identifier) (UUIDs) which are assigned to them before they are registered. The question *"what is `X`?"* is answered by determining the UUID of `X`. +One consequence of federation is that there cannot be a central authority for package naming. Different entities may use the same name to refer to unrelated packages. This possibility is unavoidable since these entities do not coordinate and may not even know about each other. Because of the lack of a central naming authority, a single project can quite possibly end up depending on different packages that have the same name. Julia's package loading mechanism handles this by not requiring package names to be globally unique, even within the dependency graph of a single project. Instead, packages are identified by [universally unique identifiers](https://en.wikipedia.org/wiki/Universally_unique_identifier) (UUIDs) which are assigned to them before they are registered. The question *"what is `X`?"* is answered by determining the UUID of `X`. Since the decentralized naming problem is somewhat abstract, it may help to walk through a concrete scenario to understand the issue. Suppose you're developing an application called `App`, which uses two packages: `Pub` and `Priv`. `Priv` is a private package that you created, whereas `Pub` is a public package that you use but don't control. When you created `Priv`, there was no public package by that name. Subsequently, however, an unrelated package also named `Priv` has been published and become popular. In fact, the `Pub` package has started to use it. Therefore, when you next upgrade `Pub` to get the latest bug fixes and features, `App` will end up—through no action of yours other than upgrading—depending on two different packages named `Priv`. `App` has a direct dependency on your private `Priv` package, and an indirect dependency, through `Pub`, on the new public `Priv` package. Since these two `Priv` packages are different but both required for `App` to continue working correctly, the expression `import Priv` must refer to different `Priv` packages depending on whether it occurs in `App`'s code or in `Pub`'s code. Julia's package loading mechanism allows this by distinguishing the two `Priv` packages by context and UUID. How this distinction works is determined by environments, as explained in the following sections. @@ -35,9 +35,9 @@ An *environment* determines what `import X` and `using X` mean in various code c These three kinds of environment each serve a different purpose: -* Project environments provide **reproducibility.** By checking a project environment into version control—e.g. a git repository—along with the rest of the project's source code, you can reproduce the exact state of the project _and_ all of its dependencies since the manifest file captures the exact version of every dependency and can be rematerialized easily. -* Package directories provide low-overhead **convenience** when a project environment would be overkill: are handy when you have a set of packages and just want to put them somewhere and use them as they are without having to create and maintain a project environment for them. -* Stacked environments allow for **augmentation** of the primary environment with additional tools. You can push an environment including development tools onto the stack and they will be available from the REPL and scripts but not from inside of packages. +* Project environments provide **reproducibility.** By checking a project environment into version control—e.g. a git repository—along with the rest of the project's source code, you can reproduce the exact state of the project _and_ all of its dependencies since the manifest file captures the exact version of every dependency. +* Package directories provide low-overhead **convenience** when a project environment isn't needed. Package directories are handy when you have a set of packages that you just want to put somewhere and use them as they are, without having to create and maintain a project environment for them. +* Stacked environments allow for **augmentation** of the primary environment with additional tools. You can push an environment including development tools onto the stack and they will be available from the REPL and scripts but not from inside packages. As an abstraction, an environment provides three maps: `roots`, `graph` and `paths`. When resolving the meaning of `import X`, `roots` and `graph` are used to determine the identity of `X` and answer the question *"what is `X`?"*, while the `paths` map is used to locate the source code of `X` and answer the question *"where is `X`?"* The specific roles of the three maps are: @@ -51,18 +51,18 @@ As an abstraction, an environment provides three maps: `roots`, `graph` and `pat - **paths:** `uuid::UUID` × `name::Symbol` ⟶ `path::String` - The `paths` map assigns to each package UUID-name pair, the location of the entry-point source file of that package. After the identity of `X` in `import X` has been resolved to a UUID via `roots` or `graph` (depending on whether it is loaded from the main project or an dependency), Julia determines what file to load to acquire `X` by looking up `paths[uuid,:X]` in the environment. Including this file should create a module named `X`. After the first time this package is loaded, any import resolving to the same `uuid` will simply create a new binding to the same already-loaded package module. + The `paths` map assigns to each package UUID-name pair, the location of that package's entry-point source file. After the identity of `X` in `import X` has been resolved to a UUID via `roots` or `graph` (depending on whether it is loaded from the main project or a dependency), Julia determines what file to load to acquire `X` by looking up `paths[uuid,:X]` in the environment. Including this file should create a module named `X`. Once this package is loaded, i.e. after its first import, any subsequent import resolving to the same `uuid` will simply create a new binding to the original already-loaded package module. Each kind of environment defines these three maps differently, as detailed in the following sections. !!! note - For clarity of exposition, the examples throughout this chapter include fully materialized data structures for `roots`, `graph` and `paths`. However, these maps are really only abstractions—for efficiency, Julia's package loading code does not actually materialize them. Instead, it queries them through internal APIs and lazily computes only as much of each structure as is necessary to load a given package. + For ease of understanding, the examples throughout this chapter show full data structures for `roots`, `graph` and `paths`. However, for efficiency, Julia's package loading code does not actually create them. Instead, it queries them through internal APIs and lazily computes only as much of each structure as it needs to load a given package. ### Project environments -A project environment is determined by a directory containing a project file, `Project.toml`, and optionally a manifest file, `Manifest.toml`. These files can also be named `JuliaProject.toml` and `JuliaManifest.toml`, in which case `Project.toml` and `Manifest.toml` are ignored; this allows for coexistence with other tools that might consider files named `Project.toml` and `Manifest.toml` significant. For pure Julia projects, however, the names `Project.toml` and `Manifest.toml` should be preferred. The `roots`, `graph` and `paths` maps of a project environment are defined as follows. +A project environment is determined by a directory containing a project file called `Project.toml`, and optionally a manifest file called `Manifest.toml`. These files may also be called `JuliaProject.toml` and `JuliaManifest.toml`, in which case `Project.toml` and `Manifest.toml` are ignored. (This allows for coexistence with other tools that might consider files called `Project.toml` and `Manifest.toml` significant.) For pure Julia projects, however, the names `Project.toml` and `Manifest.toml` are preferred. The `roots`, `graph` and `paths` maps of a project environment are defined as follows. -**The roots map** of the environment is determined by the contents of the project file, specifically, its top-level `name` and `uuid` entries and its `[deps]` section (all optional). Consider the following example project file for the hypothetical application, `App`, as described above: +**The roots map** of the environment is determined by the contents of the project file, specifically, its top-level `name` and `uuid` entries and its `[deps]` section (all optional). Consider the following example project file for the hypothetical application, `App`, as described earlier: ```toml name = "App" @@ -73,7 +73,7 @@ Priv = "ba13f791-ae1d-465a-978b-69c3ad90f72b" Pub = "c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1" ``` -This project file implies the following `roots` map, if it were materialized as a Julia dictionary: +This project file implies the following `roots` map, if it was represented by a Julia dictionary: ```julia roots = Dict( @@ -83,9 +83,9 @@ roots = Dict( ) ``` -Given this `roots` map, in the code of `App` the statement `import Priv` will cause Julia to look up `roots[:Priv]`, which yields `ba13f791-ae1d-465a-978b-69c3ad90f72b`, the UUID of the `Priv` package that is to be loaded in that context. This UUID identifies which `Priv` package to load and use when the main application evaluates `import Priv`. +Given this `roots` map, in `App`'s code the statement `import Priv` will cause Julia to look up `roots[:Priv]`, which yields `ba13f791-ae1d-465a-978b-69c3ad90f72b`, the UUID of the `Priv` package that is to be loaded in that context. This UUID identifies which `Priv` package to load and use when the main application evaluates `import Priv`. -**The dependency graph** of a project environment is determined by the contents of the manifest file, if present, or if there is no manifest file, `graph` is empty. A manifest file contains a stanza for each direct or indirect dependency of a project, including for each one, its UUID and a source tree hash or an explicit path to the source code. Consider the following example manifest file for `App`: +**The dependency graph** of a project environment is determined by the contents of the manifest file, if present. If there is no manifest file, `graph` is empty. A manifest file contains a stanza for each of a project's direct or indirect dependencies, including for each one, its UUID and a source tree hash or an explicit path to the source code. Consider the following example manifest file for `App`: ```toml [[Priv]] # the private one @@ -120,7 +120,7 @@ This manifest file describes a possible complete dependency graph for the `App` * The public `Priv` has no dependencies. - The application also depends on the `Pub` package, which in turn depends on the public `Priv ` and the same `Zebra` package which the private `Priv` package depends on. -A materialized representation of this dependency `graph` looks like this: +This dependency `graph` represented as a dictionary, looks like this: ```julia graph = Dict{UUID,Dict{Symbol,UUID}}( @@ -147,7 +147,7 @@ Given this dependency `graph`, when Julia sees `import Priv` in the `Pub` packag graph[UUID("c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1")][:Priv] ``` -and gets `2d15fe94-a1f7-436c-a4d8-07a9a496e01c` , which indicates that in the context of the `Pub` package, `import Priv` refers to the public `Priv` package, rather than the private one which the app depends on directly. This is how the name `Priv` can refer to different packages in the main project than it does in one of the packages dependencies, which allows for name collisions in the package ecosystem. +and gets `2d15fe94-a1f7-436c-a4d8-07a9a496e01c`, which indicates that in the context of the `Pub` package, `import Priv` refers to the public `Priv` package, rather than the private one which the app depends on directly. This is how the name `Priv` can refer to different packages in the main project than it does in one of its package's dependencies, which allows for duplicate names in the package ecosystem. What happens if `import Zebra` is evaluated in the main `App` code base? Since `Zebra` does not appear in the project file, the import will fail even though `Zebra` *does* appear in the manifest file. Moreover, if `import Zebra` occurs in the public `Priv` package—the one with UUID `2d15fe94-a1f7-436c-a4d8-07a9a496e01c`—then that would also fail since that `Priv` package has no declared dependencies in the manifest file and therefore cannot load any packages. The `Zebra` package can only be loaded by packages for which it appear as an explicit dependency in the manifest file: the `Pub` package and one of the `Priv` packages. @@ -167,7 +167,7 @@ If, on the other hand, Julia was loading the *other* `Priv` package—the one wi Julia uses the first of these that exists to load the public `Priv` package. -Here is a materialized `paths` map for the `App` project environment: +Here is a representation of the `paths` map for the `App` project environment: ```julia paths = Dict{Tuple{UUID,Symbol},String}( @@ -192,13 +192,13 @@ paths = Dict{Tuple{UUID,Symbol},String}( This example map includes three different kinds of package locations: -1. The private `Priv` package is "[vendored](https://stackoverflow.com/a/35109534/659248)" inside of `App` repository. +1. The private `Priv` package is "[vendored](https://stackoverflow.com/a/35109534/659248)" inside the `App` repository. 2. The public `Priv` and `Zebra` packages are in the system depot, where packages installed and managed by the system administrator live. These are available to all users on the system. 3. The `Pub` package is in the user depot, where packages installed by the user live. These are only available to the user who installed them. ### Package directories -Package directories provide a kind of environment that approximates package loading in Julia 0.6 and earlier, and which resembles package loading in many other dynamic languages. The set of packages available in a package directory corresponds to the set of subdirectories it contains that look like packages: if `X/src/X.jl` is a file in a package directory, then `X` is considered to be a package and `X/src/X.jl` is the file you load to get `X`. Which packages can "see" each other as dependencies depends on whether they contain project files or not and what appears in the `[deps]` sections of those project files. +Package directories provide a kind of environment that approximates package loading in Julia 0.6 and earlier, and which resembles package loading in many other dynamic languages. The set of packages available in a package directory corresponds to the set of subdirectories it contains that look like packages: if `X/src/X.jl` is a file in a package directory, then `X` is considered to be a package and `X/src/X.jl` is the file Julia loads to get `X`. Which packages can "see" each other as dependencies depends on whether they contain project files, and if they do, on what appears in those project files' `[deps]` sections. **The roots map** is determined by the subdirectories `X` of a package directory for which `X/src/X.jl` exists and whether `X/Project.toml` exists and has a top-level `uuid` entry. Specifically `:X => uuid` goes in `roots` for each such `X` where `uuid` is defined as: @@ -246,7 +246,7 @@ Dingo/ # no imports ``` -Here is a corresponding `roots` structure, materialized as a dictionary: +Here is a corresponding `roots` structure, represented as a dictionary: ```julia roots = Dict{Symbol,UUID}( @@ -257,7 +257,7 @@ roots = Dict{Symbol,UUID}( ) ``` -Here is the corresponding `graph` structure, materialized as a dictionary: +Here is the corresponding `graph` structure, represented as a dictionary: ```julia graph = Dict{UUID,Dict{Symbol,UUID}}( @@ -285,12 +285,12 @@ Observe the following specific instances of these rules in our example: * `Aardvark` can import on any of `Bobcat`, `Cobra` or `Dingo`; it does import `Bobcat` and `Cobra`. * `Bobcat` can and does import both `Cobra` and `Dingo`, which both have project files with UUIDs and are declared as dependencies in `Bobcat`'s `[deps]` section. -* `Bobcat` cannot possibly depend on `Aardvark` since `Aardvark` does not have a project file. +* `Bobcat` cannot depend on `Aardvark` since `Aardvark` does not have a project file. * `Cobra` can and does import `Dingo`, which has a project file and UUID, and is declared as a dependency in `Cobra`'s `[deps]` section. * `Cobra` cannot depend on `Aardvark` or `Bobcat` since neither have real UUIDs. * `Dingo` cannot import anything because it has a project file without a `[deps]` section. -**The paths map** in a package directory is simple: it maps subdirectory names to their corresponding entry-point paths. In other words, if the path to our example project directory is `/home/me/animals` then the `paths` map would be materialized as this dictionary: +**The paths map** in a package directory is simple: it maps subdirectory names to their corresponding entry-point paths. In other words, if the path to our example project directory is `/home/me/animals` then the `paths` map could be represented by this dictionary: ```julia paths = Dict{Tuple{UUID,Symbol},String}( @@ -321,7 +321,7 @@ paths = reduce(merge, reverse([paths₁, paths₂, …])) The subscripted `rootsᵢ`, `graphᵢ` and `pathsᵢ` variables correspond to the subscripted environments, `envᵢ`, contained `stack`. The `reverse` is present because `merge` favors the last argument rather than first when there are collisions between keys in its argument dictionaries. That's all there is to stacked environments. There are a couple of noteworthy features of this design: -1. The *primary environment*—i.e.the first environment in a stack—is faithfully embedded in a stacked environment. The full dependency graph of the first environment in a stack is guaranteed to be included intact in the stacked environment including the same versions of all dependencies. +1. The *primary environment*—i.e. the first environment in a stack—is faithfully embedded in a stacked environment. The full dependency graph of the first environment in a stack is guaranteed to be included intact in the stacked environment including the same versions of all dependencies. 2. Packages in non-primary environments can end up using incompatible versions of their dependencies even if their own environments are entirely compatible. This can happen when one of their dependencies is shadowed by a version in an earlier environment in the stack. Since the primary environment is typically the environment of a project you're working on, while environments later in the stack contain additional tools, this is the right tradeoff: it's better to break your dev tools but keep the project working. When such incompatibilities occur, you'll typically want to upgrade your dev tools to versions that are compatible with the main project. diff --git a/src/manual/complex-and-rational-numbers.md b/src/manual/complex-and-rational-numbers.md index 9f49aa0..6f2bfaf 100644 --- a/src/manual/complex-and-rational-numbers.md +++ b/src/manual/complex-and-rational-numbers.md @@ -1,20 +1,19 @@ # Complex and Rational Numbers -Julia ships with predefined types representing both complex and rational numbers, and supports -all standard [Mathematical Operations and Elementary Functions](@ref) on them. [Conversion and Promotion](@ref conversion-and-promotion) are defined +Julia includes predefined types for both complex and rational numbers, and supports +all the standard [Mathematical Operations and Elementary Functions](@ref) on them. [Conversion and Promotion](@ref conversion-and-promotion) are defined so that operations on any combination of predefined numeric types, whether primitive or composite, behave as expected. ## Complex Numbers The global constant [`im`](@ref) is bound to the complex number *i*, representing the principal -square root of -1. It was deemed harmful to co-opt the name `i` for a global constant, since it -is such a popular index variable name. Since Julia allows numeric literals to be [juxtaposed with identifiers as coefficients](@ref man-numeric-literal-coefficients), +square root of -1. (Using mathematicians' `i` or engineers' `j` for this global constant were rejected since they are such popular index variable names.) Since Julia allows numeric literals to be [juxtaposed with identifiers as coefficients](@ref man-numeric-literal-coefficients), this binding suffices to provide convenient syntax for complex numbers, similar to the traditional mathematical notation: ```jldoctest -julia> 1 + 2im +julia> 1+2im 1 + 2im ``` @@ -113,7 +112,7 @@ julia> angle(1 + 2im) # phase angle in radians As usual, the absolute value ([`abs`](@ref)) of a complex number is its distance from zero. [`abs2`](@ref) gives the square of the absolute value, and is of particular use for complex -numbers where it avoids taking a square root. [`angle`](@ref) returns the phase angle in radians +numbers since it avoids taking a square root. [`angle`](@ref) returns the phase angle in radians (also known as the *argument* or *arg* function). The full gamut of other [Elementary Functions](@ref) is also defined for complex numbers: @@ -157,7 +156,7 @@ julia> a = 1; b = 2; a + b*im 1 + 2im ``` -However, this is *not* recommended; Use the [`complex`](@ref) function instead to construct +However, this is *not* recommended. Instead, use the more efficient [`complex`](@ref) function to construct a complex value directly from its real and imaginary parts: ```jldoctest @@ -247,7 +246,7 @@ julia> 6//5 / 10//7 21//25 ``` -Rationals can be easily converted to floating-point numbers: +Rationals can easily be converted to floating-point numbers: ```jldoctest julia> float(3//4) @@ -277,7 +276,7 @@ julia> typeof(ans) Rational{Int64} ``` -Trying to construct a [`NaN`](@ref) rational value, however, is not: +Trying to construct a [`NaN`](@ref) rational value, however, is invalid: ```jldoctest julia> 0//0 diff --git a/src/manual/parallel-computing.md b/src/manual/parallel-computing.md index b2a9628..415def3 100644 --- a/src/manual/parallel-computing.md +++ b/src/manual/parallel-computing.md @@ -65,7 +65,7 @@ A channel can be visualized as a pipe, i.e., it has a write end and a read end : c1 = Channel(32) c2 = Channel(32) - # and a function `foo` which reads items from from c1, processes the item read + # and a function `foo` which reads items from c1, processes the item read # and writes a result to c2, function foo() while true @@ -629,7 +629,7 @@ As for v0.7 and beyond, the feeder tasks are able to share state via `nextidx` b they all run on the same process. Even if `Tasks` are scheduled cooperatively, locking may still be required in some contexts, as in [asynchronous I\O](https://docs.julialang.org/en/stable/manual/faq/#Asynchronous-IO-and-concurrent-synchronous-writes-1). This means context switches only occur at well-defined points: in this case, -when [`remotecall_fetch`](@ref) is called. This is the current state of implementation (dev v0.7) and it may change +when [`remotecall_fetch`](@ref) is called. This is the current state of implementation and it may change for future Julia versions, as it is intended to make it possible to run up to N `Tasks` on M `Process`, aka [M:N Threading](https://en.wikipedia.org/wiki/Thread_(computing)#Models). Then a lock acquiring\releasing model for `nextidx` will be needed, as it is not safe to let multiple processes read-write a resource at diff --git a/src/manual/performance-tips.md b/src/manual/performance-tips.md index ce86bc9..aaf809e 100644 --- a/src/manual/performance-tips.md +++ b/src/manual/performance-tips.md @@ -1091,7 +1091,7 @@ using Distributed responses = Vector{Any}(undef, nworkers()) @sync begin for (idx, pid) in enumerate(workers()) - @async responses[idx] = remotecall_fetch(pid, foo, args...) + @async responses[idx] = remotecall_fetch(foo, pid, args...) end end ``` From c17bcdc59a5f852912dc01ca9d71c89ea998cce5 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Sat, 20 Oct 2018 18:30:31 +0900 Subject: [PATCH 064/153] update Julia Commit 2885b62bd3 --- codex/base/base.md | 1 + codex/devdocs/sysimg.md | 28 ++++++++++--- codex/manual/arrays.md | 2 +- codex/manual/faq.md | 11 +++++ codex/manual/profile.md | 2 +- codex/manual/strings.md | 20 +++++---- codex/manual/workflow-tips.md | 76 +++++++++++++++++++++-------------- codex/stdlib/Dates.md | 7 +++- src/base/base.md | 1 + src/devdocs/sysimg.md | 28 ++++++++++--- src/manual/arrays.md | 2 +- src/manual/faq.md | 11 +++++ src/manual/profile.md | 2 +- src/manual/strings.md | 20 +++++---- src/manual/workflow-tips.md | 76 +++++++++++++++++++++-------------- src/stdlib/Dates.md | 7 +++- 16 files changed, 200 insertions(+), 94 deletions(-) diff --git a/codex/base/base.md b/codex/base/base.md index 0567e93..e8481b7 100644 --- a/codex/base/base.md +++ b/codex/base/base.md @@ -199,6 +199,7 @@ Core.NamedTuple Base.Val Core.Vararg Core.Nothing +Base.isnothing Base.Some Base.something Base.Enums.@enum diff --git a/codex/devdocs/sysimg.md b/codex/devdocs/sysimg.md index 4ca11cf..6c12278 100644 --- a/codex/devdocs/sysimg.md +++ b/codex/devdocs/sysimg.md @@ -46,16 +46,16 @@ under the same instruction set architecture (ISA). Multiple versions of the same may be created with minimum dispatch point inserted into shared functions in order to take advantage of different ISA extensions or other microarchitecture features. The version that offers the best performance will be selected automatically at runtime -based on available features. +based on available CPU features. ### Specifying multiple system image targets -Multi-microarch system image can be enabled by passing multiple targets +A multi-microarchitecture system image can be enabled by passing multiple targets during system image compilation. This can be done either with the `JULIA_CPU_TARGET` make option or with the `-C` command line option when running the compilation command manually. -Multiple targets are separated by `;` in the option. +Multiple targets are separated by `;` in the option string. The syntax for each target is a CPU name followed by multiple features separated by `,`. -All features supported by LLVM is supported and a feature can be disabled with a `-` prefix. +All features supported by LLVM are supported and a feature can be disabled with a `-` prefix. (`+` prefix is also allowed and ignored to be consistent with LLVM syntax). Additionally, a few special features are supported to control the function cloning behavior. @@ -76,7 +76,7 @@ Additionally, a few special features are supported to control the function cloni This behavior can be changed by specifying a different base with the `base()` option. The `n`th target (0-based) will be used as the base target instead of the default (`0`th) one. The base target has to be either `0` or another `clone_all` target. - Specifying a non default `clone_all` target as the base target will cause an error. + Specifying a non-`clone_all` target as the base target will cause an error. 3. `opt_size` @@ -88,6 +88,24 @@ Additionally, a few special features are supported to control the function cloni This cause the function for the targe to be optimize for size that might have a significant runtime performance impact. This corresponds to `-Oz` Clang option. +As an example, at the time of this writing, the following string is used in the creation of +the official `x86_64` Julia binaries downloadable from julialang.org: + +``` +generic;sandybridge,-xsaveopt,clone_all;haswell,-rdrnd,base(1) +``` + +This creates a system image with three separate targets; one for a generic `x86_64` +processor, one with a `sandybridge` ISA (explicitly excluding `xsaveopt`) that explicitly +clones all functions, and one targeting the `haswell` ISA, based off of the `sandybridge` +sysimg version, and also excluding `rdrnd`. When a Julia implementation loads the +generated sysimg, it will check the host processor for matching CPU capability flags, +enabling the highest ISA level possible. Note that the base level (`generic`) requires +the `cx16` instruction, which is disabled in some virtualization software and must be +enabled for the `generic` target to be loaded. Alternatively, a sysimg could be generated +with the target `generic,-cx16` for greater compatibility, however note that this may cause +performance and stability problems in some code. + ### Implementation overview This is a brief overview of different part involved in the implementation. diff --git a/codex/manual/arrays.md b/codex/manual/arrays.md index 6119c49..ff9b803 100644 --- a/codex/manual/arrays.md +++ b/codex/manual/arrays.md @@ -801,7 +801,7 @@ elements are stored contiguously in column-major order (see additional notes in [Performance Tips](@ref man-performance-tips)). The [`Array`](@ref) type is a specific instance of `DenseArray`; [`Vector`](@ref) and [`Matrix`](@ref) are aliases for the 1-d and 2-d cases. Very few operations are implemented specifically for `Array` beyond those that are required -for all `AbstractArrays`s; much of the array library is implemented in a generic +for all `AbstractArray`s; much of the array library is implemented in a generic manner that allows all custom arrays to behave similarly. `SubArray` is a specialization of `AbstractArray` that performs indexing by diff --git a/codex/manual/faq.md b/codex/manual/faq.md index 5b4fa2f..e6ae749 100644 --- a/codex/manual/faq.md +++ b/codex/manual/faq.md @@ -637,6 +637,17 @@ julia> remotecall_fetch(anon_bar, 2) 1 ``` +### Why does Julia use `*` for string concatenation? Why not `+` or something else? + +The [main argument](@ref man-concatenation) against `+` is that string concatenation is not +commutative, while `+` is generally used as a commutative operator. While the Julia community +recognizes that other languages use different operators and `*` may be unfamiliar for some +users, it communicates certain algebraic properties. + +Note that you can also use `string(...)` to concatenate strings (and other values converted +to strings); similarly, `repeat` can be used instead of `^` to repeat strings. The +[interpolation syntax](@ref string-interpolation) is also useful for constructing strings. + ## Packages and Modules ### What is the difference between "using" and "import"? diff --git a/codex/manual/profile.md b/codex/manual/profile.md index e3403cd..a4e26ff 100644 --- a/codex/manual/profile.md +++ b/codex/manual/profile.md @@ -341,5 +341,5 @@ There are many more interesting things that you can measure about your program, please read the [Linux perf examples page](http://www.brendangregg.com/perf.html). Remember that perf saves for each execution a `perf.data` file that, even for small programs, can get -quite large. Also the perf LLVM module saves temporarly debug objects in `~/.debug/jit`, remember +quite large. Also the perf LLVM module saves temporarily debug objects in `~/.debug/jit`, remember to clean that folder frequently. diff --git a/codex/manual/strings.md b/codex/manual/strings.md index 304b3c2..9e3606c 100644 --- a/codex/manual/strings.md +++ b/codex/manual/strings.md @@ -404,7 +404,7 @@ further discussion of UTF-8 encoding issues, see the section below on [byte arra The [`transcode`](@ref) function is provided to convert data between the various UTF-xx encodings, primarily for working with external data and libraries. -## Concatenation +## [Concatenation](@id man-concatenation) One of the most common and useful string operations is concatenation: @@ -617,20 +617,21 @@ julia> "1 + 2 = 3" == "1 + 2 = $(1 + 2)" true ``` -You can search for the index of a particular character using the [`findfirst`](@ref) function: +You can search for the index of a particular character using the +[`findfirst`](@ref) and [`findlast`](@ref) functions: ```jldoctest -julia> findfirst(isequal('x'), "xylophone") -1 +julia> findfirst(isequal('o'), "xylophone") +4 -julia> findfirst(isequal('p'), "xylophone") -5 +julia> findlast(isequal('o'), "xylophone") +7 julia> findfirst(isequal('z'), "xylophone") ``` -You can start the search for a character at a given offset by using [`findnext`](@ref) -with a third argument: +You can start the search for a character at a given offset by using +the functions [`findnext`](@ref) and [`findprev`](@ref): ```jldoctest julia> findnext(isequal('o'), "xylophone", 1) @@ -639,6 +640,9 @@ julia> findnext(isequal('o'), "xylophone", 1) julia> findnext(isequal('o'), "xylophone", 5) 7 +julia> findprev(isequal('o'), "xylophone", 5) +4 + julia> findnext(isequal('o'), "xylophone", 8) ``` diff --git a/codex/manual/workflow-tips.md b/codex/manual/workflow-tips.md index 857822d..8cae4ce 100644 --- a/codex/manual/workflow-tips.md +++ b/codex/manual/workflow-tips.md @@ -8,45 +8,59 @@ As already elaborated in [The Julia REPL](@ref), Julia's REPL provides rich func that facilitates an efficient interactive workflow. Here are some tips that might further enhance your experience at the command line. -### A basic editor/REPL workflow +## Command-line-based basic editor/REPL workflow The most basic Julia workflows involve using a text editor in conjunction with the `julia` command line. A common pattern includes the following elements: - * **Put code under development in a temporary module.** Create a file, say `Tmp.jl`, and include - within it + * **Generate a new project** + + ``` + $ julia -e 'using Pkg;Pkg.generate("Tmp")' +Generating project Tmp: + Tmp/Project.toml + Tmp/src/Tmp.jl + $ ls -R Tmp +Tmp: +Project.toml src + +Tmp/src: +Tmp.jl + $ cat -n Tmp/src/Tmp.jl + 1 module Tmp + 2 + 3 greet() = print("Hello World!") + 4 + 5 end # module + ``` + + * **Create a test folder** + ``` + $ mkdir Tmp/test + ``` + * **Put your test code in `test/runtests.jl` file.** ``` - module Tmp - - - - end - ``` - * **Put your test code in another file.** Create another file, say `tst.jl`, which begins with - - ```julia - import Tmp + $ cat -n Tmp/test/runtests.jl + 1 using Tmp + 2 Tmp.greet() ``` - and includes tests for the contents of `Tmp`. - Alternatively, you can wrap the contents of your test file in a module, as - - ``` - module Tst - using Tmp - - - - end - ``` - - The advantage is that you can now do `using Tmp` in your test code and can therefore avoid prepending - `Tmp.` everywhere. The disadvantage is that code can no longer be selectively copied to the REPL - without some tweaking. - * **Lather. Rinse. Repeat.** Explore ideas at the `julia` command prompt. Save good ideas in `tst.jl`. - -### Simplify initialization + * **Run test** + ``` + $ julia -e 'using Pkg;Pkg.activate("Tmp");Pkg.test()' + Updating registry at `~/.julia/registries/General` + Updating git-repo `https://github.com/JuliaRegistries/General.git` + Resolving package versions... + Updating `~/Tmp/Project.toml` + [no changes] + Testing Tmp + Resolving package versions... +Hello World! Testing Tmp tests passed + ``` + * **Lather. Rinse. Repeat.** Explore ideas at the `julia` command prompt. Save good ideas in `Tmp.jl` and test with `runtests.jl`. + +## Simplify initialization To simplify restarting the REPL, put project-specific initialization code in a file, say `_init.jl`, which you can run on startup by issuing the command: diff --git a/codex/stdlib/Dates.md b/codex/stdlib/Dates.md index dc2e7bd..bb0a9f2 100644 --- a/codex/stdlib/Dates.md +++ b/codex/stdlib/Dates.md @@ -511,7 +511,8 @@ it could represent, in days, a value of 28, 29, 30, or 31 depending on the year Or a year could represent 365 or 366 days in the case of a leap year. [`Period`](@ref) types are simple [`Int64`](@ref) wrappers and are constructed by wrapping any `Int64` convertible type, i.e. `Year(1)` or `Month(3.0)`. Arithmetic between [`Period`](@ref) of the same type behave like integers, and -limited `Period-Real` arithmetic is available. +limited `Period-Real` arithmetic is available. You can extract the underlying integer with +[`Dates.value`](@ref). ```jldoctest julia> y1 = Dates.Year(1) @@ -537,6 +538,9 @@ julia> y3 % y2 julia> div(y3,3) # mirrors integer division 3 years + +julia> Dates.value(Dates.Millisecond(10)) +10 ``` ## Rounding @@ -740,6 +744,7 @@ Dates.toprev(::Function, ::Dates.TimeType) ```@docs Dates.Period(::Any) Dates.CompoundPeriod(::Vector{<:Dates.Period}) +Dates.value Dates.default ``` diff --git a/src/base/base.md b/src/base/base.md index 0567e93..e8481b7 100644 --- a/src/base/base.md +++ b/src/base/base.md @@ -199,6 +199,7 @@ Core.NamedTuple Base.Val Core.Vararg Core.Nothing +Base.isnothing Base.Some Base.something Base.Enums.@enum diff --git a/src/devdocs/sysimg.md b/src/devdocs/sysimg.md index 4ca11cf..6c12278 100644 --- a/src/devdocs/sysimg.md +++ b/src/devdocs/sysimg.md @@ -46,16 +46,16 @@ under the same instruction set architecture (ISA). Multiple versions of the same may be created with minimum dispatch point inserted into shared functions in order to take advantage of different ISA extensions or other microarchitecture features. The version that offers the best performance will be selected automatically at runtime -based on available features. +based on available CPU features. ### Specifying multiple system image targets -Multi-microarch system image can be enabled by passing multiple targets +A multi-microarchitecture system image can be enabled by passing multiple targets during system image compilation. This can be done either with the `JULIA_CPU_TARGET` make option or with the `-C` command line option when running the compilation command manually. -Multiple targets are separated by `;` in the option. +Multiple targets are separated by `;` in the option string. The syntax for each target is a CPU name followed by multiple features separated by `,`. -All features supported by LLVM is supported and a feature can be disabled with a `-` prefix. +All features supported by LLVM are supported and a feature can be disabled with a `-` prefix. (`+` prefix is also allowed and ignored to be consistent with LLVM syntax). Additionally, a few special features are supported to control the function cloning behavior. @@ -76,7 +76,7 @@ Additionally, a few special features are supported to control the function cloni This behavior can be changed by specifying a different base with the `base()` option. The `n`th target (0-based) will be used as the base target instead of the default (`0`th) one. The base target has to be either `0` or another `clone_all` target. - Specifying a non default `clone_all` target as the base target will cause an error. + Specifying a non-`clone_all` target as the base target will cause an error. 3. `opt_size` @@ -88,6 +88,24 @@ Additionally, a few special features are supported to control the function cloni This cause the function for the targe to be optimize for size that might have a significant runtime performance impact. This corresponds to `-Oz` Clang option. +As an example, at the time of this writing, the following string is used in the creation of +the official `x86_64` Julia binaries downloadable from julialang.org: + +``` +generic;sandybridge,-xsaveopt,clone_all;haswell,-rdrnd,base(1) +``` + +This creates a system image with three separate targets; one for a generic `x86_64` +processor, one with a `sandybridge` ISA (explicitly excluding `xsaveopt`) that explicitly +clones all functions, and one targeting the `haswell` ISA, based off of the `sandybridge` +sysimg version, and also excluding `rdrnd`. When a Julia implementation loads the +generated sysimg, it will check the host processor for matching CPU capability flags, +enabling the highest ISA level possible. Note that the base level (`generic`) requires +the `cx16` instruction, which is disabled in some virtualization software and must be +enabled for the `generic` target to be loaded. Alternatively, a sysimg could be generated +with the target `generic,-cx16` for greater compatibility, however note that this may cause +performance and stability problems in some code. + ### Implementation overview This is a brief overview of different part involved in the implementation. diff --git a/src/manual/arrays.md b/src/manual/arrays.md index ace483f..33dfded 100644 --- a/src/manual/arrays.md +++ b/src/manual/arrays.md @@ -748,7 +748,7 @@ elements are stored contiguously in column-major order (see additional notes in [Performance Tips](@ref man-performance-tips)). The [`Array`](@ref) type is a specific instance of `DenseArray`; [`Vector`](@ref) and [`Matrix`](@ref) are aliases for the 1-d and 2-d cases. Very few operations are implemented specifically for `Array` beyond those that are required -for all `AbstractArrays`s; much of the array library is implemented in a generic +for all `AbstractArray`s; much of the array library is implemented in a generic manner that allows all custom arrays to behave similarly. `SubArray` is a specialization of `AbstractArray` that performs indexing by diff --git a/src/manual/faq.md b/src/manual/faq.md index 5b4fa2f..e6ae749 100644 --- a/src/manual/faq.md +++ b/src/manual/faq.md @@ -637,6 +637,17 @@ julia> remotecall_fetch(anon_bar, 2) 1 ``` +### Why does Julia use `*` for string concatenation? Why not `+` or something else? + +The [main argument](@ref man-concatenation) against `+` is that string concatenation is not +commutative, while `+` is generally used as a commutative operator. While the Julia community +recognizes that other languages use different operators and `*` may be unfamiliar for some +users, it communicates certain algebraic properties. + +Note that you can also use `string(...)` to concatenate strings (and other values converted +to strings); similarly, `repeat` can be used instead of `^` to repeat strings. The +[interpolation syntax](@ref string-interpolation) is also useful for constructing strings. + ## Packages and Modules ### What is the difference between "using" and "import"? diff --git a/src/manual/profile.md b/src/manual/profile.md index e3403cd..a4e26ff 100644 --- a/src/manual/profile.md +++ b/src/manual/profile.md @@ -341,5 +341,5 @@ There are many more interesting things that you can measure about your program, please read the [Linux perf examples page](http://www.brendangregg.com/perf.html). Remember that perf saves for each execution a `perf.data` file that, even for small programs, can get -quite large. Also the perf LLVM module saves temporarly debug objects in `~/.debug/jit`, remember +quite large. Also the perf LLVM module saves temporarily debug objects in `~/.debug/jit`, remember to clean that folder frequently. diff --git a/src/manual/strings.md b/src/manual/strings.md index 304b3c2..9e3606c 100644 --- a/src/manual/strings.md +++ b/src/manual/strings.md @@ -404,7 +404,7 @@ further discussion of UTF-8 encoding issues, see the section below on [byte arra The [`transcode`](@ref) function is provided to convert data between the various UTF-xx encodings, primarily for working with external data and libraries. -## Concatenation +## [Concatenation](@id man-concatenation) One of the most common and useful string operations is concatenation: @@ -617,20 +617,21 @@ julia> "1 + 2 = 3" == "1 + 2 = $(1 + 2)" true ``` -You can search for the index of a particular character using the [`findfirst`](@ref) function: +You can search for the index of a particular character using the +[`findfirst`](@ref) and [`findlast`](@ref) functions: ```jldoctest -julia> findfirst(isequal('x'), "xylophone") -1 +julia> findfirst(isequal('o'), "xylophone") +4 -julia> findfirst(isequal('p'), "xylophone") -5 +julia> findlast(isequal('o'), "xylophone") +7 julia> findfirst(isequal('z'), "xylophone") ``` -You can start the search for a character at a given offset by using [`findnext`](@ref) -with a third argument: +You can start the search for a character at a given offset by using +the functions [`findnext`](@ref) and [`findprev`](@ref): ```jldoctest julia> findnext(isequal('o'), "xylophone", 1) @@ -639,6 +640,9 @@ julia> findnext(isequal('o'), "xylophone", 1) julia> findnext(isequal('o'), "xylophone", 5) 7 +julia> findprev(isequal('o'), "xylophone", 5) +4 + julia> findnext(isequal('o'), "xylophone", 8) ``` diff --git a/src/manual/workflow-tips.md b/src/manual/workflow-tips.md index 857822d..8cae4ce 100644 --- a/src/manual/workflow-tips.md +++ b/src/manual/workflow-tips.md @@ -8,45 +8,59 @@ As already elaborated in [The Julia REPL](@ref), Julia's REPL provides rich func that facilitates an efficient interactive workflow. Here are some tips that might further enhance your experience at the command line. -### A basic editor/REPL workflow +## Command-line-based basic editor/REPL workflow The most basic Julia workflows involve using a text editor in conjunction with the `julia` command line. A common pattern includes the following elements: - * **Put code under development in a temporary module.** Create a file, say `Tmp.jl`, and include - within it + * **Generate a new project** + + ``` + $ julia -e 'using Pkg;Pkg.generate("Tmp")' +Generating project Tmp: + Tmp/Project.toml + Tmp/src/Tmp.jl + $ ls -R Tmp +Tmp: +Project.toml src + +Tmp/src: +Tmp.jl + $ cat -n Tmp/src/Tmp.jl + 1 module Tmp + 2 + 3 greet() = print("Hello World!") + 4 + 5 end # module + ``` + + * **Create a test folder** + ``` + $ mkdir Tmp/test + ``` + * **Put your test code in `test/runtests.jl` file.** ``` - module Tmp - - - - end - ``` - * **Put your test code in another file.** Create another file, say `tst.jl`, which begins with - - ```julia - import Tmp + $ cat -n Tmp/test/runtests.jl + 1 using Tmp + 2 Tmp.greet() ``` - and includes tests for the contents of `Tmp`. - Alternatively, you can wrap the contents of your test file in a module, as - - ``` - module Tst - using Tmp - - - - end - ``` - - The advantage is that you can now do `using Tmp` in your test code and can therefore avoid prepending - `Tmp.` everywhere. The disadvantage is that code can no longer be selectively copied to the REPL - without some tweaking. - * **Lather. Rinse. Repeat.** Explore ideas at the `julia` command prompt. Save good ideas in `tst.jl`. - -### Simplify initialization + * **Run test** + ``` + $ julia -e 'using Pkg;Pkg.activate("Tmp");Pkg.test()' + Updating registry at `~/.julia/registries/General` + Updating git-repo `https://github.com/JuliaRegistries/General.git` + Resolving package versions... + Updating `~/Tmp/Project.toml` + [no changes] + Testing Tmp + Resolving package versions... +Hello World! Testing Tmp tests passed + ``` + * **Lather. Rinse. Repeat.** Explore ideas at the `julia` command prompt. Save good ideas in `Tmp.jl` and test with `runtests.jl`. + +## Simplify initialization To simplify restarting the REPL, put project-specific initialization code in a file, say `_init.jl`, which you can run on startup by issuing the command: diff --git a/src/stdlib/Dates.md b/src/stdlib/Dates.md index dc2e7bd..bb0a9f2 100644 --- a/src/stdlib/Dates.md +++ b/src/stdlib/Dates.md @@ -511,7 +511,8 @@ it could represent, in days, a value of 28, 29, 30, or 31 depending on the year Or a year could represent 365 or 366 days in the case of a leap year. [`Period`](@ref) types are simple [`Int64`](@ref) wrappers and are constructed by wrapping any `Int64` convertible type, i.e. `Year(1)` or `Month(3.0)`. Arithmetic between [`Period`](@ref) of the same type behave like integers, and -limited `Period-Real` arithmetic is available. +limited `Period-Real` arithmetic is available. You can extract the underlying integer with +[`Dates.value`](@ref). ```jldoctest julia> y1 = Dates.Year(1) @@ -537,6 +538,9 @@ julia> y3 % y2 julia> div(y3,3) # mirrors integer division 3 years + +julia> Dates.value(Dates.Millisecond(10)) +10 ``` ## Rounding @@ -740,6 +744,7 @@ Dates.toprev(::Function, ::Dates.TimeType) ```@docs Dates.Period(::Any) Dates.CompoundPeriod(::Vector{<:Dates.Period}) +Dates.value Dates.default ``` From f6b44d9eaa07087358d98b562052ddb2f03bfef8 Mon Sep 17 00:00:00 2001 From: zmfkzj <33181709+zmfkzj@users.noreply.github.com> Date: Thu, 25 Oct 2018 01:16:28 +0900 Subject: [PATCH 065/153] Update variables.md --- src/manual/variables.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/manual/variables.md b/src/manual/variables.md index b143498..325ea2b 100644 --- a/src/manual/variables.md +++ b/src/manual/variables.md @@ -55,9 +55,7 @@ julia> 안녕하세요 = "Hello" "Hello" ``` - a REPL 및 다른 여러 줄리아 편집 환경에서 많은 유니 코드 수학을 입력 할 수 있습>니다 백 슬래쉬 된 LaTeX 심볼 이름 다음에 탭을 입력하여 심볼을 제거하십시오.예를 를어 `TeX 심볼 이름 다음에 탭을 입력하여 심볼을 제거하십시오. 예를 들어, 변수 `delta`- * tab *을 입력하거나`\ alpha`- * tab * -` \ hat`- -* tab * -`\ _2` - * tab *. 다른 사람의 코드와 같이 기호를 어딘가에서 찾으면 -당신이 입력하는 방법을 모르겠다면, REPL 도움말은 당신에게 말할 것입니다 + a REPL 및 다른 여러 줄리아 편집 환경에서 많은 유니 코드 수학 기호를 입력 할 수 있습니다. 백 슬래쉬 + LaTeX 심볼 이름 다음에 탭을 입력하여 심볼을 입력하십시오.예를 를어 변수명 δ는 `\delta`-tab, `α^²`는 `\alpha`-tab-`\hat`-tab-`\_2`-tab 으로 입력할 수 있습니다. 어떤 기호를 입력하는 방법은 REPL에서 ?(help 호출)를 입력 후 원하는 유니코드 기호를 붙여넣기하여 알 수 있습니다. julia> pi = 3 3 From d487d60c87e75374bcc94d8f69153938d6f0b220 Mon Sep 17 00:00:00 2001 From: zmfkzj <33181709+zmfkzj@users.noreply.github.com> Date: Thu, 25 Oct 2018 01:54:15 +0900 Subject: [PATCH 066/153] =?UTF-8?q?=EB=88=84=EB=9D=BD=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 누락된 설명 추가, 잘못된 상자 수정 --- src/manual/variables.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/manual/variables.md b/src/manual/variables.md index b143498..464691a 100644 --- a/src/manual/variables.md +++ b/src/manual/variables.md @@ -59,6 +59,9 @@ julia> 안녕하세요 = "Hello" * tab * -`\ _2` - * tab *. 다른 사람의 코드와 같이 기호를 어딘가에서 찾으면 당신이 입력하는 방법을 모르겠다면, REPL 도움말은 당신에게 말할 것입니다 + +julia는 심지어 내장 상수와 함수조차도 필요하다면 재정의합니다.(잠재적인 혼란을 피하기 위해 추천하지는 않습니다.) +``` julia> pi = 3 3 @@ -69,8 +72,7 @@ julia> sqrt = 4 4 ``` -그러나 이미 사용중인 내장 상수 또는 기능을 다시 정의하려고하면 -julia는 다음과같은 에러를 낼것이다 +그러나 이미 사용중인 내장 상수와 함수을 다시 정의하려고하면 julia는 다음과같은 에러를 낼것이다 ```jldoctest julia> pi @@ -89,11 +91,10 @@ ERROR: cannot assign variable Base.sqrt from module Main ##허용된 변수 이름 -변수 이름은 문자 (A-Z 또는 a-z), 밑줄 또는 유니 코드 코드의 하위 집합으로 시작해 -야합니다 -00A0보다 큰 점; 특히 [유니 코드 문자 범주] (http://www.fileformat.info/info/unicode/category/index.htm) +변수 이름은 문자 (A-Z 또는 a-z), 밑줄 또는 00A0보다 큰 유니 코드 코드의 하위 집합으로 시작해 +야합니다. 특히 [유니 코드 문자 범주] (http://www.fileformat.info/info/unicode/category/index.htm) Lu / Ll / Lt / Lm / Lo / Nl (문자), Sc / So (통화 및 기타 기호) 및 기타 문자와 >유사한 문자 -(예 : Sm 수학 기호의 서브 세트)이 허용됩니다. 그 다음 문자는 +(예 : Sm 수학 기호의 서브 세트)이 허용됩니다. 그 다음 문자는 !와 숫자 (0-9 및 Nd / No 범주의 다른 문자) 및 기타 유니 코드 코드 포인트 : 발음 구별 기호 및 기타 수정 표시 (Mn / Mc / Me / Sk 범주), 일부 구두점 커넥터 (범주 Pc), From 7a1b579394295cfce2484bdab3df428af46f85db Mon Sep 17 00:00:00 2001 From: zmfkzj <33181709+zmfkzj@users.noreply.github.com> Date: Thu, 25 Oct 2018 01:59:58 +0900 Subject: [PATCH 067/153] Update variables.md --- src/manual/variables.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/manual/variables.md b/src/manual/variables.md index 325ea2b..5e76ccf 100644 --- a/src/manual/variables.md +++ b/src/manual/variables.md @@ -55,7 +55,7 @@ julia> 안녕하세요 = "Hello" "Hello" ``` - a REPL 및 다른 여러 줄리아 편집 환경에서 많은 유니 코드 수학 기호를 입력 할 수 있습니다. 백 슬래쉬 + LaTeX 심볼 이름 다음에 탭을 입력하여 심볼을 입력하십시오.예를 를어 변수명 δ는 `\delta`-tab, `α^²`는 `\alpha`-tab-`\hat`-tab-`\_2`-tab 으로 입력할 수 있습니다. 어떤 기호를 입력하는 방법은 REPL에서 ?(help 호출)를 입력 후 원하는 유니코드 기호를 붙여넣기하여 알 수 있습니다. + REPL 및 다른 여러 줄리아 편집 환경에서 많은 유니 코드 수학 기호를 입력 할 수 있습니다. 백 슬래쉬 + LaTeX 심볼 이름 다음에 탭을 입력하여 심볼을 입력하십시오.예를 를어 변수명 δ는 `\delta`-tab, `α^²`는 `\alpha`-tab-`\hat`-tab-`\_2`-tab 으로 입력할 수 있습니다. 어떤 기호를 입력하는 방법은 REPL에서 ?(help 호출)를 입력 후 원하는 유니코드 기호를 붙여넣기하여 알 수 있습니다. julia> pi = 3 3 From e4a96a075b296ed24bfb98ed09d856560f7be053 Mon Sep 17 00:00:00 2001 From: zmfkzj <33181709+zmfkzj@users.noreply.github.com> Date: Thu, 25 Oct 2018 02:12:42 +0900 Subject: [PATCH 068/153] Update variables.md --- src/manual/variables.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/manual/variables.md b/src/manual/variables.md index 5e76ccf..92c93b7 100644 --- a/src/manual/variables.md +++ b/src/manual/variables.md @@ -55,7 +55,7 @@ julia> 안녕하세요 = "Hello" "Hello" ``` - REPL 및 다른 여러 줄리아 편집 환경에서 많은 유니 코드 수학 기호를 입력 할 수 있습니다. 백 슬래쉬 + LaTeX 심볼 이름 다음에 탭을 입력하여 심볼을 입력하십시오.예를 를어 변수명 δ는 `\delta`-tab, `α^²`는 `\alpha`-tab-`\hat`-tab-`\_2`-tab 으로 입력할 수 있습니다. 어떤 기호를 입력하는 방법은 REPL에서 ?(help 호출)를 입력 후 원하는 유니코드 기호를 붙여넣기하여 알 수 있습니다. +REPL 및 다른 여러 줄리아 편집 환경에서 많은 유니코드 수학 기호를 입력 할 수 있습니다. 백 슬래쉬 + LaTeX 기호명 다음에 탭을 입력하여 기호를 입력하십시오. 예를 들어 변수명 δ는 `\delta`-tab, `α^²`는 `\alpha`-tab-`\hat`-tab-`\_2`-tab 으로 입력할 수 있습니다. 어떤 기호를 입력하는 방법은 REPL에서 ?(help 호출)를 입력 후 원하는 유니코드 기호를 붙여넣기하여 알 수 있습니다. julia> pi = 3 3 From 6eefa985a907c3a55b9e41fb0cac7aa83b3932fe Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Thu, 25 Oct 2018 15:45:50 +0900 Subject: [PATCH 069/153] update Julia Commit 36e21d47b5 --- codex/base/base.md | 3 ++- codex/devdocs/ast.md | 10 ++++--- codex/manual/control-flow.md | 4 +-- codex/manual/getting-started.md | 1 + codex/manual/stacktraces.md | 47 +++++++++++++++++++++++++++++++++ src/base/base.md | 3 ++- src/devdocs/ast.md | 10 ++++--- src/manual/control-flow.md | 2 +- src/manual/getting-started.md | 1 + src/manual/stacktraces.md | 47 +++++++++++++++++++++++++++++++++ 10 files changed, 117 insertions(+), 11 deletions(-) diff --git a/codex/base/base.md b/codex/base/base.md index e8481b7..4eebbd7 100644 --- a/codex/base/base.md +++ b/codex/base/base.md @@ -49,7 +49,7 @@ The following two-word sequences are reserved: However, you can create variables with names: `abstract`, `mutable`, `primitive` and `type`. -Finally `where` is parsed as an infix operator for writing parametric method +Finally,`where` is parsed as an infix operator for writing parametric method and type definitions. Also `in` and `isa` are parsed as infix operators. Creation of a variable named `where`, `in` or `isa` is allowed though. @@ -304,6 +304,7 @@ Core.throw Base.rethrow Base.backtrace Base.catch_backtrace +Base.catch_stack Base.@assert Base.ArgumentError Base.AssertionError diff --git a/codex/devdocs/ast.md b/codex/devdocs/ast.md index 8669b0f..699a2b0 100644 --- a/codex/devdocs/ast.md +++ b/codex/devdocs/ast.md @@ -142,18 +142,22 @@ These symbols appear in the `head` field of `Expr`s in lowered form. * `the_exception` - Yields the caught exception inside a `catch` block. This is the value of the run time system variable - `jl_exception_in_transit`. + Yields the caught exception inside a `catch` block, as returned by `jl_current_exception()`. * `enter` Enters an exception handler (`setjmp`). `args[1]` is the label of the catch block to jump to on - error. + error. Yields a token which is consumed by `pop_exception`. * `leave` Pop exception handlers. `args[1]` is the number of handlers to pop. + * `pop_exception` + + Pop the stack of current exceptions back to the state at the associated `enter` when leaving a + catch block. `args[1]` contains the token from the associated `enter`. + * `inbounds` Controls turning bounds checks on or off. A stack is maintained; if the first argument of this diff --git a/codex/manual/control-flow.md b/codex/manual/control-flow.md index f73e523..9de3b82 100644 --- a/codex/manual/control-flow.md +++ b/codex/manual/control-flow.md @@ -793,8 +793,8 @@ end The power of the `try/catch` construct lies in the ability to unwind a deeply nested computation immediately to a much higher level in the stack of calling functions. There are situations where no error has occurred, but the ability to unwind the stack and pass a value to a higher level -is desirable. Julia provides the [`rethrow`](@ref), [`backtrace`](@ref) and [`catch_backtrace`](@ref) -functions for more advanced error handling. +is desirable. Julia provides the [`rethrow`](@ref), [`backtrace`](@ref), [`catch_backtrace`](@ref) +and [`catch_stack`](@ref) functions for more advanced error handling. ### `finally` Clauses diff --git a/codex/manual/getting-started.md b/codex/manual/getting-started.md index 530fe44..7e7ba3c 100644 --- a/codex/manual/getting-started.md +++ b/codex/manual/getting-started.md @@ -95,6 +95,7 @@ julia [switches] -- [programfile] [args...] |:--- |:---| |`-v`, `--version` |Display version information| |`-h`, `--help` |Print this message| +|`--project[={

|@.}]` |Set as the home project/environment. The default @. option will search through parent directories until a Project.toml or JuliaProject.toml file is found. |`-J`, `--sysimage ` |Start up with the given system image file| |`-H`, `--home ` |Set location of `julia` executable| |`--startup-file={yes\|no}` |Load `~/.julia/config/startup.jl`| diff --git a/codex/manual/stacktraces.md b/codex/manual/stacktraces.md index 776570d..a7da7a6 100644 --- a/codex/manual/stacktraces.md +++ b/codex/manual/stacktraces.md @@ -187,6 +187,53 @@ ERROR: Whoops! [...] ``` +## Exception stacks and [`catch_stack`](@ref) + +While handling an exception further exceptions may be thrown. It can be useful to inspect all these exceptions to +identify the root cause of a problem. The julia runtime supports this by pushing each exception onto an internal +*exception stack* as it occurs. When the code exits a `catch` normally, any exceptions which were pushed onto the stack +in the associated `try` are considered to be successfully handled and are removed from the stack. + +The stack of current exceptions can be accessed using the [`catch_stack`](@ref) function. For example, + +```julia-repl +julia> try + error("(A) The root cause") + catch + try + error("(B) An exception while handling the exception") + catch + for (exc, bt) in catch_stack() + showerror(stdout, exc, bt) + println() + end + end + end +(A) The root cause +Stacktrace: + [1] error(::String) at error.jl:33 + [2] top-level scope at REPL[7]:2 + [3] eval(::Module, ::Any) at boot.jl:319 + [4] eval_user_input(::Any, ::REPL.REPLBackend) at REPL.jl:85 + [5] macro expansion at REPL.jl:117 [inlined] + [6] (::getfield(REPL, Symbol("##26#27")){REPL.REPLBackend})() at task.jl:259 +(B) An exception while handling the exception +Stacktrace: + [1] error(::String) at error.jl:33 + [2] top-level scope at REPL[7]:5 + [3] eval(::Module, ::Any) at boot.jl:319 + [4] eval_user_input(::Any, ::REPL.REPLBackend) at REPL.jl:85 + [5] macro expansion at REPL.jl:117 [inlined] + [6] (::getfield(REPL, Symbol("##26#27")){REPL.REPLBackend})() at task.jl:259 +``` + +In this example the root cause exception (A) is first on the stack, with a further exception (B) following it. After +exiting both catch blocks normally (i.e., without throwing a further exception) all exceptions are removed from the stack +and are no longer accessible. + +The exception stack is stored on the `Task` where the exceptions occurred. When a task fails with uncaught exceptions, +`catch_stack(task)` may be used to inspect the exception stack for that task. + ## Comparison with [`backtrace`](@ref) A call to [`backtrace`](@ref) returns a vector of `Union{Ptr{Nothing}, Base.InterpreterIP}`, which may then be passed into diff --git a/src/base/base.md b/src/base/base.md index e8481b7..4eebbd7 100644 --- a/src/base/base.md +++ b/src/base/base.md @@ -49,7 +49,7 @@ The following two-word sequences are reserved: However, you can create variables with names: `abstract`, `mutable`, `primitive` and `type`. -Finally `where` is parsed as an infix operator for writing parametric method +Finally,`where` is parsed as an infix operator for writing parametric method and type definitions. Also `in` and `isa` are parsed as infix operators. Creation of a variable named `where`, `in` or `isa` is allowed though. @@ -304,6 +304,7 @@ Core.throw Base.rethrow Base.backtrace Base.catch_backtrace +Base.catch_stack Base.@assert Base.ArgumentError Base.AssertionError diff --git a/src/devdocs/ast.md b/src/devdocs/ast.md index 8669b0f..699a2b0 100644 --- a/src/devdocs/ast.md +++ b/src/devdocs/ast.md @@ -142,18 +142,22 @@ These symbols appear in the `head` field of `Expr`s in lowered form. * `the_exception` - Yields the caught exception inside a `catch` block. This is the value of the run time system variable - `jl_exception_in_transit`. + Yields the caught exception inside a `catch` block, as returned by `jl_current_exception()`. * `enter` Enters an exception handler (`setjmp`). `args[1]` is the label of the catch block to jump to on - error. + error. Yields a token which is consumed by `pop_exception`. * `leave` Pop exception handlers. `args[1]` is the number of handlers to pop. + * `pop_exception` + + Pop the stack of current exceptions back to the state at the associated `enter` when leaving a + catch block. `args[1]` contains the token from the associated `enter`. + * `inbounds` Controls turning bounds checks on or off. A stack is maintained; if the first argument of this diff --git a/src/manual/control-flow.md b/src/manual/control-flow.md index d5d8119..335bf83 100644 --- a/src/manual/control-flow.md +++ b/src/manual/control-flow.md @@ -692,7 +692,7 @@ catch end ``` -`try/catch`문의 장점은 호출 함수의 스택에서 훨씬 더 높은 레벨로 깊게 중첩된 계산을 즉시 풀 수 있는 능력에 있습니다. 오류가 발생하지 않은 상황이 있지만 스택을 풀어 더 높은 레벨로 값을 전달하는 것이 바람직합니다. Julia는 고급 오류 처리를 위해 `rethrow`, `backtrace`, `catch_backtrace`와 같은 함수들을 제공합니다. +`try/catch`문의 장점은 호출 함수의 스택에서 훨씬 더 높은 레벨로 깊게 중첩된 계산을 즉시 풀 수 있는 능력에 있습니다. 오류가 발생하지 않은 상황이 있지만 스택을 풀어 더 높은 레벨로 값을 전달하는 것이 바람직합니다. Julia는 고급 오류 처리를 위해 `rethrow`, `backtrace`, `catch_backtrace` 그리고 [`catch_stack`](@ref)와 같은 함수들을 제공합니다. ### `finally`문 diff --git a/src/manual/getting-started.md b/src/manual/getting-started.md index 9e0d9a1..ff657fc 100644 --- a/src/manual/getting-started.md +++ b/src/manual/getting-started.md @@ -75,6 +75,7 @@ julia [switches] -- [programfile] [args...] |:--- |:---| |`-v`, `--version` |버전 정보를 표시한다| |`-h`, `--help` |이 메세지를 표시한다| +|`--project[={|@.}]` |Set as the home project/environment. The default @. option will search through parent directories until a Project.toml or JuliaProject.toml file is found.| |`-J`, `--sysimage ` |주어진 시스템 이미지 파일로 실행한다| |`-H`, `--home ` |`julia` 실행파일의 위치를 지정한다| |`--startup-file={yes\|no}` |`~/.julia/config/startup.jl` 를 불러온다| diff --git a/src/manual/stacktraces.md b/src/manual/stacktraces.md index 776570d..a7da7a6 100644 --- a/src/manual/stacktraces.md +++ b/src/manual/stacktraces.md @@ -187,6 +187,53 @@ ERROR: Whoops! [...] ``` +## Exception stacks and [`catch_stack`](@ref) + +While handling an exception further exceptions may be thrown. It can be useful to inspect all these exceptions to +identify the root cause of a problem. The julia runtime supports this by pushing each exception onto an internal +*exception stack* as it occurs. When the code exits a `catch` normally, any exceptions which were pushed onto the stack +in the associated `try` are considered to be successfully handled and are removed from the stack. + +The stack of current exceptions can be accessed using the [`catch_stack`](@ref) function. For example, + +```julia-repl +julia> try + error("(A) The root cause") + catch + try + error("(B) An exception while handling the exception") + catch + for (exc, bt) in catch_stack() + showerror(stdout, exc, bt) + println() + end + end + end +(A) The root cause +Stacktrace: + [1] error(::String) at error.jl:33 + [2] top-level scope at REPL[7]:2 + [3] eval(::Module, ::Any) at boot.jl:319 + [4] eval_user_input(::Any, ::REPL.REPLBackend) at REPL.jl:85 + [5] macro expansion at REPL.jl:117 [inlined] + [6] (::getfield(REPL, Symbol("##26#27")){REPL.REPLBackend})() at task.jl:259 +(B) An exception while handling the exception +Stacktrace: + [1] error(::String) at error.jl:33 + [2] top-level scope at REPL[7]:5 + [3] eval(::Module, ::Any) at boot.jl:319 + [4] eval_user_input(::Any, ::REPL.REPLBackend) at REPL.jl:85 + [5] macro expansion at REPL.jl:117 [inlined] + [6] (::getfield(REPL, Symbol("##26#27")){REPL.REPLBackend})() at task.jl:259 +``` + +In this example the root cause exception (A) is first on the stack, with a further exception (B) following it. After +exiting both catch blocks normally (i.e., without throwing a further exception) all exceptions are removed from the stack +and are no longer accessible. + +The exception stack is stored on the `Task` where the exceptions occurred. When a task fails with uncaught exceptions, +`catch_stack(task)` may be used to inspect the exception stack for that task. + ## Comparison with [`backtrace`](@ref) A call to [`backtrace`](@ref) returns a vector of `Union{Ptr{Nothing}, Base.InterpreterIP}`, which may then be passed into From 100a469e06df0993e8e6663ac714c8e5bcd80a07 Mon Sep 17 00:00:00 2001 From: zmfkzj <33181709+zmfkzj@users.noreply.github.com> Date: Thu, 25 Oct 2018 15:51:31 +0900 Subject: [PATCH 070/153] Update variables.md --- src/manual/variables.md | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/manual/variables.md b/src/manual/variables.md index 464691a..10361f1 100644 --- a/src/manual/variables.md +++ b/src/manual/variables.md @@ -72,7 +72,7 @@ julia> sqrt = 4 4 ``` -그러나 이미 사용중인 내장 상수와 함수을 다시 정의하려고하면 julia는 다음과같은 에러를 낼것이다 +그러나 이미 사용 중인 내장 상수와 함수를 다시 정의하려고 하면 julia는 다음과 같은 에러를 냅니다. ```jldoctest julia> pi @@ -91,14 +91,7 @@ ERROR: cannot assign variable Base.sqrt from module Main ##허용된 변수 이름 -변수 이름은 문자 (A-Z 또는 a-z), 밑줄 또는 00A0보다 큰 유니 코드 코드의 하위 집합으로 시작해 -야합니다. 특히 [유니 코드 문자 범주] (http://www.fileformat.info/info/unicode/category/index.htm) -Lu / Ll / Lt / Lm / Lo / Nl (문자), Sc / So (통화 및 기타 기호) 및 기타 문자와 >유사한 문자 -(예 : Sm 수학 기호의 서브 세트)이 허용됩니다. 그 다음 문자는 !와 -숫자 (0-9 및 Nd / No 범주의 다른 문자) 및 기타 유니 코드 코드 포인트 : 발음 구별 - 기호 -및 기타 수정 표시 (Mn / Mc / Me / Sk 범주), 일부 구두점 커넥터 (범주 Pc), -소수 (primes) 및 몇 가지 다른 문자가 포함되어 있습니다. +변수 이름은 문자(A-Z 또는 a-z), 밑줄 또는 00A0보다 큰 유니코드 코드의 하위 집합으로 시작해야 합니다. 특히 [유니 코드 문자 범주] (http://www.fileformat.info/info/unicode/category/index.htm)Lu/Ll/Lt/Lm/Lo/Nl(문자), Sc/So(통화 및 기타 기호) 및 기타 문자와 유사한 문자(예 : Sm 수학 기호의 서브 세트)가 허용됩니다. 그다음 문자는 !와 숫자 (0-9 및 Nd/No 범주의 다른 문자) 및 기타 유니코드 코드 포인트(Mn/Mc/Me/Sk 범주의 발음 구별 기호 및 기타 수정 표시, Pc 범주의 일부 구두점 커넥터, 소수(primes) 및 몇 가지 다른 문자)가 포함되어 있습니다. `+`와 같은 연산자도 유효한 식별자이지만 특별히 구문 분석됩니다. 일부 상황에서는 연산자 변수와 마찬가지로 사용할 수 있습니다. 예를 들어`(+)`는 더하기 함수를,`(+) = f`는그것을 재 할당합니다. `⊕ '와 같은 대부분의 유니 코드 중온 연산자 (범주 Sm에서)는 From 2a8c3d76fd2ecf4a890c8a0100cd4a57d573b462 Mon Sep 17 00:00:00 2001 From: zmfkzj <33181709+zmfkzj@users.noreply.github.com> Date: Thu, 25 Oct 2018 15:56:15 +0900 Subject: [PATCH 071/153] Update variables.md --- src/manual/variables.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/manual/variables.md b/src/manual/variables.md index 92c93b7..178fcda 100644 --- a/src/manual/variables.md +++ b/src/manual/variables.md @@ -55,7 +55,7 @@ julia> 안녕하세요 = "Hello" "Hello" ``` -REPL 및 다른 여러 줄리아 편집 환경에서 많은 유니코드 수학 기호를 입력 할 수 있습니다. 백 슬래쉬 + LaTeX 기호명 다음에 탭을 입력하여 기호를 입력하십시오. 예를 들어 변수명 δ는 `\delta`-tab, `α^²`는 `\alpha`-tab-`\hat`-tab-`\_2`-tab 으로 입력할 수 있습니다. 어떤 기호를 입력하는 방법은 REPL에서 ?(help 호출)를 입력 후 원하는 유니코드 기호를 붙여넣기하여 알 수 있습니다. +REPL 및 다른 여러 줄리아 편집 환경에서 많은 유니코드 수학 기호를 입력 할 수 있습니다. 백 슬래쉬 - LaTeX 기호명 - 탭을 입력하면 기호로 변환됩니다. 예를 들어 변수명 δ는 `\delta`-tab, `α^²`는 `\alpha`-tab-`\hat`-tab-`\_2`-tab 으로 입력할 수 있습니다. 어떤 기호를 입력하는 방법은 REPL에서 ?(help 호출)를 입력 후 원하는 유니코드 기호를 붙여넣기하여 알 수 있습니다. julia> pi = 3 3 From 64b9e44c591839daa0587058059e000787da7721 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Thu, 25 Oct 2018 15:55:21 +0900 Subject: [PATCH 072/153] fix getting-started --- src/manual/getting-started.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/manual/getting-started.md b/src/manual/getting-started.md index ff657fc..8248cec 100644 --- a/src/manual/getting-started.md +++ b/src/manual/getting-started.md @@ -75,7 +75,7 @@ julia [switches] -- [programfile] [args...] |:--- |:---| |`-v`, `--version` |버전 정보를 표시한다| |`-h`, `--help` |이 메세지를 표시한다| -|`--project[={|@.}]` |Set as the home project/environment. The default @. option will search through parent directories until a Project.toml or JuliaProject.toml file is found.| +|`--project[={\|@.}]` |Set as the home project/environment. The default @. option will search through parent directories until a Project.toml or JuliaProject.toml file is found.| |`-J`, `--sysimage ` |주어진 시스템 이미지 파일로 실행한다| |`-H`, `--home ` |`julia` 실행파일의 위치를 지정한다| |`--startup-file={yes\|no}` |`~/.julia/config/startup.jl` 를 불러온다| From c1ddabd496da65f7c962c09189b8bab89754deaa Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Tue, 30 Oct 2018 07:13:13 +0900 Subject: [PATCH 073/153] update Julia Commit aa72f72d6f --- codex/manual/calling-c-and-fortran-code.md | 2 +- codex/manual/getting-started.md | 2 +- codex/manual/interfaces.md | 6 ++-- codex/manual/variables-and-scoping.md | 33 +++++++--------------- codex/stdlib/Pkg.md | 16 +++++------ src/manual/calling-c-and-fortran-code.md | 2 +- src/manual/interfaces.md | 6 ++-- src/manual/variables-and-scoping.md | 33 +++++++--------------- src/stdlib/Pkg.md | 16 +++++------ 9 files changed, 45 insertions(+), 71 deletions(-) diff --git a/codex/manual/calling-c-and-fortran-code.md b/codex/manual/calling-c-and-fortran-code.md index 8c35495..54ae0f1 100644 --- a/codex/manual/calling-c-and-fortran-code.md +++ b/codex/manual/calling-c-and-fortran-code.md @@ -496,7 +496,7 @@ b_a_2 = B.A[2]; in Julia: ```julia struct B - A::NTuple{3, CInt} + A::NTuple{3, Cint} end b_a_2 = B.A[3] # note the difference in indexing (1-based in Julia, 0-based in C) ``` diff --git a/codex/manual/getting-started.md b/codex/manual/getting-started.md index 7e7ba3c..9e5d55a 100644 --- a/codex/manual/getting-started.md +++ b/codex/manual/getting-started.md @@ -95,7 +95,7 @@ julia [switches] -- [programfile] [args...] |:--- |:---| |`-v`, `--version` |Display version information| |`-h`, `--help` |Print this message| -|`--project[={|@.}]` |Set as the home project/environment. The default @. option will search through parent directories until a Project.toml or JuliaProject.toml file is found. +|`--project[={\|@.}]` |Set as the home project/environment. The default @. option will search through parent directories until a Project.toml or JuliaProject.toml file is found.| |`-J`, `--sysimage ` |Start up with the given system image file| |`-H`, `--home ` |Set location of `julia` executable| |`--startup-file={yes\|no}` |Load `~/.julia/config/startup.jl`| diff --git a/codex/manual/interfaces.md b/codex/manual/interfaces.md index db69514..e4c2bb0 100644 --- a/codex/manual/interfaces.md +++ b/codex/manual/interfaces.md @@ -235,8 +235,8 @@ ourselves, we can officially define it as a subtype of an [`AbstractArray`](@ref | `similar(A, ::Type{S}, dims::Dims)` | `Array{S}(undef, dims)` | Return a mutable array with the specified element type and size | | **Non-traditional indices** | **Default definition** | **Brief description** | | `axes(A)` | `map(OneTo, size(A))` | Return the `AbstractUnitRange` of valid indices | -| `Base.similar(A, ::Type{S}, inds)` | `similar(A, S, Base.to_shape(inds))` | Return a mutable array with the specified indices `inds` (see below) | -| `Base.similar(T::Union{Type,Function}, inds)` | `T(Base.to_shape(inds))` | Return an array similar to `T` with the specified indices `inds` (see below) | +| `similar(A, ::Type{S}, inds)` | `similar(A, S, Base.to_shape(inds))` | Return a mutable array with the specified indices `inds` (see below) | +| `similar(T::Union{Type,Function}, inds)` | `T(Base.to_shape(inds))` | Return an array similar to `T` with the specified indices `inds` (see below) | If a type is defined as a subtype of `AbstractArray`, it inherits a very large set of rich behaviors including iteration and multidimensional indexing built on top of single-element access. See @@ -406,7 +406,7 @@ perhaps range-types `Ind` of your own design. For more information, see | Methods to implement |   | Brief description | |:----------------------------------------------- |:-------------------------------------- |:------------------------------------------------------------------------------------- | | `strides(A)` |   | Return the distance in memory (in number of elements) between adjacent elements in each dimension as a tuple. If `A` is an `AbstractArray{T,0}`, this should return an empty tuple. | -| `Base.unsafe_convert(::Type{Ptr{T}}, A)` |   | Return the native address of an array. | +| `Base.unsafe_convert(::Type{Ptr{T}}, A)` |   | Return the native address of an array. | | **Optional methods** | **Default definition** | **Brief description** | | `stride(A, i::Int)` |   `strides(A)[i]` | Return the distance in memory (in number of elements) between adjacent elements in dimension k. | diff --git a/codex/manual/variables-and-scoping.md b/codex/manual/variables-and-scoping.md index 40bed25..eae8c87 100644 --- a/codex/manual/variables-and-scoping.md +++ b/codex/manual/variables-and-scoping.md @@ -13,29 +13,16 @@ set of source lines; instead, it will always line up with one of these blocks. T main types of scopes in Julia, *global scope* and *local scope*. The latter can be nested. The constructs introducing scope blocks are: -# [](@id man-scope-table) - - * Scope blocks that may nest only in other global scope blocks: - - - global scope - - + [`module`](@ref), [`baremodule`](@ref) - - + at interactive prompt (REPL) - - - local scope (don't allow nesting) - - + (mutable) [`struct`](@ref), [`macro`](@ref) - - * Scope blocks which may nest anywhere (in global or local scope): - - - local scope - - + [`for`](@ref), [`while`](@ref), [`try-catch-finally`](@ref try), [`let`](@ref) - - + functions (either syntax, anonymous & do-blocks) - - + comprehensions, broadcast-fusing +### [Scope constructs](@id man-scope-table) + +Construct | Scope type | Scope blocks it may be nested in +------------ | ------------- |--------------------------- +[`module`](@ref), [`baremodule`](@ref) | global | global +interactive prompt (REPL) | global | global +(mutable) [`struct`](@ref), [`macro`](@ref) | local | global +[`for`](@ref), [`while`](@ref), [`try-catch-finally`](@ref try), [`let`](@ref) |local | global or local +functions (either syntax, anonymous & do-blocks) | local | global or local +comprehensions, broadcast-fusing | local | global or local Notably missing from this table are [begin blocks](@ref man-compound-expressions) and [if blocks](@ref man-conditional-evaluation) diff --git a/codex/stdlib/Pkg.md b/codex/stdlib/Pkg.md index 562fc5d..56357bf 100644 --- a/codex/stdlib/Pkg.md +++ b/codex/stdlib/Pkg.md @@ -81,7 +81,7 @@ identify the package in projects that depend on it. **Application:** a project which provides standalone functionality not intended to be reused by other Julia projects. For example a web application or a -command-line utility, or simulation/analytics code accompanying a scientific paper. +commmand-line utility, or simulation/analytics code accompanying a scientific paper. An application may have a UUID but does not need one. An application may also provide global configuration options for packages it depends on. Packages, on the other hand, may not provide global configuration @@ -427,7 +427,7 @@ Note the pin symbol `⚲` showing that the package is pinned. Removing the pin i ### Testing packages -The tests for a package can be run using `test` command: +The tests for a package can be run using `test`command: ``` (v1.0) pkg> test Example @@ -640,9 +640,6 @@ The build step is executed the first time a package is installed or when explici A package is built by executing the file `deps/build.jl`. ``` -shell> cat deps/build.jl -println("I am being built...") - shell> cat deps/build.log I am being built... @@ -751,7 +748,7 @@ Similar to other package managers, the Julia package manager respects [semantic As an example, a version specifier is given as e.g. `1.2.3` is therefore assumed to be compatible with the versions `[1.2.3 - 2.0.0)` where `)` is a non-inclusive upper bound. More specifically, a version specifier is either given as a **caret specifier**, e.g. `^1.2.3` or a **tilde specifier** `~1.2.3`. Caret specifiers are the default and hence `1.2.3 == ^1.2.3`. The difference between a caret and tilde is described in the next section. -The intersection of multiple version specifiers can be formed by comma separating indiviual version specifiers. +The union of multiple version specifiers can be formed by comma separating indiviual version specifiers. ##### Caret specifiers @@ -775,11 +772,14 @@ a version given as `0.a.b` is considered compatible with `0.a.c` if `a != 0` and ##### Tilde specifiers -A tilde specifier provides more limited upgrade possibilities. With a tilde, only the last specified digit is allowed to increment by one. +A tilde specifier provides more limited upgrade possibilities. When specifying major, minor +and patch version, or when specifying major and minor version, only patch version is +allowed to change. If you only specify a major version, then both minor and patch versions +are allowed to be upgraded (`~1` is thus equivalent to `^1`). This gives the following example. ``` -~1.2.3 = [1.2.3, 1.2.4) +~1.2.3 = [1.2.3, 1.3.0) ~1.2 = [1.2.0, 1.3.0) ~1 = [1.0.0, 2.0.0) ``` diff --git a/src/manual/calling-c-and-fortran-code.md b/src/manual/calling-c-and-fortran-code.md index 8c35495..54ae0f1 100644 --- a/src/manual/calling-c-and-fortran-code.md +++ b/src/manual/calling-c-and-fortran-code.md @@ -496,7 +496,7 @@ b_a_2 = B.A[2]; in Julia: ```julia struct B - A::NTuple{3, CInt} + A::NTuple{3, Cint} end b_a_2 = B.A[3] # note the difference in indexing (1-based in Julia, 0-based in C) ``` diff --git a/src/manual/interfaces.md b/src/manual/interfaces.md index db69514..e4c2bb0 100644 --- a/src/manual/interfaces.md +++ b/src/manual/interfaces.md @@ -235,8 +235,8 @@ ourselves, we can officially define it as a subtype of an [`AbstractArray`](@ref | `similar(A, ::Type{S}, dims::Dims)` | `Array{S}(undef, dims)` | Return a mutable array with the specified element type and size | | **Non-traditional indices** | **Default definition** | **Brief description** | | `axes(A)` | `map(OneTo, size(A))` | Return the `AbstractUnitRange` of valid indices | -| `Base.similar(A, ::Type{S}, inds)` | `similar(A, S, Base.to_shape(inds))` | Return a mutable array with the specified indices `inds` (see below) | -| `Base.similar(T::Union{Type,Function}, inds)` | `T(Base.to_shape(inds))` | Return an array similar to `T` with the specified indices `inds` (see below) | +| `similar(A, ::Type{S}, inds)` | `similar(A, S, Base.to_shape(inds))` | Return a mutable array with the specified indices `inds` (see below) | +| `similar(T::Union{Type,Function}, inds)` | `T(Base.to_shape(inds))` | Return an array similar to `T` with the specified indices `inds` (see below) | If a type is defined as a subtype of `AbstractArray`, it inherits a very large set of rich behaviors including iteration and multidimensional indexing built on top of single-element access. See @@ -406,7 +406,7 @@ perhaps range-types `Ind` of your own design. For more information, see | Methods to implement |   | Brief description | |:----------------------------------------------- |:-------------------------------------- |:------------------------------------------------------------------------------------- | | `strides(A)` |   | Return the distance in memory (in number of elements) between adjacent elements in each dimension as a tuple. If `A` is an `AbstractArray{T,0}`, this should return an empty tuple. | -| `Base.unsafe_convert(::Type{Ptr{T}}, A)` |   | Return the native address of an array. | +| `Base.unsafe_convert(::Type{Ptr{T}}, A)` |   | Return the native address of an array. | | **Optional methods** | **Default definition** | **Brief description** | | `stride(A, i::Int)` |   `strides(A)[i]` | Return the distance in memory (in number of elements) between adjacent elements in dimension k. | diff --git a/src/manual/variables-and-scoping.md b/src/manual/variables-and-scoping.md index 40bed25..eae8c87 100644 --- a/src/manual/variables-and-scoping.md +++ b/src/manual/variables-and-scoping.md @@ -13,29 +13,16 @@ set of source lines; instead, it will always line up with one of these blocks. T main types of scopes in Julia, *global scope* and *local scope*. The latter can be nested. The constructs introducing scope blocks are: -# [](@id man-scope-table) - - * Scope blocks that may nest only in other global scope blocks: - - - global scope - - + [`module`](@ref), [`baremodule`](@ref) - - + at interactive prompt (REPL) - - - local scope (don't allow nesting) - - + (mutable) [`struct`](@ref), [`macro`](@ref) - - * Scope blocks which may nest anywhere (in global or local scope): - - - local scope - - + [`for`](@ref), [`while`](@ref), [`try-catch-finally`](@ref try), [`let`](@ref) - - + functions (either syntax, anonymous & do-blocks) - - + comprehensions, broadcast-fusing +### [Scope constructs](@id man-scope-table) + +Construct | Scope type | Scope blocks it may be nested in +------------ | ------------- |--------------------------- +[`module`](@ref), [`baremodule`](@ref) | global | global +interactive prompt (REPL) | global | global +(mutable) [`struct`](@ref), [`macro`](@ref) | local | global +[`for`](@ref), [`while`](@ref), [`try-catch-finally`](@ref try), [`let`](@ref) |local | global or local +functions (either syntax, anonymous & do-blocks) | local | global or local +comprehensions, broadcast-fusing | local | global or local Notably missing from this table are [begin blocks](@ref man-compound-expressions) and [if blocks](@ref man-conditional-evaluation) diff --git a/src/stdlib/Pkg.md b/src/stdlib/Pkg.md index 562fc5d..56357bf 100644 --- a/src/stdlib/Pkg.md +++ b/src/stdlib/Pkg.md @@ -81,7 +81,7 @@ identify the package in projects that depend on it. **Application:** a project which provides standalone functionality not intended to be reused by other Julia projects. For example a web application or a -command-line utility, or simulation/analytics code accompanying a scientific paper. +commmand-line utility, or simulation/analytics code accompanying a scientific paper. An application may have a UUID but does not need one. An application may also provide global configuration options for packages it depends on. Packages, on the other hand, may not provide global configuration @@ -427,7 +427,7 @@ Note the pin symbol `⚲` showing that the package is pinned. Removing the pin i ### Testing packages -The tests for a package can be run using `test` command: +The tests for a package can be run using `test`command: ``` (v1.0) pkg> test Example @@ -640,9 +640,6 @@ The build step is executed the first time a package is installed or when explici A package is built by executing the file `deps/build.jl`. ``` -shell> cat deps/build.jl -println("I am being built...") - shell> cat deps/build.log I am being built... @@ -751,7 +748,7 @@ Similar to other package managers, the Julia package manager respects [semantic As an example, a version specifier is given as e.g. `1.2.3` is therefore assumed to be compatible with the versions `[1.2.3 - 2.0.0)` where `)` is a non-inclusive upper bound. More specifically, a version specifier is either given as a **caret specifier**, e.g. `^1.2.3` or a **tilde specifier** `~1.2.3`. Caret specifiers are the default and hence `1.2.3 == ^1.2.3`. The difference between a caret and tilde is described in the next section. -The intersection of multiple version specifiers can be formed by comma separating indiviual version specifiers. +The union of multiple version specifiers can be formed by comma separating indiviual version specifiers. ##### Caret specifiers @@ -775,11 +772,14 @@ a version given as `0.a.b` is considered compatible with `0.a.c` if `a != 0` and ##### Tilde specifiers -A tilde specifier provides more limited upgrade possibilities. With a tilde, only the last specified digit is allowed to increment by one. +A tilde specifier provides more limited upgrade possibilities. When specifying major, minor +and patch version, or when specifying major and minor version, only patch version is +allowed to change. If you only specify a major version, then both minor and patch versions +are allowed to be upgraded (`~1` is thus equivalent to `^1`). This gives the following example. ``` -~1.2.3 = [1.2.3, 1.2.4) +~1.2.3 = [1.2.3, 1.3.0) ~1.2 = [1.2.0, 1.3.0) ~1 = [1.0.0, 2.0.0) ``` From c918bf3cff8ff970400db81b100d5869af8322ca Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Tue, 6 Nov 2018 14:46:56 +0900 Subject: [PATCH 074/153] update Julia Commit 58fea96a5c --- codex/base/arrays.md | 1 - codex/base/base.md | 1 + codex/devdocs/inference.md | 28 ++++++++++++++++++++++------ codex/manual/interfaces.md | 2 +- codex/stdlib/Logging.md | 8 ++++---- codex/stdlib/REPL.md | 2 +- src/base/arrays.md | 1 - src/base/base.md | 1 + src/devdocs/inference.md | 28 ++++++++++++++++++++++------ src/manual/interfaces.md | 2 +- src/stdlib/Logging.md | 8 ++++---- src/stdlib/REPL.md | 2 +- 12 files changed, 58 insertions(+), 26 deletions(-) diff --git a/codex/base/arrays.md b/codex/base/arrays.md index 260649a..6cad1e6 100644 --- a/codex/base/arrays.md +++ b/codex/base/arrays.md @@ -76,7 +76,6 @@ Base.@__dot__ For specializing broadcast on custom types, see ```@docs Base.BroadcastStyle -Base.broadcast_axes Base.Broadcast.AbstractArrayStyle Base.Broadcast.ArrayStyle Base.Broadcast.DefaultArrayStyle diff --git a/codex/base/base.md b/codex/base/base.md index 4eebbd7..fe609bc 100644 --- a/codex/base/base.md +++ b/codex/base/base.md @@ -167,6 +167,7 @@ Base.isconcretetype Base.isbits Base.isbitstype Core.fieldtype +Base.fieldtypes Base.fieldcount Base.fieldoffset Base.datatype_alignment diff --git a/codex/devdocs/inference.md b/codex/devdocs/inference.md index 28f624b..df1f908 100644 --- a/codex/devdocs/inference.md +++ b/codex/devdocs/inference.md @@ -90,15 +90,31 @@ dynamic dispatch, but a mere heuristic indicating that dynamic dispatch is extremely expensive. Each statement gets analyzed for its total cost in a function called -`statement_cost`. You can run this yourself by following this example: - -```julia +`statement_cost`. You can run this yourself by following the sketch below, +where `f` is your function and `tt` is the Tuple-type of the arguments: + +```jldoctest +# A demo on `fill(3.5, (2, 3)) +f = fill +tt = Tuple{Float64, Tuple{Int,Int}} +# Create the objects we need to interact with the compiler params = Core.Compiler.Params(typemax(UInt)) -# Get the CodeInfo object -ci = (@code_typed fill(3, (5, 5)))[1] # we'll try this on the code for `fill(3, (5, 5))` +mi = Base.method_instances(f, tt)[1] +ci = code_typed(f, tt)[1][1] +opt = Core.Compiler.OptimizationState(mi, params) # Calculate cost of each statement -cost(stmt) = Core.Compiler.statement_cost(stmt, ci, Base, params) +cost(stmt::Expr) = Core.Compiler.statement_cost(stmt, -1, ci, opt.sp, opt.slottypes, opt.params) +cost(stmt) = 0 cst = map(cost, ci.code) + +# output + +5-element Array{Int64,1}: + 0 + 0 + 20 + 20 + 0 ``` The output is a `Vector{Int}` holding the estimated cost of each diff --git a/codex/manual/interfaces.md b/codex/manual/interfaces.md index e4c2bb0..d5a53e9 100644 --- a/codex/manual/interfaces.md +++ b/codex/manual/interfaces.md @@ -440,7 +440,7 @@ V = view(A, [1,2,4], :) # is not strided, as the spacing between rows is not f | `Base.similar(bc::Broadcasted{DestStyle}, ::Type{ElType})` | Allocation of output container | | **Optional methods** | | | | `Base.BroadcastStyle(::Style1, ::Style2) = Style12()` | Precedence rules for mixing styles | -| `Base.broadcast_axes(x)` | Declaration of the indices of `x` for broadcasting purposes (defaults to [`axes(x)`](@ref)) | +| `Base.axes(x)` | Declaration of the indices of `x`, as per [`axes(x)`](@ref). | | `Base.broadcastable(x)` | Convert `x` to an object that has `axes` and supports indexing | | **Bypassing default machinery** | | | `Base.copy(bc::Broadcasted{DestStyle})` | Custom implementation of `broadcast` | diff --git a/codex/stdlib/Logging.md b/codex/stdlib/Logging.md index bed0b1b..8831569 100644 --- a/codex/stdlib/Logging.md +++ b/codex/stdlib/Logging.md @@ -77,10 +77,10 @@ The system also generates some standard information for each event: * The `module` in which the logging macro was expanded. * The `file` and `line` where the logging macro occurs in the source code. -* A message `id` that is unique for each logging macro invocation. This is - very useful as a key for caching information or actions associated with an - event. For instance, it can be used to limit the number of times a message - is presented to the user. +* A message `id` that is a unique, fixed identifier for the *source code + statement* where the logging macro appears. This identifier is designed to be + fairly stable even if the source code of the file changes, as long as the + logging statement itself remains the same. * A `group` for the event, which is set to the base name of the file by default, without extension. This can be used to group messages into categories more finely than the log level (for example, all deprecation warnings have group diff --git a/codex/stdlib/REPL.md b/codex/stdlib/REPL.md index 2afa93d..3f50791 100644 --- a/codex/stdlib/REPL.md +++ b/codex/stdlib/REPL.md @@ -47,7 +47,7 @@ In Julia mode, the REPL supports something called *prompt pasting*. This activat text that starts with `julia> ` into the REPL. In that case, only expressions starting with `julia> ` are parsed, others are removed. This makes it is possible to paste a chunk of code that has been copied from a REPL session without having to scrub away prompts and outputs. This -feature is enabled by default but can be disabled or enabled at will with `Base.REPL.enable_promptpaste(::Bool)`. +feature is enabled by default but can be disabled or enabled at will with `REPL.enable_promptpaste(::Bool)`. If it is enabled, you can try it out by pasting the code block above this paragraph straight into the REPL. This feature does not work on the standard Windows command prompt due to its limitation at detecting when a paste occurs. diff --git a/src/base/arrays.md b/src/base/arrays.md index 260649a..6cad1e6 100644 --- a/src/base/arrays.md +++ b/src/base/arrays.md @@ -76,7 +76,6 @@ Base.@__dot__ For specializing broadcast on custom types, see ```@docs Base.BroadcastStyle -Base.broadcast_axes Base.Broadcast.AbstractArrayStyle Base.Broadcast.ArrayStyle Base.Broadcast.DefaultArrayStyle diff --git a/src/base/base.md b/src/base/base.md index 4eebbd7..fe609bc 100644 --- a/src/base/base.md +++ b/src/base/base.md @@ -167,6 +167,7 @@ Base.isconcretetype Base.isbits Base.isbitstype Core.fieldtype +Base.fieldtypes Base.fieldcount Base.fieldoffset Base.datatype_alignment diff --git a/src/devdocs/inference.md b/src/devdocs/inference.md index 28f624b..df1f908 100644 --- a/src/devdocs/inference.md +++ b/src/devdocs/inference.md @@ -90,15 +90,31 @@ dynamic dispatch, but a mere heuristic indicating that dynamic dispatch is extremely expensive. Each statement gets analyzed for its total cost in a function called -`statement_cost`. You can run this yourself by following this example: - -```julia +`statement_cost`. You can run this yourself by following the sketch below, +where `f` is your function and `tt` is the Tuple-type of the arguments: + +```jldoctest +# A demo on `fill(3.5, (2, 3)) +f = fill +tt = Tuple{Float64, Tuple{Int,Int}} +# Create the objects we need to interact with the compiler params = Core.Compiler.Params(typemax(UInt)) -# Get the CodeInfo object -ci = (@code_typed fill(3, (5, 5)))[1] # we'll try this on the code for `fill(3, (5, 5))` +mi = Base.method_instances(f, tt)[1] +ci = code_typed(f, tt)[1][1] +opt = Core.Compiler.OptimizationState(mi, params) # Calculate cost of each statement -cost(stmt) = Core.Compiler.statement_cost(stmt, ci, Base, params) +cost(stmt::Expr) = Core.Compiler.statement_cost(stmt, -1, ci, opt.sp, opt.slottypes, opt.params) +cost(stmt) = 0 cst = map(cost, ci.code) + +# output + +5-element Array{Int64,1}: + 0 + 0 + 20 + 20 + 0 ``` The output is a `Vector{Int}` holding the estimated cost of each diff --git a/src/manual/interfaces.md b/src/manual/interfaces.md index e4c2bb0..d5a53e9 100644 --- a/src/manual/interfaces.md +++ b/src/manual/interfaces.md @@ -440,7 +440,7 @@ V = view(A, [1,2,4], :) # is not strided, as the spacing between rows is not f | `Base.similar(bc::Broadcasted{DestStyle}, ::Type{ElType})` | Allocation of output container | | **Optional methods** | | | | `Base.BroadcastStyle(::Style1, ::Style2) = Style12()` | Precedence rules for mixing styles | -| `Base.broadcast_axes(x)` | Declaration of the indices of `x` for broadcasting purposes (defaults to [`axes(x)`](@ref)) | +| `Base.axes(x)` | Declaration of the indices of `x`, as per [`axes(x)`](@ref). | | `Base.broadcastable(x)` | Convert `x` to an object that has `axes` and supports indexing | | **Bypassing default machinery** | | | `Base.copy(bc::Broadcasted{DestStyle})` | Custom implementation of `broadcast` | diff --git a/src/stdlib/Logging.md b/src/stdlib/Logging.md index bed0b1b..8831569 100644 --- a/src/stdlib/Logging.md +++ b/src/stdlib/Logging.md @@ -77,10 +77,10 @@ The system also generates some standard information for each event: * The `module` in which the logging macro was expanded. * The `file` and `line` where the logging macro occurs in the source code. -* A message `id` that is unique for each logging macro invocation. This is - very useful as a key for caching information or actions associated with an - event. For instance, it can be used to limit the number of times a message - is presented to the user. +* A message `id` that is a unique, fixed identifier for the *source code + statement* where the logging macro appears. This identifier is designed to be + fairly stable even if the source code of the file changes, as long as the + logging statement itself remains the same. * A `group` for the event, which is set to the base name of the file by default, without extension. This can be used to group messages into categories more finely than the log level (for example, all deprecation warnings have group diff --git a/src/stdlib/REPL.md b/src/stdlib/REPL.md index 2afa93d..3f50791 100644 --- a/src/stdlib/REPL.md +++ b/src/stdlib/REPL.md @@ -47,7 +47,7 @@ In Julia mode, the REPL supports something called *prompt pasting*. This activat text that starts with `julia> ` into the REPL. In that case, only expressions starting with `julia> ` are parsed, others are removed. This makes it is possible to paste a chunk of code that has been copied from a REPL session without having to scrub away prompts and outputs. This -feature is enabled by default but can be disabled or enabled at will with `Base.REPL.enable_promptpaste(::Bool)`. +feature is enabled by default but can be disabled or enabled at will with `REPL.enable_promptpaste(::Bool)`. If it is enabled, you can try it out by pasting the code block above this paragraph straight into the REPL. This feature does not work on the standard Windows command prompt due to its limitation at detecting when a paste occurs. From 6c61bd2dcb9ba1b641ac3d72f7806669243a6c44 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Thu, 8 Nov 2018 21:41:48 +0900 Subject: [PATCH 075/153] update Julia Commit 5922b5e733 --- codex/manual/documentation.md | 5 +++++ make.jl | 3 ++- src/manual/documentation.md | 5 +++++ tools/check_codex.jl | 1 - 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/codex/manual/documentation.md b/codex/manual/documentation.md index 41ac5e4..1bb2641 100644 --- a/codex/manual/documentation.md +++ b/codex/manual/documentation.md @@ -606,6 +606,11 @@ A paragraph containing some ``\LaTeX`` markup. backticks use an even number greater than two. Note that if a single literal backtick needs to be included within ``\LaTeX`` markup then two enclosing backticks is sufficient. +!!! note + The `\` character should be escaped appropriately if the text is embedded in a Julia source code, + for example, ``` "``\\LaTeX`` syntax in a docstring." ```, since it is interpreted as a string + literal. + #### Links Links to either external or internal addresses can be written using the following syntax, where diff --git a/make.jl b/make.jl index bf972bf..d0a9989 100644 --- a/make.jl +++ b/make.jl @@ -122,7 +122,8 @@ const PAGES = [ "devdocs/offset-arrays.md", "devdocs/require.md", "devdocs/inference.md", - "devdocs/ssair.md", # Julia SSA-form IR + "devdocs/ssair.md", + "devdocs/gc-sa.md", ], "Developing/debugging Julia's C code" => [ "devdocs/backtraces.md", diff --git a/src/manual/documentation.md b/src/manual/documentation.md index 41ac5e4..1bb2641 100644 --- a/src/manual/documentation.md +++ b/src/manual/documentation.md @@ -606,6 +606,11 @@ A paragraph containing some ``\LaTeX`` markup. backticks use an even number greater than two. Note that if a single literal backtick needs to be included within ``\LaTeX`` markup then two enclosing backticks is sufficient. +!!! note + The `\` character should be escaped appropriately if the text is embedded in a Julia source code, + for example, ``` "``\\LaTeX`` syntax in a docstring." ```, since it is interpreted as a string + literal. + #### Links Links to either external or internal addresses can be written using the following syntax, where diff --git a/tools/check_codex.jl b/tools/check_codex.jl index 551e8ee..aa44160 100644 --- a/tools/check_codex.jl +++ b/tools/check_codex.jl @@ -138,7 +138,6 @@ function check_pages() pages2 = get_pages(makejl_path) do s for (a,b) in [("t_Home", "\"Home\""), ("t_Manual", "\"Manual\""), - ("\"devdocs/ssair.md\", # Julia SSA-form IR", ""), # temporal ] s = replace(s, a => b) end From 0df4d6945f750b136bc3a9ea20666dc53b53065d Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Mon, 12 Nov 2018 04:58:59 +0900 Subject: [PATCH 076/153] update Julia Commit 96ce5ba221 --- codex/devdocs/gc-sa.md | 26 +++++++++++++------------- codex/devdocs/ssair.md | 2 +- codex/manual/functions.md | 2 +- codex/manual/performance-tips.md | 20 -------------------- src/devdocs/gc-sa.md | 26 +++++++++++++------------- src/devdocs/ssair.md | 8 ++++---- src/manual/functions.md | 2 +- src/manual/performance-tips.md | 20 -------------------- 8 files changed, 33 insertions(+), 73 deletions(-) diff --git a/codex/devdocs/gc-sa.md b/codex/devdocs/gc-sa.md index 4cf336b..086601f 100644 --- a/codex/devdocs/gc-sa.md +++ b/codex/devdocs/gc-sa.md @@ -84,12 +84,12 @@ These annotations are found in src/support/analyzer_annotations.h. The are only active when the analyzer is being used and expand either to nothing (for prototype annotations) or to no-ops (for function like annotations). -### JL_NOTSAFEPOINT +### `JL_NOTSAFEPOINT` This is perhaps the most common annotation, and should be placed on any function that is known not to possibly lead to reaching a GC safepoint. In general, it is only safe for such a function to perform arithmetic, memory accesses and calls to -functions either annotated JL_NOTSAFEPOINT or otherwise known not to be safepoints (e.g. +functions either annotated `JL_NOTSAFEPOINT` or otherwise known not to be safepoints (e.g. function in the C standard library, which are hardcoded as such in the analyzer) It is valid to keep values unrooted across calls to any function annotated with this @@ -110,7 +110,7 @@ jl_value_t *example() { } ``` -### JL_MAYBE_UNROOTED/JL_ROOTS_TEMPORARILY +### `JL_MAYBE_UNROOTED`/`JL_ROOTS_TEMPORARILY` When `JL_MAYBE_UNROOTED` is annotated as an argument on a function, indicates that said argument may be passed, even if it is not rooted. @@ -123,7 +123,7 @@ The `ROOTS_TEMPORARILY` annotation provides the stronger guarantee that, not only may the value be unrooted when passed, it will also be preserved across any internal safepoints by the callee. -Note that JL_NOTSAFEPOINT essentially implies JL_MAYBE_UNROOTED/JL_ROOTS_TEMPORARILY, +Note that `JL_NOTSAFEPOINT` essentially implies `JL_MAYBE_UNROOTED`/`JL_ROOTS_TEMPORARILY`, because the rootedness of an argument is irrelevant if the function contains no safepoints. @@ -149,7 +149,7 @@ void example() { } ``` -### JL_PROPAGATES_ROOT +### `JL_PROPAGATES_ROOT` This annotation is commonly found on accessor functions that return one rootable object stored within another. When annotated on a function argument, it tells @@ -169,7 +169,7 @@ size_t example(jl_svec_t *svec) { } ``` -### JL_ROOTING_ARGUMENT/JL_ROOTED_ARGUMENT +### `JL_ROOTING_ARGUMENT`/`JL_ROOTED_ARGUMENT` This is essentially the assignment counterpart to `JL_PROPAGATES_ROOT`. When assigning a value to a field of another value that is already rooted, @@ -190,13 +190,13 @@ size_t example(jl_svec_t *svec) { } ``` -### JL_GC_DISABLED +### `JL_GC_DISABLED` This annotation implies that this function is only called with the GC runtime-disabled. Functions of this kind are most often encountered during startup and in the GC code itself. Note that this annotation is checked against the runtime enable/disable calls, so clang will know if you lie. This is not a good way to disable processing of a given function if the -GC is not actually disabled (use ifdef __clang_analyzer__ for that if you must). +GC is not actually disabled (use `ifdef __clang_analyzer__` for that if you must). Usage example: ```c @@ -211,7 +211,7 @@ void example() { } ``` -### JL_REQUIRE_ROOTED_SLOT +### `JL_REQUIRE_ROOTED_SLOT` This annotation requires the caller to pass in a slot that is rooted (i.e. values assigned to this slot will be rooted). @@ -232,7 +232,7 @@ void example() { } ``` -### JL_GLOBALLY_ROOTED +### `JL_GLOBALLY_ROOTED` This annotation implies that a given value is always globally rooted. It can be applied to global variable declarations, in which case it @@ -247,9 +247,9 @@ extern JL_DLLEXPORT jl_datatype_t *jl_any_type JL_GLOBALLY_ROOTED; jl_ast_context_t *jl_ast_ctx(fl_context_t *fl) JL_GLOBALLY_ROOTED; ``` -### JL_ALWAYS_LEAFTYPE +### `JL_ALWAYS_LEAFTYPE` -This annotations is essentially equivalent to JL_GLOBALLY_ROOTED, except that +This annotations is essentially equivalent to `JL_GLOBALLY_ROOTED`, except that is should only be used if those values are globally rooted by virtue of being a leaftype. The rooting of leaftypes is a bit complicated. They are generally rooted through `cache` field of the corresponding `TypeName`, which itself is @@ -265,7 +265,7 @@ complain about missing GC roots on these paths. JL_DLLEXPORT jl_value_t *jl_apply_array_type(jl_value_t *type, size_t dim) JL_ALWAYS_LEAFTYPE; ``` -### JL_GC_PROMISE_ROOTED +### `JL_GC_PROMISE_ROOTED` This is a function-like annotation. Any value passed to this annotation will be considered rooted for the scope of the current function. It is designed as an escape hatch diff --git a/codex/devdocs/ssair.md b/codex/devdocs/ssair.md index ea37b8b..96476d0 100644 --- a/codex/devdocs/ssair.md +++ b/codex/devdocs/ssair.md @@ -151,7 +151,7 @@ catch blocks are considered to have an invisible control flow edge from outside the function. As a result, no SSA value dominates the catch blocks, and all incoming values have to come through a `φᶜ` node. -# Main SSA data structure +## Main SSA data structure The main `SSAIR` data structure is worthy of discussion. It draws inspiration from LLVM and Webkit's B3 IR. The core of the data structure is a flat vector of statements. Each statement is implicitly assigned diff --git a/codex/manual/functions.md b/codex/manual/functions.md index 5b57f6a..5e9ec95 100644 --- a/codex/manual/functions.md +++ b/codex/manual/functions.md @@ -671,7 +671,7 @@ can call fast library code written in a low-level language. In Julia, vectorized *not* required for performance, and indeed it is often beneficial to write your own loops (see [Performance Tips](@ref man-performance-tips)), but they can still be convenient. Therefore, *any* Julia function `f` can be applied elementwise to any array (or other collection) with the syntax `f.(A)`. -For example `sin` can be applied to all elements in the vector `A`, like so: +For example, `sin` can be applied to all elements in the vector `A` like so: ```jldoctest julia> A = [1.0, 2.0, 3.0] diff --git a/codex/manual/performance-tips.md b/codex/manual/performance-tips.md index aaf809e..3a3f246 100644 --- a/codex/manual/performance-tips.md +++ b/codex/manual/performance-tips.md @@ -481,26 +481,6 @@ c = (b + 1.0f0)::Complex{T} does not hinder performance (but does not help either) since the compiler can determine the type of `c` at the time `k` is compiled. -### Declare types of keyword arguments - -Keyword arguments can have declared types: - -```julia -function with_keyword(x; name::Int = 1) - ... -end -``` - -Functions are specialized on the types of keyword arguments, so these declarations will not affect -performance of code inside the function. However, they will reduce the overhead of calls to the -function that include keyword arguments. - -Functions with keyword arguments have near-zero overhead for call sites that pass only positional -arguments. - -Passing dynamic lists of keyword arguments, as in `f(x; keywords...)`, can be slow and should -be avoided in performance-sensitive code. - ## Break functions into multiple definitions Writing a function as many small definitions allows the compiler to directly call the most applicable diff --git a/src/devdocs/gc-sa.md b/src/devdocs/gc-sa.md index 4cf336b..086601f 100644 --- a/src/devdocs/gc-sa.md +++ b/src/devdocs/gc-sa.md @@ -84,12 +84,12 @@ These annotations are found in src/support/analyzer_annotations.h. The are only active when the analyzer is being used and expand either to nothing (for prototype annotations) or to no-ops (for function like annotations). -### JL_NOTSAFEPOINT +### `JL_NOTSAFEPOINT` This is perhaps the most common annotation, and should be placed on any function that is known not to possibly lead to reaching a GC safepoint. In general, it is only safe for such a function to perform arithmetic, memory accesses and calls to -functions either annotated JL_NOTSAFEPOINT or otherwise known not to be safepoints (e.g. +functions either annotated `JL_NOTSAFEPOINT` or otherwise known not to be safepoints (e.g. function in the C standard library, which are hardcoded as such in the analyzer) It is valid to keep values unrooted across calls to any function annotated with this @@ -110,7 +110,7 @@ jl_value_t *example() { } ``` -### JL_MAYBE_UNROOTED/JL_ROOTS_TEMPORARILY +### `JL_MAYBE_UNROOTED`/`JL_ROOTS_TEMPORARILY` When `JL_MAYBE_UNROOTED` is annotated as an argument on a function, indicates that said argument may be passed, even if it is not rooted. @@ -123,7 +123,7 @@ The `ROOTS_TEMPORARILY` annotation provides the stronger guarantee that, not only may the value be unrooted when passed, it will also be preserved across any internal safepoints by the callee. -Note that JL_NOTSAFEPOINT essentially implies JL_MAYBE_UNROOTED/JL_ROOTS_TEMPORARILY, +Note that `JL_NOTSAFEPOINT` essentially implies `JL_MAYBE_UNROOTED`/`JL_ROOTS_TEMPORARILY`, because the rootedness of an argument is irrelevant if the function contains no safepoints. @@ -149,7 +149,7 @@ void example() { } ``` -### JL_PROPAGATES_ROOT +### `JL_PROPAGATES_ROOT` This annotation is commonly found on accessor functions that return one rootable object stored within another. When annotated on a function argument, it tells @@ -169,7 +169,7 @@ size_t example(jl_svec_t *svec) { } ``` -### JL_ROOTING_ARGUMENT/JL_ROOTED_ARGUMENT +### `JL_ROOTING_ARGUMENT`/`JL_ROOTED_ARGUMENT` This is essentially the assignment counterpart to `JL_PROPAGATES_ROOT`. When assigning a value to a field of another value that is already rooted, @@ -190,13 +190,13 @@ size_t example(jl_svec_t *svec) { } ``` -### JL_GC_DISABLED +### `JL_GC_DISABLED` This annotation implies that this function is only called with the GC runtime-disabled. Functions of this kind are most often encountered during startup and in the GC code itself. Note that this annotation is checked against the runtime enable/disable calls, so clang will know if you lie. This is not a good way to disable processing of a given function if the -GC is not actually disabled (use ifdef __clang_analyzer__ for that if you must). +GC is not actually disabled (use `ifdef __clang_analyzer__` for that if you must). Usage example: ```c @@ -211,7 +211,7 @@ void example() { } ``` -### JL_REQUIRE_ROOTED_SLOT +### `JL_REQUIRE_ROOTED_SLOT` This annotation requires the caller to pass in a slot that is rooted (i.e. values assigned to this slot will be rooted). @@ -232,7 +232,7 @@ void example() { } ``` -### JL_GLOBALLY_ROOTED +### `JL_GLOBALLY_ROOTED` This annotation implies that a given value is always globally rooted. It can be applied to global variable declarations, in which case it @@ -247,9 +247,9 @@ extern JL_DLLEXPORT jl_datatype_t *jl_any_type JL_GLOBALLY_ROOTED; jl_ast_context_t *jl_ast_ctx(fl_context_t *fl) JL_GLOBALLY_ROOTED; ``` -### JL_ALWAYS_LEAFTYPE +### `JL_ALWAYS_LEAFTYPE` -This annotations is essentially equivalent to JL_GLOBALLY_ROOTED, except that +This annotations is essentially equivalent to `JL_GLOBALLY_ROOTED`, except that is should only be used if those values are globally rooted by virtue of being a leaftype. The rooting of leaftypes is a bit complicated. They are generally rooted through `cache` field of the corresponding `TypeName`, which itself is @@ -265,7 +265,7 @@ complain about missing GC roots on these paths. JL_DLLEXPORT jl_value_t *jl_apply_array_type(jl_value_t *type, size_t dim) JL_ALWAYS_LEAFTYPE; ``` -### JL_GC_PROMISE_ROOTED +### `JL_GC_PROMISE_ROOTED` This is a function-like annotation. Any value passed to this annotation will be considered rooted for the scope of the current function. It is designed as an escape hatch diff --git a/src/devdocs/ssair.md b/src/devdocs/ssair.md index 253d5ce..96476d0 100644 --- a/src/devdocs/ssair.md +++ b/src/devdocs/ssair.md @@ -8,7 +8,7 @@ AST. This form had most syntactic abstractions removed, but still looked a lot l Over time, in order to facilitate optimizations, SSA values were introduced to this IR and the IR was linearized (i.e. a form where function arguments may only be SSA values or constants). However, non-ssa values (slots) remained in the IR due to the lack of Phi nodes in the IR (necessary for back-edges and re-merging of -conditional control flow), negating much of the usefulness of the SSA form representation to perform +conditional control flow), negating much of the usefulfulness of the SSA form representation to perform middle end optimizations. Some heroic effort was put into making these optimizations work without a complete SSA form representation, but the lack of such a representation ultimately proved prohibitive. @@ -90,7 +90,7 @@ catch: However, this is problematic in a language like julia where at the start of the optimization pipeline, we do not now which calls throw. We would have to conservatively assume that every call (which in julia is every statement) throws. This would have several negative effects. -On the one hand, it would essentially reduce the scope of every basic block to a single call, +On the one hand, it would essentially recuce the scope of every basic block to a single call, defeating the purpose of having operations be performed at the basic block level. On the other hand, every catch basic block would have `n*m` phi node arguments (`n`, the number of statements in the critical region, `m` the number of live values through the catch block). To work around @@ -151,7 +151,7 @@ catch blocks are considered to have an invisible control flow edge from outside the function. As a result, no SSA value dominates the catch blocks, and all incoming values have to come through a `φᶜ` node. -# Main SSA data structure +## Main SSA data structure The main `SSAIR` data structure is worthy of discussion. It draws inspiration from LLVM and Webkit's B3 IR. The core of the data structure is a flat vector of statements. Each statement is implicitly assigned @@ -168,7 +168,7 @@ Instead, we do the following: - We keep a separate buffer of nodes to insert (including the position to insert them at, the type of the corresponding value and the node itself). These nodes are numbered by their occurrence in the insertion - buffer, allowing their values to be immediately used elsewhere in the IR (i.e. if there is 12 statements in + buffer, allowing their values to be immediately used elesewhere in the IR (i.e. if there is 12 statements in the original statement list, the first new statement will be accessible as `SSAValue(13)`) - RAUW style operations are performed by setting the corresponding statement index to the replacement value. diff --git a/src/manual/functions.md b/src/manual/functions.md index 5b57f6a..5e9ec95 100644 --- a/src/manual/functions.md +++ b/src/manual/functions.md @@ -671,7 +671,7 @@ can call fast library code written in a low-level language. In Julia, vectorized *not* required for performance, and indeed it is often beneficial to write your own loops (see [Performance Tips](@ref man-performance-tips)), but they can still be convenient. Therefore, *any* Julia function `f` can be applied elementwise to any array (or other collection) with the syntax `f.(A)`. -For example `sin` can be applied to all elements in the vector `A`, like so: +For example, `sin` can be applied to all elements in the vector `A` like so: ```jldoctest julia> A = [1.0, 2.0, 3.0] diff --git a/src/manual/performance-tips.md b/src/manual/performance-tips.md index aaf809e..3a3f246 100644 --- a/src/manual/performance-tips.md +++ b/src/manual/performance-tips.md @@ -481,26 +481,6 @@ c = (b + 1.0f0)::Complex{T} does not hinder performance (but does not help either) since the compiler can determine the type of `c` at the time `k` is compiled. -### Declare types of keyword arguments - -Keyword arguments can have declared types: - -```julia -function with_keyword(x; name::Int = 1) - ... -end -``` - -Functions are specialized on the types of keyword arguments, so these declarations will not affect -performance of code inside the function. However, they will reduce the overhead of calls to the -function that include keyword arguments. - -Functions with keyword arguments have near-zero overhead for call sites that pass only positional -arguments. - -Passing dynamic lists of keyword arguments, as in `f(x; keywords...)`, can be slow and should -be avoided in performance-sensitive code. - ## Break functions into multiple definitions Writing a function as many small definitions allows the compiler to directly call the most applicable From 806ecfa111b117599c0346505e1830e47d21b513 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Thu, 15 Nov 2018 21:15:56 +0900 Subject: [PATCH 077/153] update Julia Commit 0b51625d13 --- codex/manual/documentation.md | 391 +--------------------------------- codex/manual/unicode-input.md | 2 +- codex/stdlib/Markdown.md | 384 +++++++++++++++++++++++++++++++++ src/manual/documentation.md | 391 +--------------------------------- src/stdlib/Markdown.md | 384 +++++++++++++++++++++++++++++++++ 5 files changed, 789 insertions(+), 763 deletions(-) diff --git a/codex/manual/documentation.md b/codex/manual/documentation.md index 1bb2641..4f80dc4 100644 --- a/codex/manual/documentation.md +++ b/codex/manual/documentation.md @@ -18,6 +18,11 @@ use indentation and code fences to delimit code examples from text. Technically, be associated with any other as metadata; Markdown happens to be the default, but one can construct other string macros and pass them to the `@doc` macro just as well. +!!! note + Markdown support is implemented in the `Markdown` standard library + and for a full list of supported syntax see the + [documentation](@ref Markdown). + Here is a more complex example, still using Markdown: ````julia @@ -96,6 +101,11 @@ As in the example above, we recommend following some simple conventions when wri (see [Code blocks](@ref)) starting with ````` ```jldoctest````` and contains any number of `julia>` prompts together with inputs and expected outputs that mimic the Julia REPL. + !!! note + Doctests are enabled by [`Documenter.jl`](https://github.com/JuliaDocs/Documenter.jl). + For more detailed documentation see Documenter's + [manual](https://juliadocs.github.io/Documenter.jl/). + For example in the following docstring a variable `a` is defined and the expected result, as printed in a Julia REPL, appears afterwards: @@ -545,384 +555,3 @@ should serve as an example of how to use `@__doc__` correctly. ```@docs Core.@__doc__ ``` - -## Markdown syntax - -The following markdown syntax is supported in Julia. - -### Inline elements - -Here "inline" refers to elements that can be found within blocks of text, i.e. paragraphs. These -include the following elements. - -#### Bold - -Surround words with two asterisks, `**`, to display the enclosed text in boldface. - -``` -A paragraph containing a **bold** word. -``` - -#### Italics - -Surround words with one asterisk, `*`, to display the enclosed text in italics. - -``` -A paragraph containing an *emphasized* word. -``` - -#### Literals - -Surround text that should be displayed exactly as written with single backticks, ``` ` ``` . - -``` -A paragraph containing a `literal` word. -``` - -Literals should be used when writing text that refers to names of variables, functions, or other -parts of a Julia program. - -!!! tip - To include a backtick character within literal text use three backticks rather than one to enclose - the text. - - ``` - A paragraph containing a ``` `backtick` character ```. - ``` - - By extension any odd number of backticks may be used to enclose a lesser number of backticks. - -#### ``\LaTeX`` - -Surround text that should be displayed as mathematics using ``\LaTeX`` syntax with double backticks, -``` `` ``` . - -``` -A paragraph containing some ``\LaTeX`` markup. -``` - -!!! tip - As with literals in the previous section, if literal backticks need to be written within double - backticks use an even number greater than two. Note that if a single literal backtick needs to - be included within ``\LaTeX`` markup then two enclosing backticks is sufficient. - -!!! note - The `\` character should be escaped appropriately if the text is embedded in a Julia source code, - for example, ``` "``\\LaTeX`` syntax in a docstring." ```, since it is interpreted as a string - literal. - -#### Links - -Links to either external or internal addresses can be written using the following syntax, where -the text enclosed in square brackets, `[ ]`, is the name of the link and the text enclosed in -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 -""" - tryparse(type, str; base) - -Like [`parse`](@ref), but returns either a value of the requested type, -or [`nothing`](@ref) if the string does not contain a valid number. -""" -``` - -This will create a link in the generated docs to the [`parse`](@ref) documentation -(which has more information about what this function actually does), and to the -[`nothing`](@ref) documentation. 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 -must be a single alphanumeric word containing no punctuation. - -``` -A paragraph containing a numbered footnote [^1] and a named one [^named]. -``` - -!!! note - The text associated with a footnote can be written anywhere within the same page as the footnote - reference. The syntax used to define the footnote text is discussed in the [Footnotes](@ref) section - below. - -### Toplevel elements - -The following elements can be written either at the "toplevel" of a document or within another -"toplevel" element. - -#### Paragraphs - -A paragraph is a block of plain text, possibly containing any number of inline elements defined -in the [Inline elements](@ref) section above, with one or more blank lines above and below it. - -``` -This is a paragraph. - -And this is *another* one containing some emphasized text. -A new line, but still part of the same paragraph. -``` - -#### Headers - -A document can be split up into different sections using headers. Headers use the following syntax: - -```julia -# Level One -## Level Two -### Level Three -#### Level Four -##### Level Five -###### Level Six -``` - -A header line can contain any inline syntax in the same way as a paragraph can. - -!!! tip - Try to avoid using too many levels of header within a single document. A heavily nested document - may be indicative of a need to restructure it or split it into several pages covering separate - topics. - -#### Code blocks - -Source code can be displayed as a literal block using an indent of four spaces as shown in the -following example. - -``` -This is a paragraph. - - function func(x) - # ... - end - -Another paragraph. -``` - -Additionally, code blocks can be enclosed using triple backticks with an optional "language" to -specify how a block of code should be highlighted. - -```` -A code block without a "language": - -``` -function func(x) - # ... -end -``` - -and another one with the "language" specified as `julia`: - -```julia -function func(x) - # ... -end -``` -```` - -!!! note - "Fenced" code blocks, as shown in the last example, should be preferred over indented code blocks - since there is no way to specify what language an indented code block is written in. - -#### Block quotes - -Text from external sources, such as quotations from books or websites, can be quoted using `>` -characters prepended to each line of the quote as follows. - -``` -Here's a quote: - -> Julia is a high-level, high-performance dynamic programming language for -> technical computing, with syntax that is familiar to users of other -> technical computing environments. -``` - -Note that a single space must appear after the `>` character on each line. Quoted blocks may themselves -contain other toplevel or inline elements. - -#### Images - -The syntax for images is similar to the link syntax mentioned above. Prepending a `!` character -to a link will display an image from the specified URL rather than a link to it. - -```julia -![alternative text](link/to/image.png) -``` - -#### Lists - -Unordered lists can be written by prepending each item in a list with either `*`, `+`, or `-`. - -``` -A list of items: - - * item one - * item two - * item three -``` - -Note the two spaces before each `*` and the single space after each one. - -Lists can contain other nested toplevel elements such as lists, code blocks, or quoteblocks. A -blank line should be left between each list item when including any toplevel elements within a -list. - -``` -Another list: - - * item one - - * item two - - ``` - f(x) = x - ``` - - * And a sublist: - - + sub-item one - + sub-item two -``` - -!!! note - The contents of each item in the list must line up with the first line of the item. In the above - example the fenced code block must be indented by four spaces to align with the `i` in `item two`. - -Ordered lists are written by replacing the "bullet" character, either `*`, `+`, or `-`, with a -positive integer followed by either `.` or `)`. - -``` -Two ordered lists: - - 1. item one - 2. item two - 3. item three - - 5) item five - 6) item six - 7) item seven -``` - -An ordered list may start from a number other than one, as in the second list of the above example, -where it is numbered from five. As with unordered lists, ordered lists can contain nested toplevel -elements. - -#### Display equations - -Large ``\LaTeX`` equations that do not fit inline within a paragraph may be written as display -equations using a fenced code block with the "language" `math` as in the example below. - -````julia -```math -f(a) = \frac{1}{2\pi}\int_{0}^{2\pi} (\alpha+R\cos(\theta))d\theta -``` -```` - -#### Footnotes - -This syntax is paired with the inline syntax for [Footnote references](@ref). Make sure to read -that section as well. - -Footnote text is defined using the following syntax, which is similar to footnote reference syntax, -aside from the `:` character that is appended to the footnote label. - -``` -[^1]: Numbered footnote text. - -[^note]: - - Named footnote text containing several toplevel elements. - - * item one - * item two - * item three - - ```julia - function func(x) - # ... - end - ``` -``` - -!!! note - No checks are done during parsing to make sure that all footnote references have matching footnotes. - -#### Horizontal rules - -The equivalent of an `
` HTML tag can be written using the following syntax: - -``` -Text above the line. - ---- - -And text below the line. -``` - -#### Tables - -Basic tables can be written using the syntax described below. Note that markdown tables have limited -features and cannot contain nested toplevel elements unlike other elements discussed above – -only inline elements are allowed. Tables must always contain a header row with column names. Cells -cannot span multiple rows or columns of the table. - -``` -| Column One | Column Two | Column Three | -|:---------- | ---------- |:------------:| -| Row `1` | Column `2` | | -| *Row* 2 | **Row** 2 | Column ``3`` | -``` - -!!! note - As illustrated in the above example each column of `|` characters must be aligned vertically. - - A `:` character on either end of a column's header separator (the row containing `-` characters) - specifies whether the row is left-aligned, right-aligned, or (when `:` appears on both ends) center-aligned. - Providing no `:` characters will default to right-aligning the column. - -#### Admonitions - -Specially formatted blocks, known as admonitions, can be used to highlight particular remarks. -They can be defined using the following `!!!` syntax: - -``` -!!! note - - This is the content of the note. - -!!! warning "Beware!" - - And this is another one. - - This warning admonition has a custom title: `"Beware!"`. -``` - -The type of the admonition can be any word, but some types produce special styling, -namely (in order of decreasing severity): `danger`, `warning`, `info`/`note`, and `tip`. - -A custom title for the box can be provided as a string (in double quotes) after the admonition type. -If no title text is specified after the admonition type, then the title used will be the type of the block, -i.e. `"Note"` in the case of the `note` admonition. - -Admonitions, like most other toplevel elements, can contain other toplevel elements. - -## Markdown Syntax Extensions - -Julia's markdown supports interpolation in a very similar way to basic string literals, with the -difference that it will store the object itself in the Markdown tree (as opposed to converting -it to a string). When the Markdown content is rendered the usual `show` methods will be called, -and these can be overridden as usual. This design allows the Markdown to be extended with arbitrarily -complex features (such as references) without cluttering the basic syntax. - -In principle, the Markdown parser itself can also be arbitrarily extended by packages, or an entirely -custom flavour of Markdown can be used, but this should generally be unnecessary. diff --git a/codex/manual/unicode-input.md b/codex/manual/unicode-input.md index 5ed935a..489b256 100644 --- a/codex/manual/unicode-input.md +++ b/codex/manual/unicode-input.md @@ -31,7 +31,7 @@ function tab_completions(symbols...) end function unicode_data() - file = normpath(Sys.BINDIR, "..", "..", "doc", "UnicodeData.txt") + file = normpath(@__DIR__, "..", "..", "..", "..", "..", "doc", "UnicodeData.txt") names = Dict{UInt32, String}() open(file) do unidata for line in readlines(unidata) diff --git a/codex/stdlib/Markdown.md b/codex/stdlib/Markdown.md index 7d82df3..75acc6d 100644 --- a/codex/stdlib/Markdown.md +++ b/codex/stdlib/Markdown.md @@ -1 +1,385 @@ # Markdown + +This section describes Julia's markdown syntax, which is enabled by the +Markdown standard library. The following Markdown elements are supported: + +## Inline elements + +Here "inline" refers to elements that can be found within blocks of text, i.e. paragraphs. These +include the following elements. + +### Bold + +Surround words with two asterisks, `**`, to display the enclosed text in boldface. + +``` +A paragraph containing a **bold** word. +``` + +### Italics + +Surround words with one asterisk, `*`, to display the enclosed text in italics. + +``` +A paragraph containing an *emphasized* word. +``` + +### Literals + +Surround text that should be displayed exactly as written with single backticks, ``` ` ``` . + +``` +A paragraph containing a `literal` word. +``` + +Literals should be used when writing text that refers to names of variables, functions, or other +parts of a Julia program. + +!!! tip + To include a backtick character within literal text use three backticks rather than one to enclose + the text. + + ``` + A paragraph containing a ``` `backtick` character ```. + ``` + + By extension any odd number of backticks may be used to enclose a lesser number of backticks. + +### ``\LaTeX`` + +Surround text that should be displayed as mathematics using ``\LaTeX`` syntax with double backticks, +``` `` ``` . + +``` +A paragraph containing some ``\LaTeX`` markup. +``` + +!!! tip + As with literals in the previous section, if literal backticks need to be written within double + backticks use an even number greater than two. Note that if a single literal backtick needs to + be included within ``\LaTeX`` markup then two enclosing backticks is sufficient. + +!!! note + The `\` character should be escaped appropriately if the text is embedded in a Julia source code, + for example, ``` "``\\LaTeX`` syntax in a docstring." ```, since it is interpreted as a string + literal. Alternatively, in order to avoid escaping, it is possible to use the `raw` string macro + together with the `@doc` macro: + ``` + @doc raw"``\LaTeX`` syntax in a docstring." functionname + ``` + +### Links + +Links to either external or internal addresses can be written using the following syntax, where +the text enclosed in square brackets, `[ ]`, is the name of the link and the text enclosed in +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 +""" + tryparse(type, str; base) + +Like [`parse`](@ref), but returns either a value of the requested type, +or [`nothing`](@ref) if the string does not contain a valid number. +""" +``` + +This will create a link in the generated docs to the [`parse`](@ref) documentation +(which has more information about what this function actually does), and to the +[`nothing`](@ref) documentation. 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 +must be a single alphanumeric word containing no punctuation. + +``` +A paragraph containing a numbered footnote [^1] and a named one [^named]. +``` + +!!! note + The text associated with a footnote can be written anywhere within the same page as the footnote + reference. The syntax used to define the footnote text is discussed in the [Footnotes](@ref) section + below. + +## Toplevel elements + +The following elements can be written either at the "toplevel" of a document or within another +"toplevel" element. + +### Paragraphs + +A paragraph is a block of plain text, possibly containing any number of inline elements defined +in the [Inline elements](@ref) section above, with one or more blank lines above and below it. + +``` +This is a paragraph. + +And this is *another* one containing some emphasized text. +A new line, but still part of the same paragraph. +``` + +### Headers + +A document can be split up into different sections using headers. Headers use the following syntax: + +```julia +# Level One +## Level Two +### Level Three +#### Level Four +##### Level Five +###### Level Six +``` + +A header line can contain any inline syntax in the same way as a paragraph can. + +!!! tip + Try to avoid using too many levels of header within a single document. A heavily nested document + may be indicative of a need to restructure it or split it into several pages covering separate + topics. + +### Code blocks + +Source code can be displayed as a literal block using an indent of four spaces as shown in the +following example. + +``` +This is a paragraph. + + function func(x) + # ... + end + +Another paragraph. +``` + +Additionally, code blocks can be enclosed using triple backticks with an optional "language" to +specify how a block of code should be highlighted. + +```` +A code block without a "language": + +``` +function func(x) + # ... +end +``` + +and another one with the "language" specified as `julia`: + +```julia +function func(x) + # ... +end +``` +```` + +!!! note + "Fenced" code blocks, as shown in the last example, should be preferred over indented code blocks + since there is no way to specify what language an indented code block is written in. + +### Block quotes + +Text from external sources, such as quotations from books or websites, can be quoted using `>` +characters prepended to each line of the quote as follows. + +``` +Here's a quote: + +> Julia is a high-level, high-performance dynamic programming language for +> technical computing, with syntax that is familiar to users of other +> technical computing environments. +``` + +Note that a single space must appear after the `>` character on each line. Quoted blocks may themselves +contain other toplevel or inline elements. + +### Images + +The syntax for images is similar to the link syntax mentioned above. Prepending a `!` character +to a link will display an image from the specified URL rather than a link to it. + +```julia +![alternative text](link/to/image.png) +``` + +### Lists + +Unordered lists can be written by prepending each item in a list with either `*`, `+`, or `-`. + +``` +A list of items: + + * item one + * item two + * item three +``` + +Note the two spaces before each `*` and the single space after each one. + +Lists can contain other nested toplevel elements such as lists, code blocks, or quoteblocks. A +blank line should be left between each list item when including any toplevel elements within a +list. + +``` +Another list: + + * item one + + * item two + + ``` + f(x) = x + ``` + + * And a sublist: + + + sub-item one + + sub-item two +``` + +!!! note + The contents of each item in the list must line up with the first line of the item. In the above + example the fenced code block must be indented by four spaces to align with the `i` in `item two`. + +Ordered lists are written by replacing the "bullet" character, either `*`, `+`, or `-`, with a +positive integer followed by either `.` or `)`. + +``` +Two ordered lists: + + 1. item one + 2. item two + 3. item three + + 5) item five + 6) item six + 7) item seven +``` + +An ordered list may start from a number other than one, as in the second list of the above example, +where it is numbered from five. As with unordered lists, ordered lists can contain nested toplevel +elements. + +### Display equations + +Large ``\LaTeX`` equations that do not fit inline within a paragraph may be written as display +equations using a fenced code block with the "language" `math` as in the example below. + +````julia +```math +f(a) = \frac{1}{2\pi}\int_{0}^{2\pi} (\alpha+R\cos(\theta))d\theta +``` +```` + +### Footnotes + +This syntax is paired with the inline syntax for [Footnote references](@ref). Make sure to read +that section as well. + +Footnote text is defined using the following syntax, which is similar to footnote reference syntax, +aside from the `:` character that is appended to the footnote label. + +``` +[^1]: Numbered footnote text. + +[^note]: + + Named footnote text containing several toplevel elements. + + * item one + * item two + * item three + + ```julia + function func(x) + # ... + end + ``` +``` + +!!! note + No checks are done during parsing to make sure that all footnote references have matching footnotes. + +### Horizontal rules + +The equivalent of an `
` HTML tag can be written using the following syntax: + +``` +Text above the line. + +--- + +And text below the line. +``` + +### Tables + +Basic tables can be written using the syntax described below. Note that markdown tables have limited +features and cannot contain nested toplevel elements unlike other elements discussed above – +only inline elements are allowed. Tables must always contain a header row with column names. Cells +cannot span multiple rows or columns of the table. + +``` +| Column One | Column Two | Column Three | +|:---------- | ---------- |:------------:| +| Row `1` | Column `2` | | +| *Row* 2 | **Row** 2 | Column ``3`` | +``` + +!!! note + As illustrated in the above example each column of `|` characters must be aligned vertically. + + A `:` character on either end of a column's header separator (the row containing `-` characters) + specifies whether the row is left-aligned, right-aligned, or (when `:` appears on both ends) center-aligned. + Providing no `:` characters will default to right-aligning the column. + +### Admonitions + +Specially formatted blocks, known as admonitions, can be used to highlight particular remarks. +They can be defined using the following `!!!` syntax: + +``` +!!! note + + This is the content of the note. + +!!! warning "Beware!" + + And this is another one. + + This warning admonition has a custom title: `"Beware!"`. +``` + +The type of the admonition can be any word, but some types produce special styling, +namely (in order of decreasing severity): `danger`, `warning`, `info`/`note`, and `tip`. + +A custom title for the box can be provided as a string (in double quotes) after the admonition type. +If no title text is specified after the admonition type, then the title used will be the type of the block, +i.e. `"Note"` in the case of the `note` admonition. + +Admonitions, like most other toplevel elements, can contain other toplevel elements. + +## Markdown Syntax Extensions + +Julia's markdown supports interpolation in a very similar way to basic string literals, with the +difference that it will store the object itself in the Markdown tree (as opposed to converting +it to a string). When the Markdown content is rendered the usual `show` methods will be called, +and these can be overridden as usual. This design allows the Markdown to be extended with arbitrarily +complex features (such as references) without cluttering the basic syntax. + +In principle, the Markdown parser itself can also be arbitrarily extended by packages, or an entirely +custom flavour of Markdown can be used, but this should generally be unnecessary. diff --git a/src/manual/documentation.md b/src/manual/documentation.md index 1bb2641..4f80dc4 100644 --- a/src/manual/documentation.md +++ b/src/manual/documentation.md @@ -18,6 +18,11 @@ use indentation and code fences to delimit code examples from text. Technically, be associated with any other as metadata; Markdown happens to be the default, but one can construct other string macros and pass them to the `@doc` macro just as well. +!!! note + Markdown support is implemented in the `Markdown` standard library + and for a full list of supported syntax see the + [documentation](@ref Markdown). + Here is a more complex example, still using Markdown: ````julia @@ -96,6 +101,11 @@ As in the example above, we recommend following some simple conventions when wri (see [Code blocks](@ref)) starting with ````` ```jldoctest````` and contains any number of `julia>` prompts together with inputs and expected outputs that mimic the Julia REPL. + !!! note + Doctests are enabled by [`Documenter.jl`](https://github.com/JuliaDocs/Documenter.jl). + For more detailed documentation see Documenter's + [manual](https://juliadocs.github.io/Documenter.jl/). + For example in the following docstring a variable `a` is defined and the expected result, as printed in a Julia REPL, appears afterwards: @@ -545,384 +555,3 @@ should serve as an example of how to use `@__doc__` correctly. ```@docs Core.@__doc__ ``` - -## Markdown syntax - -The following markdown syntax is supported in Julia. - -### Inline elements - -Here "inline" refers to elements that can be found within blocks of text, i.e. paragraphs. These -include the following elements. - -#### Bold - -Surround words with two asterisks, `**`, to display the enclosed text in boldface. - -``` -A paragraph containing a **bold** word. -``` - -#### Italics - -Surround words with one asterisk, `*`, to display the enclosed text in italics. - -``` -A paragraph containing an *emphasized* word. -``` - -#### Literals - -Surround text that should be displayed exactly as written with single backticks, ``` ` ``` . - -``` -A paragraph containing a `literal` word. -``` - -Literals should be used when writing text that refers to names of variables, functions, or other -parts of a Julia program. - -!!! tip - To include a backtick character within literal text use three backticks rather than one to enclose - the text. - - ``` - A paragraph containing a ``` `backtick` character ```. - ``` - - By extension any odd number of backticks may be used to enclose a lesser number of backticks. - -#### ``\LaTeX`` - -Surround text that should be displayed as mathematics using ``\LaTeX`` syntax with double backticks, -``` `` ``` . - -``` -A paragraph containing some ``\LaTeX`` markup. -``` - -!!! tip - As with literals in the previous section, if literal backticks need to be written within double - backticks use an even number greater than two. Note that if a single literal backtick needs to - be included within ``\LaTeX`` markup then two enclosing backticks is sufficient. - -!!! note - The `\` character should be escaped appropriately if the text is embedded in a Julia source code, - for example, ``` "``\\LaTeX`` syntax in a docstring." ```, since it is interpreted as a string - literal. - -#### Links - -Links to either external or internal addresses can be written using the following syntax, where -the text enclosed in square brackets, `[ ]`, is the name of the link and the text enclosed in -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 -""" - tryparse(type, str; base) - -Like [`parse`](@ref), but returns either a value of the requested type, -or [`nothing`](@ref) if the string does not contain a valid number. -""" -``` - -This will create a link in the generated docs to the [`parse`](@ref) documentation -(which has more information about what this function actually does), and to the -[`nothing`](@ref) documentation. 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 -must be a single alphanumeric word containing no punctuation. - -``` -A paragraph containing a numbered footnote [^1] and a named one [^named]. -``` - -!!! note - The text associated with a footnote can be written anywhere within the same page as the footnote - reference. The syntax used to define the footnote text is discussed in the [Footnotes](@ref) section - below. - -### Toplevel elements - -The following elements can be written either at the "toplevel" of a document or within another -"toplevel" element. - -#### Paragraphs - -A paragraph is a block of plain text, possibly containing any number of inline elements defined -in the [Inline elements](@ref) section above, with one or more blank lines above and below it. - -``` -This is a paragraph. - -And this is *another* one containing some emphasized text. -A new line, but still part of the same paragraph. -``` - -#### Headers - -A document can be split up into different sections using headers. Headers use the following syntax: - -```julia -# Level One -## Level Two -### Level Three -#### Level Four -##### Level Five -###### Level Six -``` - -A header line can contain any inline syntax in the same way as a paragraph can. - -!!! tip - Try to avoid using too many levels of header within a single document. A heavily nested document - may be indicative of a need to restructure it or split it into several pages covering separate - topics. - -#### Code blocks - -Source code can be displayed as a literal block using an indent of four spaces as shown in the -following example. - -``` -This is a paragraph. - - function func(x) - # ... - end - -Another paragraph. -``` - -Additionally, code blocks can be enclosed using triple backticks with an optional "language" to -specify how a block of code should be highlighted. - -```` -A code block without a "language": - -``` -function func(x) - # ... -end -``` - -and another one with the "language" specified as `julia`: - -```julia -function func(x) - # ... -end -``` -```` - -!!! note - "Fenced" code blocks, as shown in the last example, should be preferred over indented code blocks - since there is no way to specify what language an indented code block is written in. - -#### Block quotes - -Text from external sources, such as quotations from books or websites, can be quoted using `>` -characters prepended to each line of the quote as follows. - -``` -Here's a quote: - -> Julia is a high-level, high-performance dynamic programming language for -> technical computing, with syntax that is familiar to users of other -> technical computing environments. -``` - -Note that a single space must appear after the `>` character on each line. Quoted blocks may themselves -contain other toplevel or inline elements. - -#### Images - -The syntax for images is similar to the link syntax mentioned above. Prepending a `!` character -to a link will display an image from the specified URL rather than a link to it. - -```julia -![alternative text](link/to/image.png) -``` - -#### Lists - -Unordered lists can be written by prepending each item in a list with either `*`, `+`, or `-`. - -``` -A list of items: - - * item one - * item two - * item three -``` - -Note the two spaces before each `*` and the single space after each one. - -Lists can contain other nested toplevel elements such as lists, code blocks, or quoteblocks. A -blank line should be left between each list item when including any toplevel elements within a -list. - -``` -Another list: - - * item one - - * item two - - ``` - f(x) = x - ``` - - * And a sublist: - - + sub-item one - + sub-item two -``` - -!!! note - The contents of each item in the list must line up with the first line of the item. In the above - example the fenced code block must be indented by four spaces to align with the `i` in `item two`. - -Ordered lists are written by replacing the "bullet" character, either `*`, `+`, or `-`, with a -positive integer followed by either `.` or `)`. - -``` -Two ordered lists: - - 1. item one - 2. item two - 3. item three - - 5) item five - 6) item six - 7) item seven -``` - -An ordered list may start from a number other than one, as in the second list of the above example, -where it is numbered from five. As with unordered lists, ordered lists can contain nested toplevel -elements. - -#### Display equations - -Large ``\LaTeX`` equations that do not fit inline within a paragraph may be written as display -equations using a fenced code block with the "language" `math` as in the example below. - -````julia -```math -f(a) = \frac{1}{2\pi}\int_{0}^{2\pi} (\alpha+R\cos(\theta))d\theta -``` -```` - -#### Footnotes - -This syntax is paired with the inline syntax for [Footnote references](@ref). Make sure to read -that section as well. - -Footnote text is defined using the following syntax, which is similar to footnote reference syntax, -aside from the `:` character that is appended to the footnote label. - -``` -[^1]: Numbered footnote text. - -[^note]: - - Named footnote text containing several toplevel elements. - - * item one - * item two - * item three - - ```julia - function func(x) - # ... - end - ``` -``` - -!!! note - No checks are done during parsing to make sure that all footnote references have matching footnotes. - -#### Horizontal rules - -The equivalent of an `
` HTML tag can be written using the following syntax: - -``` -Text above the line. - ---- - -And text below the line. -``` - -#### Tables - -Basic tables can be written using the syntax described below. Note that markdown tables have limited -features and cannot contain nested toplevel elements unlike other elements discussed above – -only inline elements are allowed. Tables must always contain a header row with column names. Cells -cannot span multiple rows or columns of the table. - -``` -| Column One | Column Two | Column Three | -|:---------- | ---------- |:------------:| -| Row `1` | Column `2` | | -| *Row* 2 | **Row** 2 | Column ``3`` | -``` - -!!! note - As illustrated in the above example each column of `|` characters must be aligned vertically. - - A `:` character on either end of a column's header separator (the row containing `-` characters) - specifies whether the row is left-aligned, right-aligned, or (when `:` appears on both ends) center-aligned. - Providing no `:` characters will default to right-aligning the column. - -#### Admonitions - -Specially formatted blocks, known as admonitions, can be used to highlight particular remarks. -They can be defined using the following `!!!` syntax: - -``` -!!! note - - This is the content of the note. - -!!! warning "Beware!" - - And this is another one. - - This warning admonition has a custom title: `"Beware!"`. -``` - -The type of the admonition can be any word, but some types produce special styling, -namely (in order of decreasing severity): `danger`, `warning`, `info`/`note`, and `tip`. - -A custom title for the box can be provided as a string (in double quotes) after the admonition type. -If no title text is specified after the admonition type, then the title used will be the type of the block, -i.e. `"Note"` in the case of the `note` admonition. - -Admonitions, like most other toplevel elements, can contain other toplevel elements. - -## Markdown Syntax Extensions - -Julia's markdown supports interpolation in a very similar way to basic string literals, with the -difference that it will store the object itself in the Markdown tree (as opposed to converting -it to a string). When the Markdown content is rendered the usual `show` methods will be called, -and these can be overridden as usual. This design allows the Markdown to be extended with arbitrarily -complex features (such as references) without cluttering the basic syntax. - -In principle, the Markdown parser itself can also be arbitrarily extended by packages, or an entirely -custom flavour of Markdown can be used, but this should generally be unnecessary. diff --git a/src/stdlib/Markdown.md b/src/stdlib/Markdown.md index 7d82df3..75acc6d 100644 --- a/src/stdlib/Markdown.md +++ b/src/stdlib/Markdown.md @@ -1 +1,385 @@ # Markdown + +This section describes Julia's markdown syntax, which is enabled by the +Markdown standard library. The following Markdown elements are supported: + +## Inline elements + +Here "inline" refers to elements that can be found within blocks of text, i.e. paragraphs. These +include the following elements. + +### Bold + +Surround words with two asterisks, `**`, to display the enclosed text in boldface. + +``` +A paragraph containing a **bold** word. +``` + +### Italics + +Surround words with one asterisk, `*`, to display the enclosed text in italics. + +``` +A paragraph containing an *emphasized* word. +``` + +### Literals + +Surround text that should be displayed exactly as written with single backticks, ``` ` ``` . + +``` +A paragraph containing a `literal` word. +``` + +Literals should be used when writing text that refers to names of variables, functions, or other +parts of a Julia program. + +!!! tip + To include a backtick character within literal text use three backticks rather than one to enclose + the text. + + ``` + A paragraph containing a ``` `backtick` character ```. + ``` + + By extension any odd number of backticks may be used to enclose a lesser number of backticks. + +### ``\LaTeX`` + +Surround text that should be displayed as mathematics using ``\LaTeX`` syntax with double backticks, +``` `` ``` . + +``` +A paragraph containing some ``\LaTeX`` markup. +``` + +!!! tip + As with literals in the previous section, if literal backticks need to be written within double + backticks use an even number greater than two. Note that if a single literal backtick needs to + be included within ``\LaTeX`` markup then two enclosing backticks is sufficient. + +!!! note + The `\` character should be escaped appropriately if the text is embedded in a Julia source code, + for example, ``` "``\\LaTeX`` syntax in a docstring." ```, since it is interpreted as a string + literal. Alternatively, in order to avoid escaping, it is possible to use the `raw` string macro + together with the `@doc` macro: + ``` + @doc raw"``\LaTeX`` syntax in a docstring." functionname + ``` + +### Links + +Links to either external or internal addresses can be written using the following syntax, where +the text enclosed in square brackets, `[ ]`, is the name of the link and the text enclosed in +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 +""" + tryparse(type, str; base) + +Like [`parse`](@ref), but returns either a value of the requested type, +or [`nothing`](@ref) if the string does not contain a valid number. +""" +``` + +This will create a link in the generated docs to the [`parse`](@ref) documentation +(which has more information about what this function actually does), and to the +[`nothing`](@ref) documentation. 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 +must be a single alphanumeric word containing no punctuation. + +``` +A paragraph containing a numbered footnote [^1] and a named one [^named]. +``` + +!!! note + The text associated with a footnote can be written anywhere within the same page as the footnote + reference. The syntax used to define the footnote text is discussed in the [Footnotes](@ref) section + below. + +## Toplevel elements + +The following elements can be written either at the "toplevel" of a document or within another +"toplevel" element. + +### Paragraphs + +A paragraph is a block of plain text, possibly containing any number of inline elements defined +in the [Inline elements](@ref) section above, with one or more blank lines above and below it. + +``` +This is a paragraph. + +And this is *another* one containing some emphasized text. +A new line, but still part of the same paragraph. +``` + +### Headers + +A document can be split up into different sections using headers. Headers use the following syntax: + +```julia +# Level One +## Level Two +### Level Three +#### Level Four +##### Level Five +###### Level Six +``` + +A header line can contain any inline syntax in the same way as a paragraph can. + +!!! tip + Try to avoid using too many levels of header within a single document. A heavily nested document + may be indicative of a need to restructure it or split it into several pages covering separate + topics. + +### Code blocks + +Source code can be displayed as a literal block using an indent of four spaces as shown in the +following example. + +``` +This is a paragraph. + + function func(x) + # ... + end + +Another paragraph. +``` + +Additionally, code blocks can be enclosed using triple backticks with an optional "language" to +specify how a block of code should be highlighted. + +```` +A code block without a "language": + +``` +function func(x) + # ... +end +``` + +and another one with the "language" specified as `julia`: + +```julia +function func(x) + # ... +end +``` +```` + +!!! note + "Fenced" code blocks, as shown in the last example, should be preferred over indented code blocks + since there is no way to specify what language an indented code block is written in. + +### Block quotes + +Text from external sources, such as quotations from books or websites, can be quoted using `>` +characters prepended to each line of the quote as follows. + +``` +Here's a quote: + +> Julia is a high-level, high-performance dynamic programming language for +> technical computing, with syntax that is familiar to users of other +> technical computing environments. +``` + +Note that a single space must appear after the `>` character on each line. Quoted blocks may themselves +contain other toplevel or inline elements. + +### Images + +The syntax for images is similar to the link syntax mentioned above. Prepending a `!` character +to a link will display an image from the specified URL rather than a link to it. + +```julia +![alternative text](link/to/image.png) +``` + +### Lists + +Unordered lists can be written by prepending each item in a list with either `*`, `+`, or `-`. + +``` +A list of items: + + * item one + * item two + * item three +``` + +Note the two spaces before each `*` and the single space after each one. + +Lists can contain other nested toplevel elements such as lists, code blocks, or quoteblocks. A +blank line should be left between each list item when including any toplevel elements within a +list. + +``` +Another list: + + * item one + + * item two + + ``` + f(x) = x + ``` + + * And a sublist: + + + sub-item one + + sub-item two +``` + +!!! note + The contents of each item in the list must line up with the first line of the item. In the above + example the fenced code block must be indented by four spaces to align with the `i` in `item two`. + +Ordered lists are written by replacing the "bullet" character, either `*`, `+`, or `-`, with a +positive integer followed by either `.` or `)`. + +``` +Two ordered lists: + + 1. item one + 2. item two + 3. item three + + 5) item five + 6) item six + 7) item seven +``` + +An ordered list may start from a number other than one, as in the second list of the above example, +where it is numbered from five. As with unordered lists, ordered lists can contain nested toplevel +elements. + +### Display equations + +Large ``\LaTeX`` equations that do not fit inline within a paragraph may be written as display +equations using a fenced code block with the "language" `math` as in the example below. + +````julia +```math +f(a) = \frac{1}{2\pi}\int_{0}^{2\pi} (\alpha+R\cos(\theta))d\theta +``` +```` + +### Footnotes + +This syntax is paired with the inline syntax for [Footnote references](@ref). Make sure to read +that section as well. + +Footnote text is defined using the following syntax, which is similar to footnote reference syntax, +aside from the `:` character that is appended to the footnote label. + +``` +[^1]: Numbered footnote text. + +[^note]: + + Named footnote text containing several toplevel elements. + + * item one + * item two + * item three + + ```julia + function func(x) + # ... + end + ``` +``` + +!!! note + No checks are done during parsing to make sure that all footnote references have matching footnotes. + +### Horizontal rules + +The equivalent of an `
` HTML tag can be written using the following syntax: + +``` +Text above the line. + +--- + +And text below the line. +``` + +### Tables + +Basic tables can be written using the syntax described below. Note that markdown tables have limited +features and cannot contain nested toplevel elements unlike other elements discussed above – +only inline elements are allowed. Tables must always contain a header row with column names. Cells +cannot span multiple rows or columns of the table. + +``` +| Column One | Column Two | Column Three | +|:---------- | ---------- |:------------:| +| Row `1` | Column `2` | | +| *Row* 2 | **Row** 2 | Column ``3`` | +``` + +!!! note + As illustrated in the above example each column of `|` characters must be aligned vertically. + + A `:` character on either end of a column's header separator (the row containing `-` characters) + specifies whether the row is left-aligned, right-aligned, or (when `:` appears on both ends) center-aligned. + Providing no `:` characters will default to right-aligning the column. + +### Admonitions + +Specially formatted blocks, known as admonitions, can be used to highlight particular remarks. +They can be defined using the following `!!!` syntax: + +``` +!!! note + + This is the content of the note. + +!!! warning "Beware!" + + And this is another one. + + This warning admonition has a custom title: `"Beware!"`. +``` + +The type of the admonition can be any word, but some types produce special styling, +namely (in order of decreasing severity): `danger`, `warning`, `info`/`note`, and `tip`. + +A custom title for the box can be provided as a string (in double quotes) after the admonition type. +If no title text is specified after the admonition type, then the title used will be the type of the block, +i.e. `"Note"` in the case of the `note` admonition. + +Admonitions, like most other toplevel elements, can contain other toplevel elements. + +## Markdown Syntax Extensions + +Julia's markdown supports interpolation in a very similar way to basic string literals, with the +difference that it will store the object itself in the Markdown tree (as opposed to converting +it to a string). When the Markdown content is rendered the usual `show` methods will be called, +and these can be overridden as usual. This design allows the Markdown to be extended with arbitrarily +complex features (such as references) without cluttering the basic syntax. + +In principle, the Markdown parser itself can also be arbitrarily extended by packages, or an entirely +custom flavour of Markdown can be used, but this should generally be unnecessary. From 26566d5977b42f63c0bc1174f4e5d6d3fcb33e43 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Tue, 20 Nov 2018 15:11:18 +0900 Subject: [PATCH 078/153] update Julia Commit 9f43871e54 --- codex/base/numbers.md | 5 +---- codex/manual/arrays.md | 8 ++++++-- codex/manual/environment-variables.md | 15 +++++++++++++++ codex/manual/performance-tips.md | 2 +- codex/manual/strings.md | 27 +++++++++++++++++++++++++++ codex/stdlib/LinearAlgebra.md | 1 + src/base/numbers.md | 5 +---- src/manual/arrays.md | 6 +++++- src/manual/environment-variables.md | 15 +++++++++++++++ src/manual/performance-tips.md | 2 +- src/manual/strings.md | 27 +++++++++++++++++++++++++++ src/stdlib/LinearAlgebra.md | 1 + 12 files changed, 101 insertions(+), 13 deletions(-) diff --git a/codex/base/numbers.md b/codex/base/numbers.md index 50e6d2b..f07f7f5 100644 --- a/codex/base/numbers.md +++ b/codex/base/numbers.md @@ -120,13 +120,10 @@ and for [`BigInt`](@ref) the [GNU Multiple Precision Arithmetic Library (GMP)] (https://gmplib.org) is used. ```@docs -Base.MPFR.BigFloat(::Any) +Base.MPFR.BigFloat(::Any, rounding::RoundingMode) Base.precision Base.MPFR.precision(::Type{BigFloat}) Base.MPFR.setprecision -Base.MPFR.BigFloat(x, prec::Int) -Base.MPFR.BigFloat(x::Union{Integer, AbstractFloat, String}, rounding::RoundingMode) -Base.MPFR.BigFloat(x, prec::Int, rounding::RoundingMode) Base.GMP.BigInt(::Any) Base.@big_str ``` diff --git a/codex/manual/arrays.md b/codex/manual/arrays.md index ff9b803..7c96925 100644 --- a/codex/manual/arrays.md +++ b/codex/manual/arrays.md @@ -424,8 +424,12 @@ subsections, and arrays of booleans to select elements at their `true` indices. If `X` is an array, it must have the same number of elements as the product of the lengths of the indices: `prod(length(I_1), length(I_2), ..., length(I_n))`. The value in location `I_1[i_1], I_2[i_2], ..., I_n[i_n]` -of `A` is overwritten with the value `X[i_1, i_2, ..., i_n]`. If `X` is not an array, its value -is written to all referenced locations of `A`. +of `A` is overwritten with the value `X[i_1, i_2, ..., i_n]`. If `X` is a scalar, use the +element-wise assignment operator `.=` to write the value to all referenced locations of `A`: + +``` +A[I_1, I_2, ..., I_n] .= X +``` Just as in [Indexing](@ref man-array-indexing), the `end` keyword may be used to represent the last index of each dimension within the indexing brackets, as diff --git a/codex/manual/environment-variables.md b/codex/manual/environment-variables.md index d38aa0f..d92260d 100644 --- a/codex/manual/environment-variables.md +++ b/codex/manual/environment-variables.md @@ -14,6 +14,13 @@ The environment variables that Julia uses generally start with `JULIA`. If output will list defined environment variables relevant for Julia, including those for which `JULIA` appears in the name. +!!! note + + Some variables, such as `JULIA_NUM_THREADS` and `JULIA_PROJECT` need to be set before Julia + starts, therefore adding these to `~/.julia/config/startup.jl` is too late in the startup process. + These must either be set manually before launching Julia through bash with + `export JULIA_NUM_THREADS=4` etc. or added to `-/.bashrc` and/or `~/.bash_profile` to achieve persistence. + ## File locations ### `JULIA_BINDIR` @@ -74,6 +81,10 @@ Julia tries to find a project directory that contains `Project.toml` or `JuliaProject.toml` file from the current directory and its parents. See also the chapter on [Code Loading](@ref). +!!! note + + `JULIA_PROJECT` must be defined before starting julia; defining it in `startup.jl` is too late in the startup process. + ### `JULIA_LOAD_PATH` A separated list of absolute paths that are to be appended to the variable @@ -152,6 +163,10 @@ physical CPU cores, then the number of threads is set to the number of cores. If cores cannot be determined through system calls, then the number of threads is set to `1`. +!!! note + + `JULIA_NUM_THREADS` must be defined before starting julia; defining it in `startup.jl` is too late in the startup process. + ### `JULIA_THREAD_SLEEP_THRESHOLD` If set to a string that starts with the case-insensitive substring `"infinite"`, diff --git a/codex/manual/performance-tips.md b/codex/manual/performance-tips.md index 3a3f246..f962cdd 100644 --- a/codex/manual/performance-tips.md +++ b/codex/manual/performance-tips.md @@ -707,7 +707,7 @@ type-domain. ## The dangers of abusing multiple dispatch (aka, more on types with values-as-parameters) -Once one learns to appreciate multiple dispatch, there's an understandable tendency to go crazy +Once one learns to appreciate multiple dispatch, there's an understandable tendency to go overboard and try to use it for everything. For example, you might imagine using it to store information, e.g. diff --git a/codex/manual/strings.md b/codex/manual/strings.md index 9e3606c..87a9ed5 100644 --- a/codex/manual/strings.md +++ b/codex/manual/strings.md @@ -936,6 +936,33 @@ ERROR: syntax: invalid escape sequence Triple-quoted regex strings, of the form `r"""..."""`, are also supported (and may be convenient for regular expressions containing quotation marks or newlines). +The `Regex()` constructor may be used to create a valid regex string programmatically. This permits using the contents of string variables and other string operations when constructing the regex string. Any of the regex codes above can be used within the single string argument to `Regex()`. Here are some examples: + +```jldoctest +julia> using Dates + +julia> d = Date(1962,7,10) +1962-07-10 + +julia> regex_d = Regex("Day " * string(day(d))) +r"Day 10" + +julia> match(regex_d, "It happened on Day 10") +RegexMatch("Day 10") + +julia> name = "Jon" +"Jon" + +julia> regex_name = Regex("[\"( ]$name[\") ]") # interpolate value of name +r"[\"( ]Jon[\") ]" + +julia> match(regex_name," Jon ") +RegexMatch(" Jon ") + +julia> match(regex_name,"[Jon]") === nothing +true +``` + ## [Byte Array Literals](@id man-byte-array-literals) Another useful non-standard string literal is the byte-array string literal: `b"..."`. This diff --git a/codex/stdlib/LinearAlgebra.md b/codex/stdlib/LinearAlgebra.md index 7717baa..e941069 100644 --- a/codex/stdlib/LinearAlgebra.md +++ b/codex/stdlib/LinearAlgebra.md @@ -415,6 +415,7 @@ LinearAlgebra.adjoint! Base.copy(::Union{Transpose,Adjoint}) LinearAlgebra.stride1 LinearAlgebra.checksquare +LinearAlgebra.peakflops ``` ## Low-level matrix operations diff --git a/src/base/numbers.md b/src/base/numbers.md index 50e6d2b..f07f7f5 100644 --- a/src/base/numbers.md +++ b/src/base/numbers.md @@ -120,13 +120,10 @@ and for [`BigInt`](@ref) the [GNU Multiple Precision Arithmetic Library (GMP)] (https://gmplib.org) is used. ```@docs -Base.MPFR.BigFloat(::Any) +Base.MPFR.BigFloat(::Any, rounding::RoundingMode) Base.precision Base.MPFR.precision(::Type{BigFloat}) Base.MPFR.setprecision -Base.MPFR.BigFloat(x, prec::Int) -Base.MPFR.BigFloat(x::Union{Integer, AbstractFloat, String}, rounding::RoundingMode) -Base.MPFR.BigFloat(x, prec::Int, rounding::RoundingMode) Base.GMP.BigInt(::Any) Base.@big_str ``` diff --git a/src/manual/arrays.md b/src/manual/arrays.md index 33dfded..bfb8f6e 100644 --- a/src/manual/arrays.md +++ b/src/manual/arrays.md @@ -401,7 +401,11 @@ A[I_1, I_2, ..., I_n] = X 만약 `X`가 배열이라면, 그 원소의 갯수는 모든 인덱스 길이의 곱인 `prod(length(I_1), length(I_2), ..., length(I_n))`와 같아야 한다. `A`의 `I_1[i_1], I_2[i_2], ..., I_n[i_n]` 위치에 있는 값은 `X[i_1, i_2, ..., i_n]` 값으로 덮어쓰인다. -만약 `X`가 배열이 아니라면, `A`의 참조된 모든 위치에 `X`의 값이 대입된다. +만약 `X`가 스칼라(scala)면, `A`의 모든 위치에 `.=` (element-wise assignment operator)를 적용한다: + +``` +A[I_1, I_2, ..., I_n] .= X +``` [인덱싱](@ref man-array-indexing)에서와 마찬가지로, 각 차원의 마지막 인덱스를 나타내기 위해서 인덱싱 괄호 안에서 `end` 키워드를 사용할 수 있다. 마지막 인덱스는 인덱싱 되는 가장 안쪽의 배열의 크기에 따라 결정된다. diff --git a/src/manual/environment-variables.md b/src/manual/environment-variables.md index d38aa0f..d92260d 100644 --- a/src/manual/environment-variables.md +++ b/src/manual/environment-variables.md @@ -14,6 +14,13 @@ The environment variables that Julia uses generally start with `JULIA`. If output will list defined environment variables relevant for Julia, including those for which `JULIA` appears in the name. +!!! note + + Some variables, such as `JULIA_NUM_THREADS` and `JULIA_PROJECT` need to be set before Julia + starts, therefore adding these to `~/.julia/config/startup.jl` is too late in the startup process. + These must either be set manually before launching Julia through bash with + `export JULIA_NUM_THREADS=4` etc. or added to `-/.bashrc` and/or `~/.bash_profile` to achieve persistence. + ## File locations ### `JULIA_BINDIR` @@ -74,6 +81,10 @@ Julia tries to find a project directory that contains `Project.toml` or `JuliaProject.toml` file from the current directory and its parents. See also the chapter on [Code Loading](@ref). +!!! note + + `JULIA_PROJECT` must be defined before starting julia; defining it in `startup.jl` is too late in the startup process. + ### `JULIA_LOAD_PATH` A separated list of absolute paths that are to be appended to the variable @@ -152,6 +163,10 @@ physical CPU cores, then the number of threads is set to the number of cores. If cores cannot be determined through system calls, then the number of threads is set to `1`. +!!! note + + `JULIA_NUM_THREADS` must be defined before starting julia; defining it in `startup.jl` is too late in the startup process. + ### `JULIA_THREAD_SLEEP_THRESHOLD` If set to a string that starts with the case-insensitive substring `"infinite"`, diff --git a/src/manual/performance-tips.md b/src/manual/performance-tips.md index 3a3f246..f962cdd 100644 --- a/src/manual/performance-tips.md +++ b/src/manual/performance-tips.md @@ -707,7 +707,7 @@ type-domain. ## The dangers of abusing multiple dispatch (aka, more on types with values-as-parameters) -Once one learns to appreciate multiple dispatch, there's an understandable tendency to go crazy +Once one learns to appreciate multiple dispatch, there's an understandable tendency to go overboard and try to use it for everything. For example, you might imagine using it to store information, e.g. diff --git a/src/manual/strings.md b/src/manual/strings.md index 9e3606c..87a9ed5 100644 --- a/src/manual/strings.md +++ b/src/manual/strings.md @@ -936,6 +936,33 @@ ERROR: syntax: invalid escape sequence Triple-quoted regex strings, of the form `r"""..."""`, are also supported (and may be convenient for regular expressions containing quotation marks or newlines). +The `Regex()` constructor may be used to create a valid regex string programmatically. This permits using the contents of string variables and other string operations when constructing the regex string. Any of the regex codes above can be used within the single string argument to `Regex()`. Here are some examples: + +```jldoctest +julia> using Dates + +julia> d = Date(1962,7,10) +1962-07-10 + +julia> regex_d = Regex("Day " * string(day(d))) +r"Day 10" + +julia> match(regex_d, "It happened on Day 10") +RegexMatch("Day 10") + +julia> name = "Jon" +"Jon" + +julia> regex_name = Regex("[\"( ]$name[\") ]") # interpolate value of name +r"[\"( ]Jon[\") ]" + +julia> match(regex_name," Jon ") +RegexMatch(" Jon ") + +julia> match(regex_name,"[Jon]") === nothing +true +``` + ## [Byte Array Literals](@id man-byte-array-literals) Another useful non-standard string literal is the byte-array string literal: `b"..."`. This diff --git a/src/stdlib/LinearAlgebra.md b/src/stdlib/LinearAlgebra.md index 7717baa..e941069 100644 --- a/src/stdlib/LinearAlgebra.md +++ b/src/stdlib/LinearAlgebra.md @@ -415,6 +415,7 @@ LinearAlgebra.adjoint! Base.copy(::Union{Transpose,Adjoint}) LinearAlgebra.stride1 LinearAlgebra.checksquare +LinearAlgebra.peakflops ``` ## Low-level matrix operations From 9d08afd9b54a4477fd58ee15f45a44a65125ea1e Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Tue, 27 Nov 2018 18:36:33 +0900 Subject: [PATCH 079/153] update Julia Commit 58c0ed57dc --- Manifest.toml | 79 ++++++++++++++++++++++++++++++ Project.toml | 2 + codex/NEWS.md | 27 ---------- codex/manual/parallel-computing.md | 2 +- codex/stdlib/REPL.md | 15 ++++++ make.jl | 8 +-- src/NEWS.md | 29 ----------- src/manual/parallel-computing.md | 2 +- src/stdlib/REPL.md | 15 ++++++ 9 files changed, 117 insertions(+), 62 deletions(-) create mode 100644 Manifest.toml create mode 100644 Project.toml delete mode 100644 codex/NEWS.md delete mode 100644 src/NEWS.md diff --git a/Manifest.toml b/Manifest.toml new file mode 100644 index 0000000..609d04b --- /dev/null +++ b/Manifest.toml @@ -0,0 +1,79 @@ +[[Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" + +[[Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" + +[[Distributed]] +deps = ["LinearAlgebra", "Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" + +[[DocStringExtensions]] +deps = ["LibGit2", "Markdown", "Pkg", "Test"] +git-tree-sha1 = "a016e0bfe98a748c4488e2248c2ef4c67d6fdd35" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.5.0" + +[[Documenter]] +deps = ["Base64", "DocStringExtensions", "InteractiveUtils", "LibGit2", "Logging", "Markdown", "Pkg", "REPL", "Random", "Test", "Unicode"] +git-tree-sha1 = "9f2135e0e7ecb63f9c3ef73ea15a31d8cdb79bb7" +uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" +version = "0.20.0" + +[[InteractiveUtils]] +deps = ["LinearAlgebra", "Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" + +[[LibGit2]] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" + +[[Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" + +[[LinearAlgebra]] +deps = ["Libdl"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + +[[Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" + +[[Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" + +[[Pkg]] +deps = ["Dates", "LibGit2", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" + +[[Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[REPL]] +deps = ["InteractiveUtils", "Markdown", "Sockets"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + +[[Random]] +deps = ["Serialization"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" + +[[Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" + +[[Test]] +deps = ["Distributed", "InteractiveUtils", "Logging", "Random"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[UUIDs]] +deps = ["Random", "SHA"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" + +[[Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" diff --git a/Project.toml b/Project.toml new file mode 100644 index 0000000..dfa65cd --- /dev/null +++ b/Project.toml @@ -0,0 +1,2 @@ +[deps] +Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" diff --git a/codex/NEWS.md b/codex/NEWS.md deleted file mode 100644 index b77894e..0000000 --- a/codex/NEWS.md +++ /dev/null @@ -1,27 +0,0 @@ -Julia v1.0.0 Release Notes -========================== - -New language features ---------------------- - -Language changes ----------------- - -Breaking changes ----------------- - -Library improvements --------------------- - -Compiler/Runtime improvements ------------------------------ - -Deprecated or removed ---------------------- - -The old package manager (now called `OldPkg`) has been moved to a -separate repository at https://github.com/JuliaArchive/OldPkg.jl ([#27930](https://github.com/JuliaLang/julia/issues/27930)) - -Command-line option changes ---------------------------- - diff --git a/codex/manual/parallel-computing.md b/codex/manual/parallel-computing.md index 415def3..ab7052f 100644 --- a/codex/manual/parallel-computing.md +++ b/codex/manual/parallel-computing.md @@ -869,7 +869,7 @@ julia> let B = B remotecall_fetch(()->B, 2) end; -julia> @fetchfrom 2 varinfo() +julia> @fetchfrom 2 InteractiveUtils.varinfo() name size summary ––––––––– ––––––––– –––––––––––––––––––––– A 800 bytes 10×10 Array{Float64,2} diff --git a/codex/stdlib/REPL.md b/codex/stdlib/REPL.md index 3f50791..0526193 100644 --- a/codex/stdlib/REPL.md +++ b/codex/stdlib/REPL.md @@ -316,6 +316,21 @@ lastindex offset string The completion of fields for output from functions uses type inference, and it can only suggest fields if the function is type stable. +Dictionary keys can also be tab completed: + +```julia-repl +julia> foo = Dict("qwer1"=>1, "qwer2"=>2, "asdf"=>3) +Dict{String,Int64} with 3 entries: + "qwer2" => 2 + "asdf" => 3 + "qwer1" => 1 + +julia> foo["q[TAB] + +"qwer1" "qwer2" +julia> foo["qwer +``` + ## Customizing Colors The colors used by Julia and the REPL can be customized, as well. To change the diff --git a/make.jl b/make.jl index d0a9989..fd43efa 100644 --- a/make.jl +++ b/make.jl @@ -1,14 +1,14 @@ # code from https://github.com/JuliaLang/julia/blob/master/doc/make.jl # Install dependencies needed to build the documentation. -using Pkg +empty!(LOAD_PATH) +push!(LOAD_PATH, @__DIR__, "@stdlib") empty!(DEPOT_PATH) pushfirst!(DEPOT_PATH, joinpath(@__DIR__, "deps")) -pushfirst!(LOAD_PATH, @__DIR__) if !isdir(joinpath(@__DIR__, "deps", "packages", "Documenter")) || "deps" in ARGS + using Pkg Pkg.instantiate() - Pkg.add("Documenter") end using Documenter @@ -22,7 +22,7 @@ baremodule GenStdLib end end # make links for stdlib package docs, this is needed until #522 in Documenter.jl is finished -const STDLIB_DIR = normpath(@__DIR__, "..", "julia", "stdlib") +const STDLIB_DIR = Sys.STDLIB const STDLIB_DOCS = filter(!ismissing, map(readdir(STDLIB_DIR)) do dir sourcefile = joinpath(STDLIB_DIR, dir, "docs", "src", "index.md") if isfile(sourcefile) diff --git a/src/NEWS.md b/src/NEWS.md deleted file mode 100644 index ac7b3ae..0000000 --- a/src/NEWS.md +++ /dev/null @@ -1,29 +0,0 @@ -Julia v1.0.0 Release Notes -========================== - -New language features ---------------------- - -Language changes ----------------- - -Breaking changes ----------------- - -Library improvements --------------------- - -Compiler/Runtime improvements ------------------------------ - -Deprecated or removed ---------------------- - -The old package manager (now called `OldPkg`) has been moved to a -separate repository at https://github.com/JuliaArchive/OldPkg.jl ([#27930]) - -Command-line option changes ---------------------------- - - -[#27930]: https://github.com/JuliaLang/julia/issues/27930 diff --git a/src/manual/parallel-computing.md b/src/manual/parallel-computing.md index 415def3..ab7052f 100644 --- a/src/manual/parallel-computing.md +++ b/src/manual/parallel-computing.md @@ -869,7 +869,7 @@ julia> let B = B remotecall_fetch(()->B, 2) end; -julia> @fetchfrom 2 varinfo() +julia> @fetchfrom 2 InteractiveUtils.varinfo() name size summary ––––––––– ––––––––– –––––––––––––––––––––– A 800 bytes 10×10 Array{Float64,2} diff --git a/src/stdlib/REPL.md b/src/stdlib/REPL.md index 3f50791..0526193 100644 --- a/src/stdlib/REPL.md +++ b/src/stdlib/REPL.md @@ -316,6 +316,21 @@ lastindex offset string The completion of fields for output from functions uses type inference, and it can only suggest fields if the function is type stable. +Dictionary keys can also be tab completed: + +```julia-repl +julia> foo = Dict("qwer1"=>1, "qwer2"=>2, "asdf"=>3) +Dict{String,Int64} with 3 entries: + "qwer2" => 2 + "asdf" => 3 + "qwer1" => 1 + +julia> foo["q[TAB] + +"qwer1" "qwer2" +julia> foo["qwer +``` + ## Customizing Colors The colors used by Julia and the REPL can be customized, as well. To change the From c80ea7543935521410d81ff22f947c4b8626bbc7 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Thu, 6 Dec 2018 21:52:08 +0900 Subject: [PATCH 080/153] update Julia Commit 5cbbed32ef --- codex/NEWS.md | 130 +++ codex/assets/julia-manual.css | 8 + codex/base/base.md | 4 + codex/devdocs/ast.md | 3 + codex/devdocs/isbitsunionarrays.md | 4 +- codex/devdocs/object.md | 1 - codex/devdocs/reflection.md | 18 +- codex/manual/calling-c-and-fortran-code.md | 5 + .../handling-operating-system-variation.md | 11 +- codex/manual/stacktraces.md | 3 + codex/manual/strings.md | 2 +- codex/stdlib/LinearAlgebra.md | 2 + codex/stdlib/Pkg.md | 872 +----------------- make.jl | 2 +- src/NEWS.md | 130 +++ src/assets/julia-manual.css | 8 + src/base/base.md | 4 + src/devdocs/ast.md | 3 + src/devdocs/isbitsunionarrays.md | 4 +- src/devdocs/object.md | 1 - src/devdocs/reflection.md | 18 +- src/manual/calling-c-and-fortran-code.md | 5 + .../handling-operating-system-variation.md | 11 +- src/manual/stacktraces.md | 3 + src/manual/strings.md | 2 +- src/stdlib/LinearAlgebra.md | 2 + src/stdlib/Pkg.md | 872 +----------------- 27 files changed, 371 insertions(+), 1757 deletions(-) create mode 100644 codex/NEWS.md create mode 100644 src/NEWS.md diff --git a/codex/NEWS.md b/codex/NEWS.md new file mode 100644 index 0000000..e69cd41 --- /dev/null +++ b/codex/NEWS.md @@ -0,0 +1,130 @@ +Julia v1.1 Release Notes +========================== + +New language features +--------------------- + + * An *exception stack* is maintained on each task to make exception handling more robust and enable root cause analysis using `catch_stack` ([#28878](https://github.com/JuliaLang/julia/issues/28878)). + * The experimental macro `Base.@locals` returns a dictionary of current local variable names + and values ([#29733](https://github.com/JuliaLang/julia/issues/29733)). + +Language changes +---------------- + + * Parser inputs ending with a comma are now consistently treated as incomplete. + Previously they were sometimes parsed as tuples, depending on whitespace ([#28506](https://github.com/JuliaLang/julia/issues/28506)). + * Spaces were accidentally allowed in broadcast call syntax, e.g. `f. (x)`. They are now + disallowed, consistent with normal function call syntax ([#29781](https://github.com/JuliaLang/julia/issues/29781)). + * Big integer literals and command syntax (backticks) are now parsed with the name of + the macro (`@int128_str`, `@uint128_str`, `@big_str`, `@cmd`) qualified to refer + to the `Core` module ([#29968](https://github.com/JuliaLang/julia/issues/29968)). + * Using the same name for both a local variable and a static parameter is now an error instead + of a warning ([#29429](https://github.com/JuliaLang/julia/issues/29429)). + * Method signatures such as + `f(::Type{T}, ::T) where {T <: X}` and + `f(::Type{X}, ::Any)` + are now considered ambiguous. Previously a bug caused the first one to be considered more specific ([#30160](https://github.com/JuliaLang/julia/issues/30160)). + +Command-line option changes +--------------------------- + + * When a script run in interactive mode (`-i`) throws an error, the REPL now starts after + the error is displayed. Previously the REPL only started if the script completed without + error ([#21233](https://github.com/JuliaLang/julia/issues/21233)). + +New library functions +--------------------- + + * `splitpath(p::String)` function, which is the opposite of `joinpath(parts...)`: it splits a filepath into its components ([#28156](https://github.com/JuliaLang/julia/issues/28156)). + * `isnothing(::Any)` function, to check whether something is a `Nothing`, returns a `Bool` ([#29679](https://github.com/JuliaLang/julia/issues/29679)). + * `getpid(::Process)` method ([#24064](https://github.com/JuliaLang/julia/issues/24064)). + * `eachrow`, `eachcol` and `eachslice` functions provide efficient iterators over slices of arrays ([#29749](https://github.com/JuliaLang/julia/issues/29749)). + * `fieldtypes(T::Type)` which return the declared types of the field in type T ([#29600](https://github.com/JuliaLang/julia/issues/29600)). + * `uuid5` has been added to the `UUIDs` standard library ([#28761](https://github.com/JuliaLang/julia/issues/28761)). + * Predicate functions `Sys.isfreebsd`, `Sys.isopenbsd`, `Sys.isnetbsd`, and `Sys.isdragonfly` for + detecting BSD systems have been added ([#30249](https://github.com/JuliaLang/julia/issues/30249)). + +Standard library changes +------------------------ + + * `CartesianIndices` can now be constructed from two `CartesianIndex`es `I` and `J` with `I:J` ([#29440](https://github.com/JuliaLang/julia/issues/29440)). + * `CartesianIndices` support broadcasting arithmetic (+ and -) with a `CartesianIndex` ([#29890](https://github.com/JuliaLang/julia/issues/29890)). + * `copy!` support for arrays, dicts, and sets has been moved to Base from the Future package ([#29173](https://github.com/JuliaLang/julia/issues/29173)). + * Channels now convert inserted values (like containers) instead of requiring types to match ([#29092](https://github.com/JuliaLang/julia/issues/29092)). + * `range` can accept the stop value as a positional argument, e.g. `range(1,10,step=2)` ([#28708](https://github.com/JuliaLang/julia/issues/28708)). + * `diff` now supports arrays of arbitrary dimensionality and can operate over any dimension ([#29827](https://github.com/JuliaLang/julia/issues/29827)). + * The constructor `BigFloat(::BigFloat)` now respects the global precision setting and always + returns a `BigFloat` with precision equal to `precision(BigFloat)` ([#29127](https://github.com/JuliaLang/julia/issues/29127)). The optional + `precision` argument to override the global setting is now a keyword instead of positional + argument ([#29157](https://github.com/JuliaLang/julia/issues/29157)). + * The use of scientific notation when printing `BigFloat` values is now consistent with other floating point + types ([#29211](https://github.com/JuliaLang/julia/issues/29211)). + * `Regex` now behave like a scalar when used in broadcasting ([#29913](https://github.com/JuliaLang/julia/issues/29913)). + * `Char` now behaves like a read-only 0-dimensional array ([#29819](https://github.com/JuliaLang/julia/issues/29819)). + * `parse` now allows strings representing integer 0 and 1 for type `Bool` ([#29980](https://github.com/JuliaLang/julia/issues/29980)). + * `Base.tail` now works on named tuples ([#29595](https://github.com/JuliaLang/julia/issues/29595)). + * The process id is appended to malloc log files in order to track memory allocations of + multiple processes ([#29969](https://github.com/JuliaLang/julia/issues/29969)). + * `Base.julia_cmd` now propagates the `--inline=(yes|no)` flag ([#29858](https://github.com/JuliaLang/julia/issues/29858)). + * `Base.@kwdef` can now be used for parametric structs, and for structs with supertypes ([#29316](https://github.com/JuliaLang/julia/issues/29316)). + * `merge(::NamedTuple, ::NamedTuple...)` can now be used with more than 2 `NamedTuple`s ([#29259](https://github.com/JuliaLang/julia/issues/29259)). + * `Future.copy!` has been moved to `Base` ([#29178](https://github.com/JuliaLang/julia/issues/29178)). + * New `ncodeunits(c::Char)` method as a fast equivalent to `ncodeunits(string(c))` ([#29153](https://github.com/JuliaLang/julia/issues/29153)). + * New `sort!(::AbstractArray; dims)` method that can sort the array along the `dims` dimension ([#28902](https://github.com/JuliaLang/julia/issues/28902)). + * `range` now accept `stop` as a positional argument ([#28708](https://github.com/JuliaLang/julia/issues/28708)). + * `parse(Bool, str)` is now supported ([#29997](https://github.com/JuliaLang/julia/issues/29997)). + * `copyto!(::AbstractMatrix, ::UniformScaling)` supports rectangular matrices now ([#28790](https://github.com/JuliaLang/julia/issues/28790)). + * In `put!(c::Channel{T}, v)`, `v` now gets converted to `T` as `put!` is being called ([#29092](https://github.com/JuliaLang/julia/issues/29092)). + * `current_project()` now searches the parent directories of a Git repository for a `Project.toml` file. + This also affects the behavior of the `--project` command line option when using the default + `--project=@.` ([#29108](https://github.com/JuliaLang/julia/issues/29108)). + +#### Dates + * New `DateTime(::Date, ::Time)` constructor ([#29754](https://github.com/JuliaLang/julia/issues/29754)). + * `TimeZone` now behave like a scalar when used in broadcasting ([#30159](https://github.com/JuliaLang/julia/issues/30159)). + +#### InteractiveUtils + * `edit` can now be called on a module to edit the file that defines it ([#29636](https://github.com/JuliaLang/julia/issues/29636)). + * All compiler-reflection tools (i.e. the `code_` class of functions and macros) now print accurate + line number and inlining information in a common style, and take an optional parameter (debuginfo=:default) + to control the verbosity of the metadata shown ([#29893](https://github.com/JuliaLang/julia/issues/29893)). + +#### LinearAlgebra + * `isdiag` and `isposdef` for `Diagonal` and `UniformScaling` ([#29638](https://github.com/JuliaLang/julia/issues/29638)). + * `mul!`, `rmul!` and `lmul!` methods for `UniformScaling` ([#29506](https://github.com/JuliaLang/julia/issues/29506)). + * `Symmetric` and `Hermitian` matrices now preserve the wrapper when scaled with a number ([#29469](https://github.com/JuliaLang/julia/issues/29469)). + * Exponentiation operator `^` now supports raising a `Irrational` to an `AbstractMatrix` power ([#29782](https://github.com/JuliaLang/julia/issues/29782)). + +#### Random + * `randperm` and `randcycle` now use the type of their argument to determine the element type of + the returned array ([#29670](https://github.com/JuliaLang/julia/issues/29670)). + * A new method `rand(::Tuple)` implements sampling from the values of a tuple ([#25278](https://github.com/JuliaLang/julia/issues/25278)). + * `serialize` and `deserialize` now accept a filename argument, like `write` and `read` ([#30151](https://github.com/JuliaLang/julia/issues/30151)). + +#### SparseArrays + * `sprandn` now supports specifying the output element type ([#30083](https://github.com/JuliaLang/julia/issues/30083)). + +#### Statistics + * `mean` and `var` now handles the empty case ([#29033](https://github.com/JuliaLang/julia/issues/29033)). + +External dependencies +--------------------- + + * 7zip (bundled with Julia on Windows) has been upgraded from version 16.04 to 18.05 ([#30035](https://github.com/JuliaLang/julia/issues/30035)). + * Busybox is no longer bundled with Julia on Windows ([#30022](https://github.com/JuliaLang/julia/issues/30022)). + * OpenBLAS has been upgraded from 0.3.2 to 0.3.3 ([#29845](https://github.com/JuliaLang/julia/issues/29845)). + * The source code for Pkg is no longer included in JuliaLang/julia. Pkg is instead + downloaded during the build process ([#29615](https://github.com/JuliaLang/julia/issues/29615)). + * LLVM has been upgraded to 6.0.1 and support for LLVM < 6.0 has been dropped ([#28745](https://github.com/JuliaLang/julia/issues/28745), [#28696](https://github.com/JuliaLang/julia/issues/28696)). + +Deprecated or removed +--------------------- + + * `one(i::CartesianIndex)` should be replaced with `oneunit(i::CartesianIndex)` ([#29442](https://github.com/JuliaLang/julia/issues/29442)). + * The internal array `Base.Grisu.DIGITS` is deprecated; new code should use `Base.Grisu.getbuf()` + to get an appropriate task-local buffer and pass it to `grisu()` instead ([#29907](https://github.com/JuliaLang/julia/issues/29907)). + * The internal function `Base._default_type(T)` has been removed. Calls to it should be + replaced with just the argument `T` ([#29739](https://github.com/JuliaLang/julia/issues/29739)). + * `peakflops` has been scheduled to move from `InteractiveUtils` to `LinearAlgebra` + but is already now available as `LinearAlgebra.peakflops` ([#29978](https://github.com/JuliaLang/julia/issues/29978)). + diff --git a/codex/assets/julia-manual.css b/codex/assets/julia-manual.css index 00772f3..f303c67 100644 --- a/codex/assets/julia-manual.css +++ b/codex/assets/julia-manual.css @@ -1,3 +1,11 @@ nav.toc h1 { display: none; } + +.admonition.compat > .admonition-title { + background-color: hsla(90, 60%, 50%, 1); +} + +.admonition.compat { + background-color: hsla(90, 70%, 90%, 1); +} diff --git a/codex/base/base.md b/codex/base/base.md index fe609bc..2e057cb 100644 --- a/codex/base/base.md +++ b/codex/base/base.md @@ -285,6 +285,10 @@ Base.Sys.isunix Base.Sys.isapple Base.Sys.islinux Base.Sys.isbsd +Base.Sys.isfreebsd +Base.Sys.isopenbsd +Base.Sys.isnetbsd +Base.Sys.isdragonfly Base.Sys.iswindows Base.Sys.windows_version Base.@static diff --git a/codex/devdocs/ast.md b/codex/devdocs/ast.md index 699a2b0..a30bdd1 100644 --- a/codex/devdocs/ast.md +++ b/codex/devdocs/ast.md @@ -158,6 +158,9 @@ These symbols appear in the `head` field of `Expr`s in lowered form. Pop the stack of current exceptions back to the state at the associated `enter` when leaving a catch block. `args[1]` contains the token from the associated `enter`. + !!! compat "Julia 1.1" + `pop_exception` is new in Julia 1.1. + * `inbounds` Controls turning bounds checks on or off. A stack is maintained; if the first argument of this diff --git a/codex/devdocs/isbitsunionarrays.md b/codex/devdocs/isbitsunionarrays.md index 9831998..ad5e16c 100644 --- a/codex/devdocs/isbitsunionarrays.md +++ b/codex/devdocs/isbitsunionarrays.md @@ -6,8 +6,8 @@ Julia also supports Union types, quite literally the union of a set of types. Cu ## isbits Union Structs -Julia now includes an optimization wherein "isbits Union" fields in types (`mutable struct`, `struct`, etc.) will be stored inline. This is accomplished by determining the "inline size" of the Union type (e.g. `Union{UInt8, Int16}` will have a size of 16 bytes, which represents the size needed of the largest Union type `Int16`), and in addition, allocating an extra "type tag byte" (`UInt8`), whose value signals the type of the actual value stored inline of the "Union bytes". The type tag byte value is the index of the actual value's type in the Union type's order of types. For example, a type tag value of `0x02` for a field with type `Union{Nothing, UInt8, Int16}` would indicate that an `Int16` value is stored in the 16 bytes of the field in the structure's memory; a `0x01` value would indicate that a `UInt8` value was stored in the first 8 bytes of the 16 bytes of the field's memory. Lastly, a value of `0x00` signals that the `nothing` value will be returned for this field, even though, as a singleton type with a single type instance, it technically has a size of 0. The type tag byte for a type's Union field is stored directly after the field's computed Union memory. +Julia now includes an optimization wherein "isbits Union" fields in types (`mutable struct`, `struct`, etc.) will be stored inline. This is accomplished by determining the "inline size" of the Union type (e.g. `Union{UInt8, Int16}` will have a size of two bytes, which represents the size needed of the largest Union type `Int16`), and in addition, allocating an extra "type tag byte" (`UInt8`), whose value signals the type of the actual value stored inline of the "Union bytes". The type tag byte value is the index of the actual value's type in the Union type's order of types. For example, a type tag value of `0x02` for a field with type `Union{Nothing, UInt8, Int16}` would indicate that an `Int16` value is stored in the 16 bytes of the field in the structure's memory; a `0x01` value would indicate that a `UInt8` value was stored in the first 8 bytes of the 16 bytes of the field's memory. Lastly, a value of `0x00` signals that the `nothing` value will be returned for this field, even though, as a singleton type with a single type instance, it technically has a size of 0. The type tag byte for a type's Union field is stored directly after the field's computed Union memory. ## isbits Union Arrays -Julia can now also store "isbits Union" values inline in an Array, as opposed to requiring an indirection box. The optimization is accomplished by storing an extra "type tag array" of bytes, one byte per array element, alongside the bytes of the actual array data. This type tag array serves the same function as the type field case: it's value signals the type of the actual stored Union value in the array. In terms of layout, a Julia Array can include extra "buffer" space before and after it's actual data values, which are tracked in the `a->offset` and `a->maxsize` fields of the `jl_array_t*` type. The "type tag array" is treated exactly as another `jl_array_t*`, but which shares the same `a->offset`, `a->maxsize`, and `a->len` fields. So the formula to access an isbits Union Array's type tag bytes is `a->data + (a->maxsize - a->offset) * a->elsize + a->offset`; i.e. the Array's `a->data` pointer is already shifted by `a->offset`, so correcting for that, we follow the data all the way to the max of what it can hold `a->maxsize`, then adjust by `a->ofset` more bytes to account for any present "front buffering" the array might be doing. This layout in particular allows for very efficient resizing operations as the type tag data only ever has to move when the actual array's data has to move. \ No newline at end of file +Julia can now also store "isbits Union" values inline in an Array, as opposed to requiring an indirection box. The optimization is accomplished by storing an extra "type tag array" of bytes, one byte per array element, alongside the bytes of the actual array data. This type tag array serves the same function as the type field case: its value signals the type of the actual stored Union value in the array. In terms of layout, a Julia Array can include extra "buffer" space before and after its actual data values, which are tracked in the `a->offset` and `a->maxsize` fields of the `jl_array_t*` type. The "type tag array" is treated exactly as another `jl_array_t*`, but which shares the same `a->offset`, `a->maxsize`, and `a->len` fields. So the formula to access an isbits Union Array's type tag bytes is `a->data + (a->maxsize - a->offset) * a->elsize + a->offset`; i.e. the Array's `a->data` pointer is already shifted by `a->offset`, so correcting for that, we follow the data all the way to the max of what it can hold `a->maxsize`, then adjust by `a->ofset` more bytes to account for any present "front buffering" the array might be doing. This layout in particular allows for very efficient resizing operations as the type tag data only ever has to move when the actual array's data has to move. diff --git a/codex/devdocs/object.md b/codex/devdocs/object.md index 49d1e46..8cba7c8 100644 --- a/codex/devdocs/object.md +++ b/codex/devdocs/object.md @@ -116,7 +116,6 @@ Types: ```c jl_datatype_t *jl_apply_type(jl_datatype_t *tc, jl_tuple_t *params); jl_datatype_t *jl_apply_array_type(jl_datatype_t *type, size_t dim); -jl_uniontype_t *jl_new_uniontype(jl_tuple_t *types); ``` While these are the most commonly used options, there are more low-level constructors too, which diff --git a/codex/devdocs/reflection.md b/codex/devdocs/reflection.md index bcf22fd..3e41b14 100644 --- a/codex/devdocs/reflection.md +++ b/codex/devdocs/reflection.md @@ -94,12 +94,12 @@ particular interest for understanding how language constructs map to primitive o as assignments, branches, and calls: ```jldoctest -julia> Meta.lower(@__MODULE__, :([1+2, sin(0.5)]) ) +julia> Meta.lower(@__MODULE__, :( [1+2, sin(0.5)] )) :($(Expr(:thunk, CodeInfo( - 1 ─ %1 = 1 + 2 - │ %2 = sin(0.5) - │ %3 = (Base.vect)(%1, %2) - └── return %3 +1 ─ %1 = 1 + 2 +│ %2 = sin(0.5) +│ %3 = (Base.vect)(%1, %2) +└── return %3 )))) ``` @@ -122,11 +122,11 @@ calls and expand argument types automatically: ```julia-repl julia> @code_llvm +(1,1) -; Function Attrs: sspreq -define i64 @"julia_+_130862"(i64, i64) #0 { +; @ int.jl:53 within `+' +define i64 @"julia_+_130862"(i64, i64) { top: - %2 = add i64 %1, %0, !dbg !8 - ret i64 %2, !dbg !8 + %2 = add i64 %1, %0 + ret i64 %2 } ``` diff --git a/codex/manual/calling-c-and-fortran-code.md b/codex/manual/calling-c-and-fortran-code.md index 54ae0f1..a73f746 100644 --- a/codex/manual/calling-c-and-fortran-code.md +++ b/codex/manual/calling-c-and-fortran-code.md @@ -44,6 +44,11 @@ to [`ccall`](@ref) are as follows: OR + a `:function` name symbol or `"function"` name string, which is resolved in the + current process, + + OR + a function pointer (for example, from `dlsym`). 2. Return type (see below for mapping the declared C type to Julia) diff --git a/codex/manual/handling-operating-system-variation.md b/codex/manual/handling-operating-system-variation.md index 155d303..026d7df 100644 --- a/codex/manual/handling-operating-system-variation.md +++ b/codex/manual/handling-operating-system-variation.md @@ -2,8 +2,9 @@ When writing cross-platform applications or libraries, it is often necessary to allow for differences between operating systems. The variable `Sys.KERNEL` can be used to handle such -cases. There are several functions in the `Sys` module intended to make this easier: -`isunix`, `islinux`, `isapple`, `isbsd`, and `iswindows`. These may be used as follows: +cases. There are several functions in the `Sys` module intended to make this easier, such as +`isunix`, `islinux`, `isapple`, `isbsd`, `isfreebsd`, and `iswindows`. These may be used +as follows: ```julia if Sys.iswindows() @@ -11,9 +12,9 @@ if Sys.iswindows() end ``` -Note that `islinux` and `isapple` are mutually exclusive subsets of `isunix`. Additionally, -there is a macro `@static` which makes it possible to use these functions to conditionally hide -invalid code, as demonstrated in the following examples. +Note that `islinux`, `isapple`, and `isfreebsd` are mutually exclusive subsets of `isunix`. +Additionally, there is a macro `@static` which makes it possible to use these functions to +conditionally hide invalid code, as demonstrated in the following examples. Simple blocks: diff --git a/codex/manual/stacktraces.md b/codex/manual/stacktraces.md index a7da7a6..01a3417 100644 --- a/codex/manual/stacktraces.md +++ b/codex/manual/stacktraces.md @@ -189,6 +189,9 @@ ERROR: Whoops! ## Exception stacks and [`catch_stack`](@ref) +!!! compat "Julia 1.1" + Exception stacks requires at least Julia 1.1. + While handling an exception further exceptions may be thrown. It can be useful to inspect all these exceptions to identify the root cause of a problem. The julia runtime supports this by pushing each exception onto an internal *exception stack* as it occurs. When the code exits a `catch` normally, any exceptions which were pushed onto the stack diff --git a/codex/manual/strings.md b/codex/manual/strings.md index 87a9ed5..1fd2a5b 100644 --- a/codex/manual/strings.md +++ b/codex/manual/strings.md @@ -854,7 +854,7 @@ julia> m[2] Captures can be referenced in a substitution string when using [`replace`](@ref) by using `\n` to refer to the nth capture group and prefixing the substitution string with `s`. Capture group 0 refers to the entire match object. Named capture groups can be referenced in the substitution -with `g`. For example: +with `\g`. For example: ```jldoctest julia> replace("first second", r"(\w+) (?\w+)" => s"\g \1") diff --git a/codex/stdlib/LinearAlgebra.md b/codex/stdlib/LinearAlgebra.md index e941069..0b245a5 100644 --- a/codex/stdlib/LinearAlgebra.md +++ b/codex/stdlib/LinearAlgebra.md @@ -371,6 +371,8 @@ LinearAlgebra.pinv LinearAlgebra.nullspace Base.kron LinearAlgebra.exp(::StridedMatrix{<:LinearAlgebra.BlasFloat}) +Base.:^(::AbstractMatrix, ::Number) +Base.:^(::Number, ::AbstractMatrix) LinearAlgebra.log(::StridedMatrix) LinearAlgebra.sqrt(::StridedMatrix{<:Real}) LinearAlgebra.cos(::StridedMatrix{<:Real}) diff --git a/codex/stdlib/Pkg.md b/codex/stdlib/Pkg.md index 56357bf..e5c14ac 100644 --- a/codex/stdlib/Pkg.md +++ b/codex/stdlib/Pkg.md @@ -1,865 +1,17 @@ # Pkg -## Introduction - -Pkg is the standard package manager for Julia 1.0 and newer. Unlike traditional -package managers, which install and manage a single global set of packages, Pkg -is designed around “environments”: independent sets of packages that can be -local to an individual project or shared and selected by name. The exact set of -packages and versions in an environment is captured in a _manifest file_ which -can be checked into a project repository and tracked in version control, -significantly improving reproducibility of projects. If you’ve ever tried to run -code you haven’t used in a while only to find that you can’t get anything to -work because you’ve updated or uninstalled some of the packages your project was -using, you’ll understand the motivation for this approach. In Pkg, since each -project maintains its own independent set of package versions, you’ll never have -this problem again. Moreover, if you check out a project on a new system, you -can simply materialize the environment described by its manifest file and -immediately be up and running with a known-good set of dependencies. - -Since environments are managed and updated independently from each other, -“dependency hell” is significantly alleviated in Pkg. If you want to use the -latest and greatest version of some package in a new project but you’re stuck on -an older version in a different project, that’s no problem – since they have -separate environments they can just use different versions, which are both -installed at the same time in different locations on your system. The location -of each package version is canonical, so when environments use the same versions -of packages, they can share installations, avoiding unnecessary duplication of -the package. Old package versions that are no longer used by any environments -are periodically “garbage collected” by the package manager. - -Pkg’s approach to local environments may be familiar to people who have used -Python’s `virtualenv` or Ruby’s `bundler`. In Julia, instead of hacking the -language’s code loading mechanisms to support environments, we have the benefit -that Julia natively understands them. In addition, Julia environments are -“stackable”: you can overlay one environment with another and thereby have -access to additional packages outside of the primary environment. This makes it -easy to work on a project, which provides the primary environment, while still -having access to all your usual dev tools like profilers, debuggers, and so on, -just by having an environment including these dev tools later in the load path. - -Last but not least, Pkg is designed to support federated package registries. -This means that it allows multiple registries managed by different parties to -interact seamlessly. In particular, this includes private registries which can -live behind corporate firewalls. You can install and update your own packages -from a private registry with exactly the same tools and workflows that you use -to install and manage official Julia packages. If you urgently need to apply a -hotfix for a public package that’s critical to your company’s product, you can -tag a private version of it in your company’s internal registry and get a fix to -your developers and ops teams quickly and easily without having to wait for an -upstream patch to be accepted and published. Once an official fix is published, -however, you can just upgrade your dependencies and you'll be back on an -official release again. - -## Glossary - -**Project:** a source tree with a standard layout, including a `src` directory -for the main body of Julia code, a `test` directory for testing the project, -`docs` for documentation files, and optionally a `deps` directory for a build -script and its outputs. A project will typically also have a project file and -may optionally have a manifest file: - -- **Project file:** a file in the root directory of a project, named - `Project.toml` (or `JuliaProject.toml`) describing metadata about the project, - including its name, UUID (for packages), authors, license, and the names and - UUIDs of packages and libraries that it depends on. - -- **Manifest file:** a file in the root directory of a project, named - `Manifest.toml` (or `JuliaManifest.toml`) describing a complete dependency graph - and exact versions of each package and library used by a project. - -**Package:** a project which provides reusable functionality that can be used by -other Julia projects via `import X` or `using X`. A package should have a -project file with a `uuid` entry giving its package UUID. This UUID is used to -identify the package in projects that depend on it. +Pkg is Julia's builtin package manager, and handles operations +such as installing, updating and removing packages. !!! note - For legacy reasons it is possible to load a package without a project file or - UUID from the REPL or the top-level of a script. It is not possible, however, - to load a package without a project file or UUID from a project with them. Once - you've loaded from a project file, everything needs a project file and UUID. - -**Application:** a project which provides standalone functionality not intended -to be reused by other Julia projects. For example a web application or a -commmand-line utility, or simulation/analytics code accompanying a scientific paper. -An application may have a UUID but does not need one. -An application may also provide global configuration options for packages it -depends on. Packages, on the other hand, may not provide global configuration -since that could conflict with the configuration of the main application. - -!!! note - **Projects _vs._ Packages _vs._ Applications:** - - 1. **Project** is an umbrella term: packages and applications are kinds of projects. - 2. **Packages** should have UUIDs, applications can have a UUIDs but don't need them. - 3. **Applications** can provide global configuration, whereas packages cannot. - -**Library (future work):** a compiled binary dependency (not written in Julia) -packaged to be used by a Julia project. These are currently typically built in- -place by a `deps/build.jl` script in a project’s source tree, but in the future -we plan to make libraries first-class entities directly installed and upgraded -by the package manager. - -**Environment:** the combination of the top-level name map provided by a project -file combined with the dependency graph and map from packages to their entry points -provided by a manifest file. For more detail see the manual section on code loading. - -- **Explicit environment:** an environment in the form of an explicit project - file and an optional corresponding manifest file together in a directory. If the - manifest file is absent then the implied dependency graph and location maps are - empty. - -- **Implicit environment:** an environment provided as a directory (without a - project file or manifest file) containing packages with entry points of the form - `X.jl`, `X.jl/src/X.jl` or `X/src/X.jl`. The top-level name map is implied by - these entry points. The dependency graph is implied by the existence of project - files inside of these package directories, e.g. `X.jl/Project.toml` or - `X/Project.toml`. The dependencies of the `X` package are the dependencies in - the corresponding project file if there is one. The location map is implied by - the entry points themselves. - -**Registry:** a source tree with a standard layout recording metadata about a -registered set of packages, the tagged versions of them which are available, and -which versions of packages are compatible or incompatible with each other. A -registry is indexed by package name and UUID, and has a directory for each -registered package providing the following metadata about it: - -- name – e.g. `DataFrames` -- UUID – e.g. `a93c6f00-e57d-5684-b7b6-d8193f3e46c0` -- authors – e.g. `Jane Q. Developer ` -- license – e.g. MIT, BSD3, or GPLv2 -- repository – e.g. `https://github.com/JuliaData/DataFrames.jl.git` -- description – a block of text summarizing the functionality of a package -- keywords – e.g. `data`, `tabular`, `analysis`, `statistics` -- versions – a list of all registered version tags - -For each registered version of a package, the following information is provided: - -- its semantic version number – e.g. `v1.2.3` -- its git tree SHA-1 hash – e.g. `7ffb18ea3245ef98e368b02b81e8a86543a11103` -- a map from names to UUIDs of dependencies -- which versions of other packages it is compatible/incompatible with - -Dependencies and compatibility are stored in a compressed but human-readable -format using ranges of package versions. - -**Depot:** a directory on a system where various package-related resources live, -including: - -- `environments`: shared named environments (e.g. `v1.0`, `devtools`) -- `clones`: bare clones of package repositories -- `compiled`: cached compiled package images (`.ji` files) -- `config`: global configuration files (e.g. `startup.jl`) -- `dev`: default directory for package development -- `logs`: log files (e.g. `manifest_usage.toml`, `repl_history.jl`) -- `packages`: installed package versions -- `registries`: clones of registries (e.g. `General`) - -**Load path:** a stack of environments where package identities, their -dependencies, and entry-points are searched for. The load path is controlled in -Julia by the `LOAD_PATH` global variable which is populated at startup based on -the value of the `JULIA_LOAD_PATH` environment variable. The first entry is your -primary environment, often the current project, while later entries provide -additional packages one may want to use from the REPL or top-level scripts. - -**Depot path:** a stack of depot locations where the package manager, as well as -Julia's code loading mechanisms, look for registries, installed packages, named -environments, repo clones, cached compiled package images, and configuration -files. The depot path is controlled by the Julia `DEPOT_PATH` global variable -which is populated at startup based on the value of the `JULIA_DEPOT_PATH` -environment variable. The first entry is the “user depot” and should be writable -by and owned by the current user. The user depot is where: registries are -cloned, new package versions are installed, named environments are created and -updated, package repos are cloned, newly compiled package image files are saved, -log files are written, development packages are checked out by default, and -global configuration data is saved. Later entries in the depot path are treated -as read-only and are appropriate for registries, packages, etc. installed and -managed by system administrators. - -## Getting Started - -The Pkg REPL-mode is entered from the Julia REPL using the key `]`. - -``` -(v1.0) pkg> -``` - -The part inside the parenthesis of the prompt shows the name of the current project. -Since we haven't created our own project yet, we are in the default project, located at `~/.julia/environments/v1.0` -(or whatever version of Julia you happen to run). - -To return to the `julia>` prompt, either press backspace when the input line is empty or press Ctrl+C. -Help is available by calling `pkg> help`. -If you are in an environment that does not have access to a REPL you can still use the REPL mode commands using -the string macro `pkg` available after `using Pkg`. The command `pkg"cmd"` would be equivalent to executing `cmd` -in the REPL mode. - -The documentation here describes using Pkg from the REPL mode. Documentation of using -the Pkg API (by calling `Pkg.` functions) is in progress of being written. - -### Adding packages - -There are two ways of adding packages, either using the `add` command or the `dev` command. -The most frequently used one is `add` and its usage is described first. - -#### Adding registered packages - -In the Pkg REPL packages can be added with the `add` command followed by the name of the package, for example: - -``` -(v1.0) pkg> add Example - Cloning default registries into /Users/kristoffer/.julia/registries - Cloning registry General from "https://github.com/JuliaRegistries/General.git" - Updating registry at `~/.julia/registries/General` - Updating git-repo `https://github.com/JuliaRegistries/General.git` - Resolving package versions... - Updating `~/.julia/environments/v1.0/Project.toml` - [7876af07] + Example v0.5.1 - Updating `~/.julia/environments/v1.0/Manifest.toml` - [7876af07] + Example v0.5.1 - [8dfed614] + Test -``` - -Here we added the package Example to the current project. In this example, we are using a fresh Julia installation, -and this is our first time adding a package using Pkg. By default, Pkg clones Julia's General registry, -and uses this registry to look up packages requested for inclusion in the current environment. -The status update shows a short form of the package UUID to the left, then the package name, and the version. -Since standard libraries (e.g. `Test`) are shipped with Julia, they do not have a version. The project status contains the packages -you have added yourself, in this case, `Example`: - -``` -(v1.0) pkg> st - Status `Project.toml` - [7876af07] Example v0.5.1 -``` - -The manifest status, in addition, includes the dependencies of explicitly added packages. - -``` -(v1.0) pkg> st --manifest - Status `Manifest.toml` - [7876af07] Example v0.5.1 - [8dfed614] Test -``` - -It is possible to add multiple packages in one command as `pkg> add A B C`. - -After a package is added to the project, it can be loaded in Julia: - -``` -julia> using Example - -julia> Example.hello("User") -"Hello, User" -``` - -A specific version can be installed by appending a version after a `@` symbol, e.g. `@v0.4`, to the package name: - -``` -(v1.0) pkg> add Example@0.4 - Resolving package versions... - Updating `~/.julia/environments/v1.0/Project.toml` - [7876af07] + Example v0.4.1 - Updating `~/.julia/environments/v1.0/Manifest.toml` - [7876af07] + Example v0.4.1 -``` - -If the master branch (or a certain commit SHA) of `Example` has a hotfix that has not yet included in a registered version, -we can explicitly track a branch (or commit) by appending `#branch` (or `#commit`) to the package name: - -``` -(v1.0) pkg> add Example#master - Updating git-repo `https://github.com/JuliaLang/Example.jl.git` - Resolving package versions... - Updating `~/.julia/environments/v1.0/Project.toml` - [7876af07] ~ Example v0.5.1 ⇒ v0.5.1+ #master (https://github.com/JuliaLang/Example.jl.git) - Updating `~/.julia/environments/v1.0/Manifest.toml` - [7876af07] ~ Example v0.5.1 ⇒ v0.5.1+ #master (https://github.com/JuliaLang/Example.jl.git) -``` - -The status output now shows that we are tracking the `master` branch of `Example`. -When updating packages, we will pull updates from that branch. - -To go back to tracking the registry version of `Example`, the command `free` is used: - -``` -(v1.0) pkg> free Example - Resolving package versions... - Updating `~/.julia/environments/v1.0/Project.toml` - [7876af07] ~ Example v0.5.1+ #master (https://github.com/JuliaLang/Example.jl.git) ⇒ v0.5.1 - Updating `~/.julia/environments/v1.0/Manifest.toml` - [7876af07] ~ Example v0.5.1+ #master )https://github.com/JuliaLang/Example.jl.git) ⇒ v0.5.1 -``` - - -#### Adding unregistered packages - -If a package is not in a registry, it can still be added by instead of the package name giving the URL to the repository to `add`. - -``` -(v1.0) pkg> add https://github.com/fredrikekre/ImportMacros.jl - Updating git-repo `https://github.com/fredrikekre/ImportMacros.jl` - Resolving package versions... -Downloaded MacroTools ─ v0.4.1 - Updating `~/.julia/environments/v1.0/Project.toml` - [e6797606] + ImportMacros v0.0.0 # (https://github.com/fredrikekre/ImportMacros.jl) - Updating `~/.julia/environments/v1.0/Manifest.toml` - [e6797606] + ImportMacros v0.0.0 # (https://github.com/fredrikekre/ImportMacros.jl) - [1914dd2f] + MacroTools v0.4.1 -``` - -The dependencies of the unregistered package (here `MacroTools`) got installed. -For unregistered packages we could have given a branch (or commit SHA) to track using `#`, just like for registered packages. - - -#### Adding a local package - -Instead of giving a URL of a git repo to `add` we could instead have given a local path to a git repo. -This works similarly to adding a URL. The local repository will be tracked (at some branch) and updates -from that local repo are pulled when packages are updated. -Note that changes to files in the local package repository will not immediately be reflected when loading that package. -The changes would have to be committed and the packages updated in order to pull in the changes. - -#### Developing packages - -By only using `add` your Manifest will always have a "reproducible state", in other words, as long as the repositories and registries used are still accessible -it is possible to retrieve the exact state of all the dependencies in the project. This has the advantage that you can send your project (`Project.toml` -and `Manifest.toml`) to someone else and they can "instantiate" that project in the same state as you had it locally. -However, when you are developing a package, it is more convenient to load packages at their current state at some path. For this reason, the `dev` command exists. - -Let's try to `dev` a registered package: - -``` -(v1.0) pkg> dev Example - Updating git-repo `https://github.com/JuliaLang/Example.jl.git` - Resolving package versions... - Updating `~/.julia/environments/v1.0/Project.toml` - [7876af07] + Example v0.5.1+ [`~/.julia/dev/Example`] - Updating `~/.julia/environments/v1.0/Manifest.toml` - [7876af07] + Example v0.5.1+ [`~/.julia/dev/Example`] -``` - -The `dev` command fetches a full clone of the package to `~/.julia/dev/` (the path can be changed by setting the environment variable `JULIA_PKG_DEVDIR`). -When importing `Example` julia will now import it from `~/.julia/dev/Example` and whatever local changes have been made to the files in that path are consequently -reflected in the code loaded. When we used `add` we said that we tracked the package repository, we here say that we track the path itself. -Note that the package manager will never touch any of the files at a tracked path. It is therefore up to you to pull updates, change branches etc. -If we try to `dev` a package at some branch that already exists at `~/.julia/dev/` the package manager we will simply use the existing path. -For example: - -``` -(v1.0) pkg> dev Example - Updating git-repo `https://github.com/JuliaLang/Example.jl.git` -[ Info: Path `/Users/kristoffer/.julia/dev/Example` exists and looks like the correct package, using existing path instead of cloning -``` - -Note the info message saying that it is using the existing path. As a general rule, the package manager will -never touch files that are tracking a path. - -If `dev` is used on a local path, that path to that package is recorded and used when loading that package. -The path will be recorded relative to the project file, unless it is given as an absolute path. - -To stop tracking a path and use the registered version again, use `free` - -``` -(v1.0) pkg> free Example - Resolving package versions... - Updating `~/.julia/environments/v1.0/Project.toml` - [7876af07] ↓ Example v0.5.1+ [`~/.julia/dev/Example`] ⇒ v0.5.1 - Updating `~/.julia/environments/v1.0/Manifest.toml` - [7876af07] ↓ Example v0.5.1+ [`~/.julia/dev/Example`] ⇒ v0.5.1 -``` - -It should be pointed out that by using `dev` your project is now inherently stateful. -Its state depends on the current content of the files at the path and the manifest cannot be "instantiated" by someone else without -knowing the exact content of all the packages that are tracking a path. - -Note that if you add a dependency to a package that tracks a local path, the Manifest (which contains the whole dependency graph) will become -out of sync with the actual dependency graph. This means that the package will not be able to load that dependency since it is not recorded -in the Manifest. To update sync the Manifest, use the REPL command `resolve`. - -### Removing packages - -Packages can be removed from the current project by using `pkg> rm Package`. -This will only remove packages that exist in the project, to remove a package that only -exists as a dependency use `pkg> rm --manifest DepPackage`. -Note that this will remove all packages that depends on `DepPackage`. - -### Updating packages - -When new versions of packages the project is using are released, it is a good idea to update. Simply calling `up` will try to update *all* the dependencies of the project -to the latest compatible version. Sometimes this is not what you want. You can specify a subset of the dependencies to upgrade by giving them as arguments to `up`, e.g: - -``` -(v1.0) pkg> up Example -``` - -The version of all other packages direct dependencies will stay the same. If you only want to update the minor version of packages, to reduce the risk that your project breaks, you can give the `--minor` flag, e.g: - -``` -(v1.0) pkg> up --minor Example -``` - -Packages that track a repository are not updated when a minor upgrade is done. -Packages that track a path are never touched by the package manager. - -### Pinning a package - -A pinned package will never be updated. A package can be pinned using `pin` as for example - -``` -(v1.0) pkg> pin Example - Resolving package versions... - Updating `~/.julia/environments/v1.0/Project.toml` - [7876af07] ~ Example v0.5.1 ⇒ v0.5.1 ⚲ - Updating `~/.julia/environments/v1.0/Manifest.toml` - [7876af07] ~ Example v0.5.1 ⇒ v0.5.1 ⚲ -``` - -Note the pin symbol `⚲` showing that the package is pinned. Removing the pin is done using `free` - -``` -(v1.0) pkg> free Example - Updating `~/.julia/environments/v1.0/Project.toml` - [7876af07] ~ Example v0.5.1 ⚲ ⇒ v0.5.1 - Updating `~/.julia/environments/v1.0/Manifest.toml` - [7876af07] ~ Example v0.5.1 ⚲ ⇒ v0.5.1 -``` - -### Testing packages - -The tests for a package can be run using `test`command: - -``` -(v1.0) pkg> test Example - Testing Example - Testing Example tests passed -``` - -### Building packages - -The build step of a package is automatically run when a package is first installed. -The output of the build process is directed to a file. -To explicitly run the build step for a package the `build` command is used: - -``` -(v1.0) pkg> build MbedTLS - Building MbedTLS → `~/.julia/packages/MbedTLS/h1Vu/deps/build.log` - -shell> cat ~/.julia/packages/MbedTLS/h1Vu/deps/build.log -┌ Warning: `wait(t::Task)` is deprecated, use `fetch(t)` instead. -│ caller = macro expansion at OutputCollector.jl:63 [inlined] -└ @ Core OutputCollector.jl:63 -... -[ Info: using prebuilt binaries -``` - -## Creating your own projects - -So far we have added packages to the default project at `~/.julia/environments/v1.0`, it is, however, easy to create other, independent, projects. -It should be pointed out if two projects uses the same package at the same version, the content of this package is not duplicated. -In order to create a new project, create a directory for it and then activate that directory to make it the "active project" which package operations manipulate: - -``` -shell> mkdir MyProject - -shell> cd MyProject -/Users/kristoffer/MyProject - -(v1.0) pkg> activate . - -(MyProject) pkg> st - Status `Project.toml` -``` - -Note that the REPL prompt changed when the new project is activated. Since this is a newly created project, the status command show it contains no packages, and in fact, it has no project or manifest file until we add a package to it: - -``` -shell> ls -l -total 0 - -(MyProject) pkg> add Example - Updating registry at `~/.julia/registries/General` - Updating git-repo `https://github.com/JuliaRegistries/General.git` - Resolving package versions... - Updating `Project.toml` - [7876af07] + Example v0.5.1 - Updating `Manifest.toml` - [7876af07] + Example v0.5.1 - [8dfed614] + Test - -shell> ls -l -total 8 --rw-r--r-- 1 stefan staff 207 Jul 3 16:35 Manifest.toml --rw-r--r-- 1 stefan staff 56 Jul 3 16:35 Project.toml - -shell> cat Project.toml -[deps] -Example = "7876af07-990d-54b4-ab0e-23690620f79a" - -shell> cat Manifest.toml -[[Example]] -deps = ["Test"] -git-tree-sha1 = "8eb7b4d4ca487caade9ba3e85932e28ce6d6e1f8" -uuid = "7876af07-990d-54b4-ab0e-23690620f79a" -version = "0.5.1" - -[[Test]] -uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" -``` - -This new environment is completely separate from the one we used earlier. - -## Garbage collecting old, unused packages - -As packages are updated and projects are deleted, installed packages that were once used will inevitably -become old and not used from any existing project. -Pkg keeps a log of all projects used so it can go through the log and see exactly which projects still exist -and what packages those projects used. The rest can be deleted. -This is done with the `gc` command: - -``` -(v1.0) pkg> gc - Active manifests at: - `/Users/kristoffer/BinaryProvider/Manifest.toml` - ... - `/Users/kristoffer/Compat.jl/Manifest.toml` - Deleted /Users/kristoffer/.julia/packages/BenchmarkTools/1cAj: 146.302 KiB - Deleted /Users/kristoffer/.julia/packages/Cassette/BXVB: 795.557 KiB - ... - Deleted /Users/kristoffer/.julia/packages/WeakRefStrings/YrK6: 27.328 KiB - Deleted 36 package installations: 113.205 MiB -``` - -Note that only packages in `~/.julia/packages` are deleted. - -## Creating your own packages - -A package is a project with a `name`, `uuid` and `version` entry in the `Project.toml` file `src/PackageName.jl` file that defines the module `PackageName`. -This file is executed when the package is loaded. - -### Generating files for a package - -To generate files for a new package, use `pkg> generate`. - -``` -(v1.0) pkg> generate HelloWorld -``` - -This creates a new project `HelloWorld` with the following files (visualized with the external [`tree` command](https://linux.die.net/man/1/tree)): - -```jl -shell> cd HelloWorld - -shell> tree . -. -├── Project.toml -└── src - └── HelloWorld.jl - -1 directory, 2 files -``` - -The `Project.toml` file contains the name of the package, its unique UUID, its version, the author and eventual dependencies: - -```toml -name = "HelloWorld" -uuid = "b4cd1eb8-1e24-11e8-3319-93036a3eb9f3" -version = "0.1.0" -author = ["Some One "] - -[deps] -``` - -The content of `src/HelloWorld.jl` is: - -```jl -module HelloWorld - -greet() = print("Hello World!") - -end # module -``` - -We can now activate the project and load the package: - -```jl -pkg> activate . - -julia> import HelloWorld - -julia> HelloWorld.greet() -Hello World! -``` - -### Adding dependencies to the project - -Let’s say we want to use the standard library package `Random` and the registered package `JSON` in our project. -We simply `add` these packages (note how the prompt now shows the name of the newly generated project, -since we are inside the `HelloWorld` project directory): - -``` -(HelloWorld) pkg> add Random JSON - Resolving package versions... - Updating "~/Documents/HelloWorld/Project.toml" - [682c06a0] + JSON v0.17.1 - [9a3f8284] + Random - Updating "~/Documents/HelloWorld/Manifest.toml" - [34da2185] + Compat v0.57.0 - [682c06a0] + JSON v0.17.1 - [4d1e1d77] + Nullables v0.0.4 - ... -``` - -Both `Random` and `JSON` got added to the project’s `Project.toml` file, and the resulting dependencies got added to the `Manifest.toml` file. -The resolver has installed each package with the highest possible version, while still respecting the compatibility that each package enforce on its dependencies. - -We can now use both `Random` and `JSON` in our project. Changing `src/HelloWorld.jl` to - -``` -module HelloWorld - -import Random -import JSON - -greet() = print("Hello World!") -greet_alien() = print("Hello ", Random.randstring(8)) - -end # module -``` - -and reloading the package, the new `greet_alien` function that uses `Random` can be used: - -``` -julia> HelloWorld.greet_alien() -Hello aT157rHV -``` - -### Adding a build step to the package. - -The build step is executed the first time a package is installed or when explicitly invoked with `build`. -A package is built by executing the file `deps/build.jl`. - -``` -shell> cat deps/build.log -I am being built... - -(HelloWorld) pkg> build - Building HelloWorld → `deps/build.log` - Resolving package versions... - -shell> cat deps/build.log -I am being built... -``` - -If the build step fails, the output of the build step is printed to the console - -``` -shell> cat deps/build.jl -error("Ooops") - -(HelloWorld) pkg> build - Building HelloWorld → `deps/build.log` - Resolving package versions... -┌ Error: Error building `HelloWorld`: -│ ERROR: LoadError: Ooops -│ Stacktrace: -│ [1] error(::String) at ./error.jl:33 -│ [2] top-level scope at none:0 -│ [3] include at ./boot.jl:317 [inlined] -│ [4] include_relative(::Module, ::String) at ./loading.jl:1071 -│ [5] include(::Module, ::String) at ./sysimg.jl:29 -│ [6] include(::String) at ./client.jl:393 -│ [7] top-level scope at none:0 -│ in expression starting at /Users/kristoffer/.julia/dev/Pkg/HelloWorld/deps/build.jl:1 -└ @ Pkg.Operations Operations.jl:938 -``` - -### Adding tests to the package - -When a package is tested the file `test/runtests.jl` is executed. - -``` -shell> cat test/runtests.jl -println("Testing...") -(HelloWorld) pkg> test - Testing HelloWorld - Resolving package versions... -Testing... - Testing HelloWorld tests passed -``` - -#### Test-specific dependencies - -Sometimes one might want to use some packages only at testing time but not -enforce a dependency on them when the package is used. This is possible by -adding dependencies to `[extras]` and a `test` target in `[targets]` to the Project file. -Here we add the `Test` standard library as a test-only dependency by adding the -following to the Project file: - -``` -[extras] -Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[targets] -test = ["Test"] -``` - -We can now use `Test` in the test script and we can see that it gets installed on testing: - -``` -shell> cat test/runtests.jl -using Test -@test 1 == 1 - -(HelloWorld) pkg> test - Testing HelloWorld - Resolving package versions... - Updating `/var/folders/64/76tk_g152sg6c6t0b4nkn1vw0000gn/T/tmpPzUPPw/Project.toml` - [d8327f2a] + HelloWorld v0.1.0 [`~/.julia/dev/Pkg/HelloWorld`] - [8dfed614] + Test - Updating `/var/folders/64/76tk_g152sg6c6t0b4nkn1vw0000gn/T/tmpPzUPPw/Manifest.toml` - [d8327f2a] + HelloWorld v0.1.0 [`~/.julia/dev/Pkg/HelloWorld`] - Testing HelloWorld tests passed``` -``` - -### Compatibility - -Compatibility refers to the ability to restrict what version of the dependencies that your project is compatible with. -If the compatibility for a dependency is not given, the project is assumed to be compatible with all versions of that dependency. - -Compatibility for a dependency is entered in the `Project.toml` file as for example: - -```toml -[compat] -julia = "1.0" -Example = "0.4.3" -``` - -After a compatibility entry is put into the project file, `up` can be used to apply it. - -The format of the version specifier is described in detail below. - -!!! info - There is currently no way to give compatibility from the Pkg REPL mode so for now, one has to manually edit the project file. - -#### Version specifier format - -Similar to other package managers, the Julia package manager respects [semantic versioning](https://semver.org/) (semver). -As an example, a version specifier is given as e.g. `1.2.3` is therefore assumed to be compatible with the versions `[1.2.3 - 2.0.0)` where `)` is a non-inclusive upper bound. -More specifically, a version specifier is either given as a **caret specifier**, e.g. `^1.2.3` or a **tilde specifier** `~1.2.3`. -Caret specifiers are the default and hence `1.2.3 == ^1.2.3`. The difference between a caret and tilde is described in the next section. -The union of multiple version specifiers can be formed by comma separating indiviual version specifiers. - -##### Caret specifiers - -A caret specifier allows upgrade that would be compatible according to semver. -An updated dependency is considered compatible if the new version does not modify the left-most non zero digit in the version specifier. - -Some examples are shown below. - -``` -^1.2.3 = [1.2.3, 2.0.0) -^1.2 = [1.2.0, 2.0.0) -^1 = [1.0.0, 2.0.0) -^0.2.3 = [0.2.3, 0.3.0) -^0.0.3 = [0.0.3, 0.0.4) -^0.0 = [0.0.0, 0.1.0) -^0 = [0.0.0, 1.0.0) -``` - -While the semver specification says that all versions with a major version of 0 are incompatible with each other, we have made that choice that -a version given as `0.a.b` is considered compatible with `0.a.c` if `a != 0` and `c >= b`. - -##### Tilde specifiers - -A tilde specifier provides more limited upgrade possibilities. When specifying major, minor -and patch version, or when specifying major and minor version, only patch version is -allowed to change. If you only specify a major version, then both minor and patch versions -are allowed to be upgraded (`~1` is thus equivalent to `^1`). -This gives the following example. - -``` -~1.2.3 = [1.2.3, 1.3.0) -~1.2 = [1.2.0, 1.3.0) -~1 = [1.0.0, 2.0.0) -``` - -#### Inequality specifiers - -Inequalities can also be used to specify version ranges: - -``` ->= 1.2.3 = [1.2.3, ∞) -≥ 1.2.3 = [1.2.3, ∞) -= 1.2.3 = [1.2.3, 1.2.3] -< 1.2.3 = [0.0.0, 1.2.2] -``` - - -## Precompiling a project - -The REPL command `precompile` can be used to precompile all the dependencies in the project. You can for example do - -``` -(HelloWorld) pkg> update; precompile -``` - -to update the dependencies and then precompile them. - -## Preview mode - -If you just want to see the effects of running a command, but not change your state you can `preview` a command. -For example: - -``` -(HelloWorld) pkg> preview add Plots -``` - -or - -``` -(HelloWorld) pkg> preview up -``` - -will show you the effects of adding `Plots`, or doing a full upgrade, respectively, would have on your project. -However, nothing would be installed and your `Project.toml` and `Manifest.toml` are untouched. - -## Using someone else's project - -Simply clone their project using e.g. `git clone`, `cd` to the project directory and call - -``` -(v1.0) pkg> activate . - -(SomeProject) pkg> instantiate -``` - -If the project contains a manifest, this will install the packages in the same state that is given by that manifest. -Otherwise, it will resolve the latest versions of the dependencies compatible with the project. - -## References - -This section describes the "API mode" of interacting with Pkg.jl which is recommended for non-interactive usage, -in i.e. scripts. In the REPL mode packages (with associated version, UUID, URL etc) are parsed from strings, -for example, `"Package#master"`,`"Package@v0.1"`, `"www.mypkg.com/MyPkg#my/feature"`. -It is possible to use strings as arguments for simple commands in the API mode (like `Pkg.add(["PackageA", "PackageB"])`, -more complicated commands, that e.g. specify URLs or version range, uses a more structured format over strings. -This is done by creating an instance of a [`PackageSpec`](@ref) which are passed in to functions. - -```@docs -PackageSpec -PackageMode -UpgradeLevel -Pkg.add -Pkg.develop -Pkg.activate -Pkg.rm -Pkg.update -Pkg.test -Pkg.build -Pkg.pin -Pkg.free -Pkg.instantiate -Pkg.resolve -Pkg.setprotocol! + What follows is a very brief introduction to Pkg. It is highly + recommended to read the full manual, which is available here: + [https://julialang.github.io/Pkg.jl/v1/](https://julialang.github.io/Pkg.jl/v1/). + +```@eval +import Markdown +file = joinpath(Sys.STDLIB, "Pkg", "docs", "src", "getting-started.md") +str = read(file, String) +str = replace(str, r"^#.*$"m => "") +Markdown.parse(str) ``` diff --git a/make.jl b/make.jl index fd43efa..893628d 100644 --- a/make.jl +++ b/make.jl @@ -39,7 +39,7 @@ const t_Manual = "매뉴얼" const PAGES = [ t_Home => "index.md", - # hide("NEWS.md"), + hide("NEWS.md"), t_Manual => [ "manual/getting-started.md", "manual/variables.md", diff --git a/src/NEWS.md b/src/NEWS.md new file mode 100644 index 0000000..e69cd41 --- /dev/null +++ b/src/NEWS.md @@ -0,0 +1,130 @@ +Julia v1.1 Release Notes +========================== + +New language features +--------------------- + + * An *exception stack* is maintained on each task to make exception handling more robust and enable root cause analysis using `catch_stack` ([#28878](https://github.com/JuliaLang/julia/issues/28878)). + * The experimental macro `Base.@locals` returns a dictionary of current local variable names + and values ([#29733](https://github.com/JuliaLang/julia/issues/29733)). + +Language changes +---------------- + + * Parser inputs ending with a comma are now consistently treated as incomplete. + Previously they were sometimes parsed as tuples, depending on whitespace ([#28506](https://github.com/JuliaLang/julia/issues/28506)). + * Spaces were accidentally allowed in broadcast call syntax, e.g. `f. (x)`. They are now + disallowed, consistent with normal function call syntax ([#29781](https://github.com/JuliaLang/julia/issues/29781)). + * Big integer literals and command syntax (backticks) are now parsed with the name of + the macro (`@int128_str`, `@uint128_str`, `@big_str`, `@cmd`) qualified to refer + to the `Core` module ([#29968](https://github.com/JuliaLang/julia/issues/29968)). + * Using the same name for both a local variable and a static parameter is now an error instead + of a warning ([#29429](https://github.com/JuliaLang/julia/issues/29429)). + * Method signatures such as + `f(::Type{T}, ::T) where {T <: X}` and + `f(::Type{X}, ::Any)` + are now considered ambiguous. Previously a bug caused the first one to be considered more specific ([#30160](https://github.com/JuliaLang/julia/issues/30160)). + +Command-line option changes +--------------------------- + + * When a script run in interactive mode (`-i`) throws an error, the REPL now starts after + the error is displayed. Previously the REPL only started if the script completed without + error ([#21233](https://github.com/JuliaLang/julia/issues/21233)). + +New library functions +--------------------- + + * `splitpath(p::String)` function, which is the opposite of `joinpath(parts...)`: it splits a filepath into its components ([#28156](https://github.com/JuliaLang/julia/issues/28156)). + * `isnothing(::Any)` function, to check whether something is a `Nothing`, returns a `Bool` ([#29679](https://github.com/JuliaLang/julia/issues/29679)). + * `getpid(::Process)` method ([#24064](https://github.com/JuliaLang/julia/issues/24064)). + * `eachrow`, `eachcol` and `eachslice` functions provide efficient iterators over slices of arrays ([#29749](https://github.com/JuliaLang/julia/issues/29749)). + * `fieldtypes(T::Type)` which return the declared types of the field in type T ([#29600](https://github.com/JuliaLang/julia/issues/29600)). + * `uuid5` has been added to the `UUIDs` standard library ([#28761](https://github.com/JuliaLang/julia/issues/28761)). + * Predicate functions `Sys.isfreebsd`, `Sys.isopenbsd`, `Sys.isnetbsd`, and `Sys.isdragonfly` for + detecting BSD systems have been added ([#30249](https://github.com/JuliaLang/julia/issues/30249)). + +Standard library changes +------------------------ + + * `CartesianIndices` can now be constructed from two `CartesianIndex`es `I` and `J` with `I:J` ([#29440](https://github.com/JuliaLang/julia/issues/29440)). + * `CartesianIndices` support broadcasting arithmetic (+ and -) with a `CartesianIndex` ([#29890](https://github.com/JuliaLang/julia/issues/29890)). + * `copy!` support for arrays, dicts, and sets has been moved to Base from the Future package ([#29173](https://github.com/JuliaLang/julia/issues/29173)). + * Channels now convert inserted values (like containers) instead of requiring types to match ([#29092](https://github.com/JuliaLang/julia/issues/29092)). + * `range` can accept the stop value as a positional argument, e.g. `range(1,10,step=2)` ([#28708](https://github.com/JuliaLang/julia/issues/28708)). + * `diff` now supports arrays of arbitrary dimensionality and can operate over any dimension ([#29827](https://github.com/JuliaLang/julia/issues/29827)). + * The constructor `BigFloat(::BigFloat)` now respects the global precision setting and always + returns a `BigFloat` with precision equal to `precision(BigFloat)` ([#29127](https://github.com/JuliaLang/julia/issues/29127)). The optional + `precision` argument to override the global setting is now a keyword instead of positional + argument ([#29157](https://github.com/JuliaLang/julia/issues/29157)). + * The use of scientific notation when printing `BigFloat` values is now consistent with other floating point + types ([#29211](https://github.com/JuliaLang/julia/issues/29211)). + * `Regex` now behave like a scalar when used in broadcasting ([#29913](https://github.com/JuliaLang/julia/issues/29913)). + * `Char` now behaves like a read-only 0-dimensional array ([#29819](https://github.com/JuliaLang/julia/issues/29819)). + * `parse` now allows strings representing integer 0 and 1 for type `Bool` ([#29980](https://github.com/JuliaLang/julia/issues/29980)). + * `Base.tail` now works on named tuples ([#29595](https://github.com/JuliaLang/julia/issues/29595)). + * The process id is appended to malloc log files in order to track memory allocations of + multiple processes ([#29969](https://github.com/JuliaLang/julia/issues/29969)). + * `Base.julia_cmd` now propagates the `--inline=(yes|no)` flag ([#29858](https://github.com/JuliaLang/julia/issues/29858)). + * `Base.@kwdef` can now be used for parametric structs, and for structs with supertypes ([#29316](https://github.com/JuliaLang/julia/issues/29316)). + * `merge(::NamedTuple, ::NamedTuple...)` can now be used with more than 2 `NamedTuple`s ([#29259](https://github.com/JuliaLang/julia/issues/29259)). + * `Future.copy!` has been moved to `Base` ([#29178](https://github.com/JuliaLang/julia/issues/29178)). + * New `ncodeunits(c::Char)` method as a fast equivalent to `ncodeunits(string(c))` ([#29153](https://github.com/JuliaLang/julia/issues/29153)). + * New `sort!(::AbstractArray; dims)` method that can sort the array along the `dims` dimension ([#28902](https://github.com/JuliaLang/julia/issues/28902)). + * `range` now accept `stop` as a positional argument ([#28708](https://github.com/JuliaLang/julia/issues/28708)). + * `parse(Bool, str)` is now supported ([#29997](https://github.com/JuliaLang/julia/issues/29997)). + * `copyto!(::AbstractMatrix, ::UniformScaling)` supports rectangular matrices now ([#28790](https://github.com/JuliaLang/julia/issues/28790)). + * In `put!(c::Channel{T}, v)`, `v` now gets converted to `T` as `put!` is being called ([#29092](https://github.com/JuliaLang/julia/issues/29092)). + * `current_project()` now searches the parent directories of a Git repository for a `Project.toml` file. + This also affects the behavior of the `--project` command line option when using the default + `--project=@.` ([#29108](https://github.com/JuliaLang/julia/issues/29108)). + +#### Dates + * New `DateTime(::Date, ::Time)` constructor ([#29754](https://github.com/JuliaLang/julia/issues/29754)). + * `TimeZone` now behave like a scalar when used in broadcasting ([#30159](https://github.com/JuliaLang/julia/issues/30159)). + +#### InteractiveUtils + * `edit` can now be called on a module to edit the file that defines it ([#29636](https://github.com/JuliaLang/julia/issues/29636)). + * All compiler-reflection tools (i.e. the `code_` class of functions and macros) now print accurate + line number and inlining information in a common style, and take an optional parameter (debuginfo=:default) + to control the verbosity of the metadata shown ([#29893](https://github.com/JuliaLang/julia/issues/29893)). + +#### LinearAlgebra + * `isdiag` and `isposdef` for `Diagonal` and `UniformScaling` ([#29638](https://github.com/JuliaLang/julia/issues/29638)). + * `mul!`, `rmul!` and `lmul!` methods for `UniformScaling` ([#29506](https://github.com/JuliaLang/julia/issues/29506)). + * `Symmetric` and `Hermitian` matrices now preserve the wrapper when scaled with a number ([#29469](https://github.com/JuliaLang/julia/issues/29469)). + * Exponentiation operator `^` now supports raising a `Irrational` to an `AbstractMatrix` power ([#29782](https://github.com/JuliaLang/julia/issues/29782)). + +#### Random + * `randperm` and `randcycle` now use the type of their argument to determine the element type of + the returned array ([#29670](https://github.com/JuliaLang/julia/issues/29670)). + * A new method `rand(::Tuple)` implements sampling from the values of a tuple ([#25278](https://github.com/JuliaLang/julia/issues/25278)). + * `serialize` and `deserialize` now accept a filename argument, like `write` and `read` ([#30151](https://github.com/JuliaLang/julia/issues/30151)). + +#### SparseArrays + * `sprandn` now supports specifying the output element type ([#30083](https://github.com/JuliaLang/julia/issues/30083)). + +#### Statistics + * `mean` and `var` now handles the empty case ([#29033](https://github.com/JuliaLang/julia/issues/29033)). + +External dependencies +--------------------- + + * 7zip (bundled with Julia on Windows) has been upgraded from version 16.04 to 18.05 ([#30035](https://github.com/JuliaLang/julia/issues/30035)). + * Busybox is no longer bundled with Julia on Windows ([#30022](https://github.com/JuliaLang/julia/issues/30022)). + * OpenBLAS has been upgraded from 0.3.2 to 0.3.3 ([#29845](https://github.com/JuliaLang/julia/issues/29845)). + * The source code for Pkg is no longer included in JuliaLang/julia. Pkg is instead + downloaded during the build process ([#29615](https://github.com/JuliaLang/julia/issues/29615)). + * LLVM has been upgraded to 6.0.1 and support for LLVM < 6.0 has been dropped ([#28745](https://github.com/JuliaLang/julia/issues/28745), [#28696](https://github.com/JuliaLang/julia/issues/28696)). + +Deprecated or removed +--------------------- + + * `one(i::CartesianIndex)` should be replaced with `oneunit(i::CartesianIndex)` ([#29442](https://github.com/JuliaLang/julia/issues/29442)). + * The internal array `Base.Grisu.DIGITS` is deprecated; new code should use `Base.Grisu.getbuf()` + to get an appropriate task-local buffer and pass it to `grisu()` instead ([#29907](https://github.com/JuliaLang/julia/issues/29907)). + * The internal function `Base._default_type(T)` has been removed. Calls to it should be + replaced with just the argument `T` ([#29739](https://github.com/JuliaLang/julia/issues/29739)). + * `peakflops` has been scheduled to move from `InteractiveUtils` to `LinearAlgebra` + but is already now available as `LinearAlgebra.peakflops` ([#29978](https://github.com/JuliaLang/julia/issues/29978)). + diff --git a/src/assets/julia-manual.css b/src/assets/julia-manual.css index 00772f3..f303c67 100644 --- a/src/assets/julia-manual.css +++ b/src/assets/julia-manual.css @@ -1,3 +1,11 @@ nav.toc h1 { display: none; } + +.admonition.compat > .admonition-title { + background-color: hsla(90, 60%, 50%, 1); +} + +.admonition.compat { + background-color: hsla(90, 70%, 90%, 1); +} diff --git a/src/base/base.md b/src/base/base.md index fe609bc..2e057cb 100644 --- a/src/base/base.md +++ b/src/base/base.md @@ -285,6 +285,10 @@ Base.Sys.isunix Base.Sys.isapple Base.Sys.islinux Base.Sys.isbsd +Base.Sys.isfreebsd +Base.Sys.isopenbsd +Base.Sys.isnetbsd +Base.Sys.isdragonfly Base.Sys.iswindows Base.Sys.windows_version Base.@static diff --git a/src/devdocs/ast.md b/src/devdocs/ast.md index 699a2b0..a30bdd1 100644 --- a/src/devdocs/ast.md +++ b/src/devdocs/ast.md @@ -158,6 +158,9 @@ These symbols appear in the `head` field of `Expr`s in lowered form. Pop the stack of current exceptions back to the state at the associated `enter` when leaving a catch block. `args[1]` contains the token from the associated `enter`. + !!! compat "Julia 1.1" + `pop_exception` is new in Julia 1.1. + * `inbounds` Controls turning bounds checks on or off. A stack is maintained; if the first argument of this diff --git a/src/devdocs/isbitsunionarrays.md b/src/devdocs/isbitsunionarrays.md index 9831998..ad5e16c 100644 --- a/src/devdocs/isbitsunionarrays.md +++ b/src/devdocs/isbitsunionarrays.md @@ -6,8 +6,8 @@ Julia also supports Union types, quite literally the union of a set of types. Cu ## isbits Union Structs -Julia now includes an optimization wherein "isbits Union" fields in types (`mutable struct`, `struct`, etc.) will be stored inline. This is accomplished by determining the "inline size" of the Union type (e.g. `Union{UInt8, Int16}` will have a size of 16 bytes, which represents the size needed of the largest Union type `Int16`), and in addition, allocating an extra "type tag byte" (`UInt8`), whose value signals the type of the actual value stored inline of the "Union bytes". The type tag byte value is the index of the actual value's type in the Union type's order of types. For example, a type tag value of `0x02` for a field with type `Union{Nothing, UInt8, Int16}` would indicate that an `Int16` value is stored in the 16 bytes of the field in the structure's memory; a `0x01` value would indicate that a `UInt8` value was stored in the first 8 bytes of the 16 bytes of the field's memory. Lastly, a value of `0x00` signals that the `nothing` value will be returned for this field, even though, as a singleton type with a single type instance, it technically has a size of 0. The type tag byte for a type's Union field is stored directly after the field's computed Union memory. +Julia now includes an optimization wherein "isbits Union" fields in types (`mutable struct`, `struct`, etc.) will be stored inline. This is accomplished by determining the "inline size" of the Union type (e.g. `Union{UInt8, Int16}` will have a size of two bytes, which represents the size needed of the largest Union type `Int16`), and in addition, allocating an extra "type tag byte" (`UInt8`), whose value signals the type of the actual value stored inline of the "Union bytes". The type tag byte value is the index of the actual value's type in the Union type's order of types. For example, a type tag value of `0x02` for a field with type `Union{Nothing, UInt8, Int16}` would indicate that an `Int16` value is stored in the 16 bytes of the field in the structure's memory; a `0x01` value would indicate that a `UInt8` value was stored in the first 8 bytes of the 16 bytes of the field's memory. Lastly, a value of `0x00` signals that the `nothing` value will be returned for this field, even though, as a singleton type with a single type instance, it technically has a size of 0. The type tag byte for a type's Union field is stored directly after the field's computed Union memory. ## isbits Union Arrays -Julia can now also store "isbits Union" values inline in an Array, as opposed to requiring an indirection box. The optimization is accomplished by storing an extra "type tag array" of bytes, one byte per array element, alongside the bytes of the actual array data. This type tag array serves the same function as the type field case: it's value signals the type of the actual stored Union value in the array. In terms of layout, a Julia Array can include extra "buffer" space before and after it's actual data values, which are tracked in the `a->offset` and `a->maxsize` fields of the `jl_array_t*` type. The "type tag array" is treated exactly as another `jl_array_t*`, but which shares the same `a->offset`, `a->maxsize`, and `a->len` fields. So the formula to access an isbits Union Array's type tag bytes is `a->data + (a->maxsize - a->offset) * a->elsize + a->offset`; i.e. the Array's `a->data` pointer is already shifted by `a->offset`, so correcting for that, we follow the data all the way to the max of what it can hold `a->maxsize`, then adjust by `a->ofset` more bytes to account for any present "front buffering" the array might be doing. This layout in particular allows for very efficient resizing operations as the type tag data only ever has to move when the actual array's data has to move. \ No newline at end of file +Julia can now also store "isbits Union" values inline in an Array, as opposed to requiring an indirection box. The optimization is accomplished by storing an extra "type tag array" of bytes, one byte per array element, alongside the bytes of the actual array data. This type tag array serves the same function as the type field case: its value signals the type of the actual stored Union value in the array. In terms of layout, a Julia Array can include extra "buffer" space before and after its actual data values, which are tracked in the `a->offset` and `a->maxsize` fields of the `jl_array_t*` type. The "type tag array" is treated exactly as another `jl_array_t*`, but which shares the same `a->offset`, `a->maxsize`, and `a->len` fields. So the formula to access an isbits Union Array's type tag bytes is `a->data + (a->maxsize - a->offset) * a->elsize + a->offset`; i.e. the Array's `a->data` pointer is already shifted by `a->offset`, so correcting for that, we follow the data all the way to the max of what it can hold `a->maxsize`, then adjust by `a->ofset` more bytes to account for any present "front buffering" the array might be doing. This layout in particular allows for very efficient resizing operations as the type tag data only ever has to move when the actual array's data has to move. diff --git a/src/devdocs/object.md b/src/devdocs/object.md index 49d1e46..8cba7c8 100644 --- a/src/devdocs/object.md +++ b/src/devdocs/object.md @@ -116,7 +116,6 @@ Types: ```c jl_datatype_t *jl_apply_type(jl_datatype_t *tc, jl_tuple_t *params); jl_datatype_t *jl_apply_array_type(jl_datatype_t *type, size_t dim); -jl_uniontype_t *jl_new_uniontype(jl_tuple_t *types); ``` While these are the most commonly used options, there are more low-level constructors too, which diff --git a/src/devdocs/reflection.md b/src/devdocs/reflection.md index bcf22fd..3e41b14 100644 --- a/src/devdocs/reflection.md +++ b/src/devdocs/reflection.md @@ -94,12 +94,12 @@ particular interest for understanding how language constructs map to primitive o as assignments, branches, and calls: ```jldoctest -julia> Meta.lower(@__MODULE__, :([1+2, sin(0.5)]) ) +julia> Meta.lower(@__MODULE__, :( [1+2, sin(0.5)] )) :($(Expr(:thunk, CodeInfo( - 1 ─ %1 = 1 + 2 - │ %2 = sin(0.5) - │ %3 = (Base.vect)(%1, %2) - └── return %3 +1 ─ %1 = 1 + 2 +│ %2 = sin(0.5) +│ %3 = (Base.vect)(%1, %2) +└── return %3 )))) ``` @@ -122,11 +122,11 @@ calls and expand argument types automatically: ```julia-repl julia> @code_llvm +(1,1) -; Function Attrs: sspreq -define i64 @"julia_+_130862"(i64, i64) #0 { +; @ int.jl:53 within `+' +define i64 @"julia_+_130862"(i64, i64) { top: - %2 = add i64 %1, %0, !dbg !8 - ret i64 %2, !dbg !8 + %2 = add i64 %1, %0 + ret i64 %2 } ``` diff --git a/src/manual/calling-c-and-fortran-code.md b/src/manual/calling-c-and-fortran-code.md index 54ae0f1..a73f746 100644 --- a/src/manual/calling-c-and-fortran-code.md +++ b/src/manual/calling-c-and-fortran-code.md @@ -44,6 +44,11 @@ to [`ccall`](@ref) are as follows: OR + a `:function` name symbol or `"function"` name string, which is resolved in the + current process, + + OR + a function pointer (for example, from `dlsym`). 2. Return type (see below for mapping the declared C type to Julia) diff --git a/src/manual/handling-operating-system-variation.md b/src/manual/handling-operating-system-variation.md index 155d303..026d7df 100644 --- a/src/manual/handling-operating-system-variation.md +++ b/src/manual/handling-operating-system-variation.md @@ -2,8 +2,9 @@ When writing cross-platform applications or libraries, it is often necessary to allow for differences between operating systems. The variable `Sys.KERNEL` can be used to handle such -cases. There are several functions in the `Sys` module intended to make this easier: -`isunix`, `islinux`, `isapple`, `isbsd`, and `iswindows`. These may be used as follows: +cases. There are several functions in the `Sys` module intended to make this easier, such as +`isunix`, `islinux`, `isapple`, `isbsd`, `isfreebsd`, and `iswindows`. These may be used +as follows: ```julia if Sys.iswindows() @@ -11,9 +12,9 @@ if Sys.iswindows() end ``` -Note that `islinux` and `isapple` are mutually exclusive subsets of `isunix`. Additionally, -there is a macro `@static` which makes it possible to use these functions to conditionally hide -invalid code, as demonstrated in the following examples. +Note that `islinux`, `isapple`, and `isfreebsd` are mutually exclusive subsets of `isunix`. +Additionally, there is a macro `@static` which makes it possible to use these functions to +conditionally hide invalid code, as demonstrated in the following examples. Simple blocks: diff --git a/src/manual/stacktraces.md b/src/manual/stacktraces.md index a7da7a6..01a3417 100644 --- a/src/manual/stacktraces.md +++ b/src/manual/stacktraces.md @@ -189,6 +189,9 @@ ERROR: Whoops! ## Exception stacks and [`catch_stack`](@ref) +!!! compat "Julia 1.1" + Exception stacks requires at least Julia 1.1. + While handling an exception further exceptions may be thrown. It can be useful to inspect all these exceptions to identify the root cause of a problem. The julia runtime supports this by pushing each exception onto an internal *exception stack* as it occurs. When the code exits a `catch` normally, any exceptions which were pushed onto the stack diff --git a/src/manual/strings.md b/src/manual/strings.md index 87a9ed5..1fd2a5b 100644 --- a/src/manual/strings.md +++ b/src/manual/strings.md @@ -854,7 +854,7 @@ julia> m[2] Captures can be referenced in a substitution string when using [`replace`](@ref) by using `\n` to refer to the nth capture group and prefixing the substitution string with `s`. Capture group 0 refers to the entire match object. Named capture groups can be referenced in the substitution -with `g`. For example: +with `\g`. For example: ```jldoctest julia> replace("first second", r"(\w+) (?\w+)" => s"\g \1") diff --git a/src/stdlib/LinearAlgebra.md b/src/stdlib/LinearAlgebra.md index e941069..0b245a5 100644 --- a/src/stdlib/LinearAlgebra.md +++ b/src/stdlib/LinearAlgebra.md @@ -371,6 +371,8 @@ LinearAlgebra.pinv LinearAlgebra.nullspace Base.kron LinearAlgebra.exp(::StridedMatrix{<:LinearAlgebra.BlasFloat}) +Base.:^(::AbstractMatrix, ::Number) +Base.:^(::Number, ::AbstractMatrix) LinearAlgebra.log(::StridedMatrix) LinearAlgebra.sqrt(::StridedMatrix{<:Real}) LinearAlgebra.cos(::StridedMatrix{<:Real}) diff --git a/src/stdlib/Pkg.md b/src/stdlib/Pkg.md index 56357bf..e5c14ac 100644 --- a/src/stdlib/Pkg.md +++ b/src/stdlib/Pkg.md @@ -1,865 +1,17 @@ # Pkg -## Introduction - -Pkg is the standard package manager for Julia 1.0 and newer. Unlike traditional -package managers, which install and manage a single global set of packages, Pkg -is designed around “environments”: independent sets of packages that can be -local to an individual project or shared and selected by name. The exact set of -packages and versions in an environment is captured in a _manifest file_ which -can be checked into a project repository and tracked in version control, -significantly improving reproducibility of projects. If you’ve ever tried to run -code you haven’t used in a while only to find that you can’t get anything to -work because you’ve updated or uninstalled some of the packages your project was -using, you’ll understand the motivation for this approach. In Pkg, since each -project maintains its own independent set of package versions, you’ll never have -this problem again. Moreover, if you check out a project on a new system, you -can simply materialize the environment described by its manifest file and -immediately be up and running with a known-good set of dependencies. - -Since environments are managed and updated independently from each other, -“dependency hell” is significantly alleviated in Pkg. If you want to use the -latest and greatest version of some package in a new project but you’re stuck on -an older version in a different project, that’s no problem – since they have -separate environments they can just use different versions, which are both -installed at the same time in different locations on your system. The location -of each package version is canonical, so when environments use the same versions -of packages, they can share installations, avoiding unnecessary duplication of -the package. Old package versions that are no longer used by any environments -are periodically “garbage collected” by the package manager. - -Pkg’s approach to local environments may be familiar to people who have used -Python’s `virtualenv` or Ruby’s `bundler`. In Julia, instead of hacking the -language’s code loading mechanisms to support environments, we have the benefit -that Julia natively understands them. In addition, Julia environments are -“stackable”: you can overlay one environment with another and thereby have -access to additional packages outside of the primary environment. This makes it -easy to work on a project, which provides the primary environment, while still -having access to all your usual dev tools like profilers, debuggers, and so on, -just by having an environment including these dev tools later in the load path. - -Last but not least, Pkg is designed to support federated package registries. -This means that it allows multiple registries managed by different parties to -interact seamlessly. In particular, this includes private registries which can -live behind corporate firewalls. You can install and update your own packages -from a private registry with exactly the same tools and workflows that you use -to install and manage official Julia packages. If you urgently need to apply a -hotfix for a public package that’s critical to your company’s product, you can -tag a private version of it in your company’s internal registry and get a fix to -your developers and ops teams quickly and easily without having to wait for an -upstream patch to be accepted and published. Once an official fix is published, -however, you can just upgrade your dependencies and you'll be back on an -official release again. - -## Glossary - -**Project:** a source tree with a standard layout, including a `src` directory -for the main body of Julia code, a `test` directory for testing the project, -`docs` for documentation files, and optionally a `deps` directory for a build -script and its outputs. A project will typically also have a project file and -may optionally have a manifest file: - -- **Project file:** a file in the root directory of a project, named - `Project.toml` (or `JuliaProject.toml`) describing metadata about the project, - including its name, UUID (for packages), authors, license, and the names and - UUIDs of packages and libraries that it depends on. - -- **Manifest file:** a file in the root directory of a project, named - `Manifest.toml` (or `JuliaManifest.toml`) describing a complete dependency graph - and exact versions of each package and library used by a project. - -**Package:** a project which provides reusable functionality that can be used by -other Julia projects via `import X` or `using X`. A package should have a -project file with a `uuid` entry giving its package UUID. This UUID is used to -identify the package in projects that depend on it. +Pkg is Julia's builtin package manager, and handles operations +such as installing, updating and removing packages. !!! note - For legacy reasons it is possible to load a package without a project file or - UUID from the REPL or the top-level of a script. It is not possible, however, - to load a package without a project file or UUID from a project with them. Once - you've loaded from a project file, everything needs a project file and UUID. - -**Application:** a project which provides standalone functionality not intended -to be reused by other Julia projects. For example a web application or a -commmand-line utility, or simulation/analytics code accompanying a scientific paper. -An application may have a UUID but does not need one. -An application may also provide global configuration options for packages it -depends on. Packages, on the other hand, may not provide global configuration -since that could conflict with the configuration of the main application. - -!!! note - **Projects _vs._ Packages _vs._ Applications:** - - 1. **Project** is an umbrella term: packages and applications are kinds of projects. - 2. **Packages** should have UUIDs, applications can have a UUIDs but don't need them. - 3. **Applications** can provide global configuration, whereas packages cannot. - -**Library (future work):** a compiled binary dependency (not written in Julia) -packaged to be used by a Julia project. These are currently typically built in- -place by a `deps/build.jl` script in a project’s source tree, but in the future -we plan to make libraries first-class entities directly installed and upgraded -by the package manager. - -**Environment:** the combination of the top-level name map provided by a project -file combined with the dependency graph and map from packages to their entry points -provided by a manifest file. For more detail see the manual section on code loading. - -- **Explicit environment:** an environment in the form of an explicit project - file and an optional corresponding manifest file together in a directory. If the - manifest file is absent then the implied dependency graph and location maps are - empty. - -- **Implicit environment:** an environment provided as a directory (without a - project file or manifest file) containing packages with entry points of the form - `X.jl`, `X.jl/src/X.jl` or `X/src/X.jl`. The top-level name map is implied by - these entry points. The dependency graph is implied by the existence of project - files inside of these package directories, e.g. `X.jl/Project.toml` or - `X/Project.toml`. The dependencies of the `X` package are the dependencies in - the corresponding project file if there is one. The location map is implied by - the entry points themselves. - -**Registry:** a source tree with a standard layout recording metadata about a -registered set of packages, the tagged versions of them which are available, and -which versions of packages are compatible or incompatible with each other. A -registry is indexed by package name and UUID, and has a directory for each -registered package providing the following metadata about it: - -- name – e.g. `DataFrames` -- UUID – e.g. `a93c6f00-e57d-5684-b7b6-d8193f3e46c0` -- authors – e.g. `Jane Q. Developer ` -- license – e.g. MIT, BSD3, or GPLv2 -- repository – e.g. `https://github.com/JuliaData/DataFrames.jl.git` -- description – a block of text summarizing the functionality of a package -- keywords – e.g. `data`, `tabular`, `analysis`, `statistics` -- versions – a list of all registered version tags - -For each registered version of a package, the following information is provided: - -- its semantic version number – e.g. `v1.2.3` -- its git tree SHA-1 hash – e.g. `7ffb18ea3245ef98e368b02b81e8a86543a11103` -- a map from names to UUIDs of dependencies -- which versions of other packages it is compatible/incompatible with - -Dependencies and compatibility are stored in a compressed but human-readable -format using ranges of package versions. - -**Depot:** a directory on a system where various package-related resources live, -including: - -- `environments`: shared named environments (e.g. `v1.0`, `devtools`) -- `clones`: bare clones of package repositories -- `compiled`: cached compiled package images (`.ji` files) -- `config`: global configuration files (e.g. `startup.jl`) -- `dev`: default directory for package development -- `logs`: log files (e.g. `manifest_usage.toml`, `repl_history.jl`) -- `packages`: installed package versions -- `registries`: clones of registries (e.g. `General`) - -**Load path:** a stack of environments where package identities, their -dependencies, and entry-points are searched for. The load path is controlled in -Julia by the `LOAD_PATH` global variable which is populated at startup based on -the value of the `JULIA_LOAD_PATH` environment variable. The first entry is your -primary environment, often the current project, while later entries provide -additional packages one may want to use from the REPL or top-level scripts. - -**Depot path:** a stack of depot locations where the package manager, as well as -Julia's code loading mechanisms, look for registries, installed packages, named -environments, repo clones, cached compiled package images, and configuration -files. The depot path is controlled by the Julia `DEPOT_PATH` global variable -which is populated at startup based on the value of the `JULIA_DEPOT_PATH` -environment variable. The first entry is the “user depot” and should be writable -by and owned by the current user. The user depot is where: registries are -cloned, new package versions are installed, named environments are created and -updated, package repos are cloned, newly compiled package image files are saved, -log files are written, development packages are checked out by default, and -global configuration data is saved. Later entries in the depot path are treated -as read-only and are appropriate for registries, packages, etc. installed and -managed by system administrators. - -## Getting Started - -The Pkg REPL-mode is entered from the Julia REPL using the key `]`. - -``` -(v1.0) pkg> -``` - -The part inside the parenthesis of the prompt shows the name of the current project. -Since we haven't created our own project yet, we are in the default project, located at `~/.julia/environments/v1.0` -(or whatever version of Julia you happen to run). - -To return to the `julia>` prompt, either press backspace when the input line is empty or press Ctrl+C. -Help is available by calling `pkg> help`. -If you are in an environment that does not have access to a REPL you can still use the REPL mode commands using -the string macro `pkg` available after `using Pkg`. The command `pkg"cmd"` would be equivalent to executing `cmd` -in the REPL mode. - -The documentation here describes using Pkg from the REPL mode. Documentation of using -the Pkg API (by calling `Pkg.` functions) is in progress of being written. - -### Adding packages - -There are two ways of adding packages, either using the `add` command or the `dev` command. -The most frequently used one is `add` and its usage is described first. - -#### Adding registered packages - -In the Pkg REPL packages can be added with the `add` command followed by the name of the package, for example: - -``` -(v1.0) pkg> add Example - Cloning default registries into /Users/kristoffer/.julia/registries - Cloning registry General from "https://github.com/JuliaRegistries/General.git" - Updating registry at `~/.julia/registries/General` - Updating git-repo `https://github.com/JuliaRegistries/General.git` - Resolving package versions... - Updating `~/.julia/environments/v1.0/Project.toml` - [7876af07] + Example v0.5.1 - Updating `~/.julia/environments/v1.0/Manifest.toml` - [7876af07] + Example v0.5.1 - [8dfed614] + Test -``` - -Here we added the package Example to the current project. In this example, we are using a fresh Julia installation, -and this is our first time adding a package using Pkg. By default, Pkg clones Julia's General registry, -and uses this registry to look up packages requested for inclusion in the current environment. -The status update shows a short form of the package UUID to the left, then the package name, and the version. -Since standard libraries (e.g. `Test`) are shipped with Julia, they do not have a version. The project status contains the packages -you have added yourself, in this case, `Example`: - -``` -(v1.0) pkg> st - Status `Project.toml` - [7876af07] Example v0.5.1 -``` - -The manifest status, in addition, includes the dependencies of explicitly added packages. - -``` -(v1.0) pkg> st --manifest - Status `Manifest.toml` - [7876af07] Example v0.5.1 - [8dfed614] Test -``` - -It is possible to add multiple packages in one command as `pkg> add A B C`. - -After a package is added to the project, it can be loaded in Julia: - -``` -julia> using Example - -julia> Example.hello("User") -"Hello, User" -``` - -A specific version can be installed by appending a version after a `@` symbol, e.g. `@v0.4`, to the package name: - -``` -(v1.0) pkg> add Example@0.4 - Resolving package versions... - Updating `~/.julia/environments/v1.0/Project.toml` - [7876af07] + Example v0.4.1 - Updating `~/.julia/environments/v1.0/Manifest.toml` - [7876af07] + Example v0.4.1 -``` - -If the master branch (or a certain commit SHA) of `Example` has a hotfix that has not yet included in a registered version, -we can explicitly track a branch (or commit) by appending `#branch` (or `#commit`) to the package name: - -``` -(v1.0) pkg> add Example#master - Updating git-repo `https://github.com/JuliaLang/Example.jl.git` - Resolving package versions... - Updating `~/.julia/environments/v1.0/Project.toml` - [7876af07] ~ Example v0.5.1 ⇒ v0.5.1+ #master (https://github.com/JuliaLang/Example.jl.git) - Updating `~/.julia/environments/v1.0/Manifest.toml` - [7876af07] ~ Example v0.5.1 ⇒ v0.5.1+ #master (https://github.com/JuliaLang/Example.jl.git) -``` - -The status output now shows that we are tracking the `master` branch of `Example`. -When updating packages, we will pull updates from that branch. - -To go back to tracking the registry version of `Example`, the command `free` is used: - -``` -(v1.0) pkg> free Example - Resolving package versions... - Updating `~/.julia/environments/v1.0/Project.toml` - [7876af07] ~ Example v0.5.1+ #master (https://github.com/JuliaLang/Example.jl.git) ⇒ v0.5.1 - Updating `~/.julia/environments/v1.0/Manifest.toml` - [7876af07] ~ Example v0.5.1+ #master )https://github.com/JuliaLang/Example.jl.git) ⇒ v0.5.1 -``` - - -#### Adding unregistered packages - -If a package is not in a registry, it can still be added by instead of the package name giving the URL to the repository to `add`. - -``` -(v1.0) pkg> add https://github.com/fredrikekre/ImportMacros.jl - Updating git-repo `https://github.com/fredrikekre/ImportMacros.jl` - Resolving package versions... -Downloaded MacroTools ─ v0.4.1 - Updating `~/.julia/environments/v1.0/Project.toml` - [e6797606] + ImportMacros v0.0.0 # (https://github.com/fredrikekre/ImportMacros.jl) - Updating `~/.julia/environments/v1.0/Manifest.toml` - [e6797606] + ImportMacros v0.0.0 # (https://github.com/fredrikekre/ImportMacros.jl) - [1914dd2f] + MacroTools v0.4.1 -``` - -The dependencies of the unregistered package (here `MacroTools`) got installed. -For unregistered packages we could have given a branch (or commit SHA) to track using `#`, just like for registered packages. - - -#### Adding a local package - -Instead of giving a URL of a git repo to `add` we could instead have given a local path to a git repo. -This works similarly to adding a URL. The local repository will be tracked (at some branch) and updates -from that local repo are pulled when packages are updated. -Note that changes to files in the local package repository will not immediately be reflected when loading that package. -The changes would have to be committed and the packages updated in order to pull in the changes. - -#### Developing packages - -By only using `add` your Manifest will always have a "reproducible state", in other words, as long as the repositories and registries used are still accessible -it is possible to retrieve the exact state of all the dependencies in the project. This has the advantage that you can send your project (`Project.toml` -and `Manifest.toml`) to someone else and they can "instantiate" that project in the same state as you had it locally. -However, when you are developing a package, it is more convenient to load packages at their current state at some path. For this reason, the `dev` command exists. - -Let's try to `dev` a registered package: - -``` -(v1.0) pkg> dev Example - Updating git-repo `https://github.com/JuliaLang/Example.jl.git` - Resolving package versions... - Updating `~/.julia/environments/v1.0/Project.toml` - [7876af07] + Example v0.5.1+ [`~/.julia/dev/Example`] - Updating `~/.julia/environments/v1.0/Manifest.toml` - [7876af07] + Example v0.5.1+ [`~/.julia/dev/Example`] -``` - -The `dev` command fetches a full clone of the package to `~/.julia/dev/` (the path can be changed by setting the environment variable `JULIA_PKG_DEVDIR`). -When importing `Example` julia will now import it from `~/.julia/dev/Example` and whatever local changes have been made to the files in that path are consequently -reflected in the code loaded. When we used `add` we said that we tracked the package repository, we here say that we track the path itself. -Note that the package manager will never touch any of the files at a tracked path. It is therefore up to you to pull updates, change branches etc. -If we try to `dev` a package at some branch that already exists at `~/.julia/dev/` the package manager we will simply use the existing path. -For example: - -``` -(v1.0) pkg> dev Example - Updating git-repo `https://github.com/JuliaLang/Example.jl.git` -[ Info: Path `/Users/kristoffer/.julia/dev/Example` exists and looks like the correct package, using existing path instead of cloning -``` - -Note the info message saying that it is using the existing path. As a general rule, the package manager will -never touch files that are tracking a path. - -If `dev` is used on a local path, that path to that package is recorded and used when loading that package. -The path will be recorded relative to the project file, unless it is given as an absolute path. - -To stop tracking a path and use the registered version again, use `free` - -``` -(v1.0) pkg> free Example - Resolving package versions... - Updating `~/.julia/environments/v1.0/Project.toml` - [7876af07] ↓ Example v0.5.1+ [`~/.julia/dev/Example`] ⇒ v0.5.1 - Updating `~/.julia/environments/v1.0/Manifest.toml` - [7876af07] ↓ Example v0.5.1+ [`~/.julia/dev/Example`] ⇒ v0.5.1 -``` - -It should be pointed out that by using `dev` your project is now inherently stateful. -Its state depends on the current content of the files at the path and the manifest cannot be "instantiated" by someone else without -knowing the exact content of all the packages that are tracking a path. - -Note that if you add a dependency to a package that tracks a local path, the Manifest (which contains the whole dependency graph) will become -out of sync with the actual dependency graph. This means that the package will not be able to load that dependency since it is not recorded -in the Manifest. To update sync the Manifest, use the REPL command `resolve`. - -### Removing packages - -Packages can be removed from the current project by using `pkg> rm Package`. -This will only remove packages that exist in the project, to remove a package that only -exists as a dependency use `pkg> rm --manifest DepPackage`. -Note that this will remove all packages that depends on `DepPackage`. - -### Updating packages - -When new versions of packages the project is using are released, it is a good idea to update. Simply calling `up` will try to update *all* the dependencies of the project -to the latest compatible version. Sometimes this is not what you want. You can specify a subset of the dependencies to upgrade by giving them as arguments to `up`, e.g: - -``` -(v1.0) pkg> up Example -``` - -The version of all other packages direct dependencies will stay the same. If you only want to update the minor version of packages, to reduce the risk that your project breaks, you can give the `--minor` flag, e.g: - -``` -(v1.0) pkg> up --minor Example -``` - -Packages that track a repository are not updated when a minor upgrade is done. -Packages that track a path are never touched by the package manager. - -### Pinning a package - -A pinned package will never be updated. A package can be pinned using `pin` as for example - -``` -(v1.0) pkg> pin Example - Resolving package versions... - Updating `~/.julia/environments/v1.0/Project.toml` - [7876af07] ~ Example v0.5.1 ⇒ v0.5.1 ⚲ - Updating `~/.julia/environments/v1.0/Manifest.toml` - [7876af07] ~ Example v0.5.1 ⇒ v0.5.1 ⚲ -``` - -Note the pin symbol `⚲` showing that the package is pinned. Removing the pin is done using `free` - -``` -(v1.0) pkg> free Example - Updating `~/.julia/environments/v1.0/Project.toml` - [7876af07] ~ Example v0.5.1 ⚲ ⇒ v0.5.1 - Updating `~/.julia/environments/v1.0/Manifest.toml` - [7876af07] ~ Example v0.5.1 ⚲ ⇒ v0.5.1 -``` - -### Testing packages - -The tests for a package can be run using `test`command: - -``` -(v1.0) pkg> test Example - Testing Example - Testing Example tests passed -``` - -### Building packages - -The build step of a package is automatically run when a package is first installed. -The output of the build process is directed to a file. -To explicitly run the build step for a package the `build` command is used: - -``` -(v1.0) pkg> build MbedTLS - Building MbedTLS → `~/.julia/packages/MbedTLS/h1Vu/deps/build.log` - -shell> cat ~/.julia/packages/MbedTLS/h1Vu/deps/build.log -┌ Warning: `wait(t::Task)` is deprecated, use `fetch(t)` instead. -│ caller = macro expansion at OutputCollector.jl:63 [inlined] -└ @ Core OutputCollector.jl:63 -... -[ Info: using prebuilt binaries -``` - -## Creating your own projects - -So far we have added packages to the default project at `~/.julia/environments/v1.0`, it is, however, easy to create other, independent, projects. -It should be pointed out if two projects uses the same package at the same version, the content of this package is not duplicated. -In order to create a new project, create a directory for it and then activate that directory to make it the "active project" which package operations manipulate: - -``` -shell> mkdir MyProject - -shell> cd MyProject -/Users/kristoffer/MyProject - -(v1.0) pkg> activate . - -(MyProject) pkg> st - Status `Project.toml` -``` - -Note that the REPL prompt changed when the new project is activated. Since this is a newly created project, the status command show it contains no packages, and in fact, it has no project or manifest file until we add a package to it: - -``` -shell> ls -l -total 0 - -(MyProject) pkg> add Example - Updating registry at `~/.julia/registries/General` - Updating git-repo `https://github.com/JuliaRegistries/General.git` - Resolving package versions... - Updating `Project.toml` - [7876af07] + Example v0.5.1 - Updating `Manifest.toml` - [7876af07] + Example v0.5.1 - [8dfed614] + Test - -shell> ls -l -total 8 --rw-r--r-- 1 stefan staff 207 Jul 3 16:35 Manifest.toml --rw-r--r-- 1 stefan staff 56 Jul 3 16:35 Project.toml - -shell> cat Project.toml -[deps] -Example = "7876af07-990d-54b4-ab0e-23690620f79a" - -shell> cat Manifest.toml -[[Example]] -deps = ["Test"] -git-tree-sha1 = "8eb7b4d4ca487caade9ba3e85932e28ce6d6e1f8" -uuid = "7876af07-990d-54b4-ab0e-23690620f79a" -version = "0.5.1" - -[[Test]] -uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" -``` - -This new environment is completely separate from the one we used earlier. - -## Garbage collecting old, unused packages - -As packages are updated and projects are deleted, installed packages that were once used will inevitably -become old and not used from any existing project. -Pkg keeps a log of all projects used so it can go through the log and see exactly which projects still exist -and what packages those projects used. The rest can be deleted. -This is done with the `gc` command: - -``` -(v1.0) pkg> gc - Active manifests at: - `/Users/kristoffer/BinaryProvider/Manifest.toml` - ... - `/Users/kristoffer/Compat.jl/Manifest.toml` - Deleted /Users/kristoffer/.julia/packages/BenchmarkTools/1cAj: 146.302 KiB - Deleted /Users/kristoffer/.julia/packages/Cassette/BXVB: 795.557 KiB - ... - Deleted /Users/kristoffer/.julia/packages/WeakRefStrings/YrK6: 27.328 KiB - Deleted 36 package installations: 113.205 MiB -``` - -Note that only packages in `~/.julia/packages` are deleted. - -## Creating your own packages - -A package is a project with a `name`, `uuid` and `version` entry in the `Project.toml` file `src/PackageName.jl` file that defines the module `PackageName`. -This file is executed when the package is loaded. - -### Generating files for a package - -To generate files for a new package, use `pkg> generate`. - -``` -(v1.0) pkg> generate HelloWorld -``` - -This creates a new project `HelloWorld` with the following files (visualized with the external [`tree` command](https://linux.die.net/man/1/tree)): - -```jl -shell> cd HelloWorld - -shell> tree . -. -├── Project.toml -└── src - └── HelloWorld.jl - -1 directory, 2 files -``` - -The `Project.toml` file contains the name of the package, its unique UUID, its version, the author and eventual dependencies: - -```toml -name = "HelloWorld" -uuid = "b4cd1eb8-1e24-11e8-3319-93036a3eb9f3" -version = "0.1.0" -author = ["Some One "] - -[deps] -``` - -The content of `src/HelloWorld.jl` is: - -```jl -module HelloWorld - -greet() = print("Hello World!") - -end # module -``` - -We can now activate the project and load the package: - -```jl -pkg> activate . - -julia> import HelloWorld - -julia> HelloWorld.greet() -Hello World! -``` - -### Adding dependencies to the project - -Let’s say we want to use the standard library package `Random` and the registered package `JSON` in our project. -We simply `add` these packages (note how the prompt now shows the name of the newly generated project, -since we are inside the `HelloWorld` project directory): - -``` -(HelloWorld) pkg> add Random JSON - Resolving package versions... - Updating "~/Documents/HelloWorld/Project.toml" - [682c06a0] + JSON v0.17.1 - [9a3f8284] + Random - Updating "~/Documents/HelloWorld/Manifest.toml" - [34da2185] + Compat v0.57.0 - [682c06a0] + JSON v0.17.1 - [4d1e1d77] + Nullables v0.0.4 - ... -``` - -Both `Random` and `JSON` got added to the project’s `Project.toml` file, and the resulting dependencies got added to the `Manifest.toml` file. -The resolver has installed each package with the highest possible version, while still respecting the compatibility that each package enforce on its dependencies. - -We can now use both `Random` and `JSON` in our project. Changing `src/HelloWorld.jl` to - -``` -module HelloWorld - -import Random -import JSON - -greet() = print("Hello World!") -greet_alien() = print("Hello ", Random.randstring(8)) - -end # module -``` - -and reloading the package, the new `greet_alien` function that uses `Random` can be used: - -``` -julia> HelloWorld.greet_alien() -Hello aT157rHV -``` - -### Adding a build step to the package. - -The build step is executed the first time a package is installed or when explicitly invoked with `build`. -A package is built by executing the file `deps/build.jl`. - -``` -shell> cat deps/build.log -I am being built... - -(HelloWorld) pkg> build - Building HelloWorld → `deps/build.log` - Resolving package versions... - -shell> cat deps/build.log -I am being built... -``` - -If the build step fails, the output of the build step is printed to the console - -``` -shell> cat deps/build.jl -error("Ooops") - -(HelloWorld) pkg> build - Building HelloWorld → `deps/build.log` - Resolving package versions... -┌ Error: Error building `HelloWorld`: -│ ERROR: LoadError: Ooops -│ Stacktrace: -│ [1] error(::String) at ./error.jl:33 -│ [2] top-level scope at none:0 -│ [3] include at ./boot.jl:317 [inlined] -│ [4] include_relative(::Module, ::String) at ./loading.jl:1071 -│ [5] include(::Module, ::String) at ./sysimg.jl:29 -│ [6] include(::String) at ./client.jl:393 -│ [7] top-level scope at none:0 -│ in expression starting at /Users/kristoffer/.julia/dev/Pkg/HelloWorld/deps/build.jl:1 -└ @ Pkg.Operations Operations.jl:938 -``` - -### Adding tests to the package - -When a package is tested the file `test/runtests.jl` is executed. - -``` -shell> cat test/runtests.jl -println("Testing...") -(HelloWorld) pkg> test - Testing HelloWorld - Resolving package versions... -Testing... - Testing HelloWorld tests passed -``` - -#### Test-specific dependencies - -Sometimes one might want to use some packages only at testing time but not -enforce a dependency on them when the package is used. This is possible by -adding dependencies to `[extras]` and a `test` target in `[targets]` to the Project file. -Here we add the `Test` standard library as a test-only dependency by adding the -following to the Project file: - -``` -[extras] -Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[targets] -test = ["Test"] -``` - -We can now use `Test` in the test script and we can see that it gets installed on testing: - -``` -shell> cat test/runtests.jl -using Test -@test 1 == 1 - -(HelloWorld) pkg> test - Testing HelloWorld - Resolving package versions... - Updating `/var/folders/64/76tk_g152sg6c6t0b4nkn1vw0000gn/T/tmpPzUPPw/Project.toml` - [d8327f2a] + HelloWorld v0.1.0 [`~/.julia/dev/Pkg/HelloWorld`] - [8dfed614] + Test - Updating `/var/folders/64/76tk_g152sg6c6t0b4nkn1vw0000gn/T/tmpPzUPPw/Manifest.toml` - [d8327f2a] + HelloWorld v0.1.0 [`~/.julia/dev/Pkg/HelloWorld`] - Testing HelloWorld tests passed``` -``` - -### Compatibility - -Compatibility refers to the ability to restrict what version of the dependencies that your project is compatible with. -If the compatibility for a dependency is not given, the project is assumed to be compatible with all versions of that dependency. - -Compatibility for a dependency is entered in the `Project.toml` file as for example: - -```toml -[compat] -julia = "1.0" -Example = "0.4.3" -``` - -After a compatibility entry is put into the project file, `up` can be used to apply it. - -The format of the version specifier is described in detail below. - -!!! info - There is currently no way to give compatibility from the Pkg REPL mode so for now, one has to manually edit the project file. - -#### Version specifier format - -Similar to other package managers, the Julia package manager respects [semantic versioning](https://semver.org/) (semver). -As an example, a version specifier is given as e.g. `1.2.3` is therefore assumed to be compatible with the versions `[1.2.3 - 2.0.0)` where `)` is a non-inclusive upper bound. -More specifically, a version specifier is either given as a **caret specifier**, e.g. `^1.2.3` or a **tilde specifier** `~1.2.3`. -Caret specifiers are the default and hence `1.2.3 == ^1.2.3`. The difference between a caret and tilde is described in the next section. -The union of multiple version specifiers can be formed by comma separating indiviual version specifiers. - -##### Caret specifiers - -A caret specifier allows upgrade that would be compatible according to semver. -An updated dependency is considered compatible if the new version does not modify the left-most non zero digit in the version specifier. - -Some examples are shown below. - -``` -^1.2.3 = [1.2.3, 2.0.0) -^1.2 = [1.2.0, 2.0.0) -^1 = [1.0.0, 2.0.0) -^0.2.3 = [0.2.3, 0.3.0) -^0.0.3 = [0.0.3, 0.0.4) -^0.0 = [0.0.0, 0.1.0) -^0 = [0.0.0, 1.0.0) -``` - -While the semver specification says that all versions with a major version of 0 are incompatible with each other, we have made that choice that -a version given as `0.a.b` is considered compatible with `0.a.c` if `a != 0` and `c >= b`. - -##### Tilde specifiers - -A tilde specifier provides more limited upgrade possibilities. When specifying major, minor -and patch version, or when specifying major and minor version, only patch version is -allowed to change. If you only specify a major version, then both minor and patch versions -are allowed to be upgraded (`~1` is thus equivalent to `^1`). -This gives the following example. - -``` -~1.2.3 = [1.2.3, 1.3.0) -~1.2 = [1.2.0, 1.3.0) -~1 = [1.0.0, 2.0.0) -``` - -#### Inequality specifiers - -Inequalities can also be used to specify version ranges: - -``` ->= 1.2.3 = [1.2.3, ∞) -≥ 1.2.3 = [1.2.3, ∞) -= 1.2.3 = [1.2.3, 1.2.3] -< 1.2.3 = [0.0.0, 1.2.2] -``` - - -## Precompiling a project - -The REPL command `precompile` can be used to precompile all the dependencies in the project. You can for example do - -``` -(HelloWorld) pkg> update; precompile -``` - -to update the dependencies and then precompile them. - -## Preview mode - -If you just want to see the effects of running a command, but not change your state you can `preview` a command. -For example: - -``` -(HelloWorld) pkg> preview add Plots -``` - -or - -``` -(HelloWorld) pkg> preview up -``` - -will show you the effects of adding `Plots`, or doing a full upgrade, respectively, would have on your project. -However, nothing would be installed and your `Project.toml` and `Manifest.toml` are untouched. - -## Using someone else's project - -Simply clone their project using e.g. `git clone`, `cd` to the project directory and call - -``` -(v1.0) pkg> activate . - -(SomeProject) pkg> instantiate -``` - -If the project contains a manifest, this will install the packages in the same state that is given by that manifest. -Otherwise, it will resolve the latest versions of the dependencies compatible with the project. - -## References - -This section describes the "API mode" of interacting with Pkg.jl which is recommended for non-interactive usage, -in i.e. scripts. In the REPL mode packages (with associated version, UUID, URL etc) are parsed from strings, -for example, `"Package#master"`,`"Package@v0.1"`, `"www.mypkg.com/MyPkg#my/feature"`. -It is possible to use strings as arguments for simple commands in the API mode (like `Pkg.add(["PackageA", "PackageB"])`, -more complicated commands, that e.g. specify URLs or version range, uses a more structured format over strings. -This is done by creating an instance of a [`PackageSpec`](@ref) which are passed in to functions. - -```@docs -PackageSpec -PackageMode -UpgradeLevel -Pkg.add -Pkg.develop -Pkg.activate -Pkg.rm -Pkg.update -Pkg.test -Pkg.build -Pkg.pin -Pkg.free -Pkg.instantiate -Pkg.resolve -Pkg.setprotocol! + What follows is a very brief introduction to Pkg. It is highly + recommended to read the full manual, which is available here: + [https://julialang.github.io/Pkg.jl/v1/](https://julialang.github.io/Pkg.jl/v1/). + +```@eval +import Markdown +file = joinpath(Sys.STDLIB, "Pkg", "docs", "src", "getting-started.md") +str = read(file, String) +str = replace(str, r"^#.*$"m => "") +Markdown.parse(str) ``` From 3d2e9fa3d16e165926e7287f52dd9ab667ba4d5c Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Sat, 8 Dec 2018 10:03:23 +0900 Subject: [PATCH 081/153] update Julia Commit 4fc446f179 --- codex/NEWS.md | 15 +++++++++++++ codex/index.md | 7 +----- codex/manual/arrays.md | 30 ++++++++++++++++--------- codex/manual/constructors.md | 2 +- codex/manual/getting-started.md | 5 +++++ codex/manual/mathematical-operations.md | 4 ++-- codex/manual/types.md | 2 +- src/NEWS.md | 15 +++++++++++++ src/index.md | 8 ++----- src/manual/arrays.md | 23 ++++++++++++------- src/manual/constructors.md | 2 +- src/manual/getting-started.md | 5 +++++ src/manual/mathematical-operations.md | 4 ++-- src/manual/types.md | 2 +- 14 files changed, 85 insertions(+), 39 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index e69cd41..721d9ea 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -20,6 +20,14 @@ Language changes to the `Core` module ([#29968](https://github.com/JuliaLang/julia/issues/29968)). * Using the same name for both a local variable and a static parameter is now an error instead of a warning ([#29429](https://github.com/JuliaLang/julia/issues/29429)). + * `findall(in(b), a)` now returns a `CartesianIndex` when `a` is a matrix or a higher-dimensional array, + for consistency with other `findall` methods. Use `LinearIndices(a)[findall(in(b), a)]` to get + the old behavior, or `CartesianIndices(a)[findall(in(b), a)]` to get the new behavior + on previous Julia versions ([#30226](https://github.com/JuliaLang/julia/issues/30226)). + * `findmin(::BitArray)` and `findmax(::BitArray)` now return a `CartesianIndex` when `a` is a matrix + or a higher-dimensional array, for consistency with for other array types. + Use `LinearIndices(a)[findmin(a)[2]]` to get the old behavior, or `CartesianIndices(a)[findmin(a)[2]]` + to get the new behavior on previous Julia versions ([#30102](https://github.com/JuliaLang/julia/issues/30102)). * Method signatures such as `f(::Type{T}, ::T) where {T <: X}` and `f(::Type{X}, ::Any)` @@ -43,6 +51,9 @@ New library functions * `uuid5` has been added to the `UUIDs` standard library ([#28761](https://github.com/JuliaLang/julia/issues/28761)). * Predicate functions `Sys.isfreebsd`, `Sys.isopenbsd`, `Sys.isnetbsd`, and `Sys.isdragonfly` for detecting BSD systems have been added ([#30249](https://github.com/JuliaLang/julia/issues/30249)). + * Internal `Base.disable_library_threading` that sets libraries to use one thread. + It executes function hooks that have been registered with + `Base.at_disable_library_threading` ([#30004](https://github.com/JuliaLang/julia/issues/30004)). Standard library changes ------------------------ @@ -72,12 +83,16 @@ Standard library changes * New `ncodeunits(c::Char)` method as a fast equivalent to `ncodeunits(string(c))` ([#29153](https://github.com/JuliaLang/julia/issues/29153)). * New `sort!(::AbstractArray; dims)` method that can sort the array along the `dims` dimension ([#28902](https://github.com/JuliaLang/julia/issues/28902)). * `range` now accept `stop` as a positional argument ([#28708](https://github.com/JuliaLang/julia/issues/28708)). + * `get(A::AbstractArray, (), default)` now returns the result of `A[]` if it can instead of always + returning an empty array ([#30270](https://github.com/JuliaLang/julia/issues/30270)). * `parse(Bool, str)` is now supported ([#29997](https://github.com/JuliaLang/julia/issues/29997)). * `copyto!(::AbstractMatrix, ::UniformScaling)` supports rectangular matrices now ([#28790](https://github.com/JuliaLang/julia/issues/28790)). * In `put!(c::Channel{T}, v)`, `v` now gets converted to `T` as `put!` is being called ([#29092](https://github.com/JuliaLang/julia/issues/29092)). * `current_project()` now searches the parent directories of a Git repository for a `Project.toml` file. This also affects the behavior of the `--project` command line option when using the default `--project=@.` ([#29108](https://github.com/JuliaLang/julia/issues/29108)). + * The `spawn` API is now more flexible and supports taking IOBuffer directly as a I/O stream, + converting to a system pipe as needed ([#30278](https://github.com/JuliaLang/julia/issues/30278)). #### Dates * New `DateTime(::Date, ::Time)` constructor ([#29754](https://github.com/JuliaLang/julia/issues/29754)). diff --git a/codex/index.md b/codex/index.md index a627979..b8fe2dc 100644 --- a/codex/index.md +++ b/codex/index.md @@ -18,12 +18,7 @@ end import Markdown Markdown.parse(String(take!(io))) ``` - -Please read the [release blog post](https://julialang.org/blog/2018/08/one-point-zero) for a general overview of the language and -many of the changes since Julia v0.6. Note that version 0.7 was released alongside -1.0 to provide an upgrade path for packages and code that predates the 1.0 release. -The only difference between 0.7 and 1.0 is the removal of deprecation warnings. -For a complete list of all the changes since 0.6, see the [release notes for version 0.7](https://docs.julialang.org/en/v0.7.0/NEWS/) +Please read the [release notes](NEWS.md) to see what has changed since the last release. ### [Introduction](@id man-introduction) diff --git a/codex/manual/arrays.md b/codex/manual/arrays.md index 7c96925..4667fb4 100644 --- a/codex/manual/arrays.md +++ b/codex/manual/arrays.md @@ -279,7 +279,7 @@ julia> [(i,j) for i=1:3 for j=1:i if i+j == 4] ## [Indexing](@id man-array-indexing) -The general syntax for indexing into an n-dimensional array A is: +The general syntax for indexing into an n-dimensional array `A` is: ``` X = A[I_1, I_2, ..., I_n] @@ -295,8 +295,8 @@ If all the indices are scalars, then the result `X` is a single element from the `X` is an array with the same number of dimensions as the sum of the dimensionalities of all the indices. -If all indices are vectors, for example, then the shape of `X` would be `(length(I_1), length(I_2), ..., length(I_n))`, -with location `(i_1, i_2, ..., i_n)` of `X` containing the value `A[I_1[i_1], I_2[i_2], ..., I_n[i_n]]`. +If all indices `I_k` are vectors, for example, then the shape of `X` would be `(length(I_1), length(I_2), ..., length(I_n))`, +with location `i_1, i_2, ..., i_n` of `X` containing the value `A[I_1[i_1], I_2[i_2], ..., I_n[i_n]]`. Example: @@ -364,9 +364,9 @@ julia> A[[1 2; 1 2], 1, 2, 1] 5 6 ``` -The location `(i_1, i_2, i_3, ..., i_{n+1})` contains the value at `A[I_1[i_1, i_2], I_2[i_3], ..., I_n[i_{n+1}]]`. -All dimensions indexed with scalars are dropped. For example, the result of `A[2, I, 3]` is an -array with size `size(I)`. Its `i`th element is populated by `A[2, I[i], 3]`. +The location `i_1, i_2, i_3, ..., i_{n+1}` contains the value at `A[I_1[i_1, i_2], I_2[i_3], ..., I_n[i_{n+1}]]`. +All dimensions indexed with scalars are dropped. For example, if `J` is an array of indices, then the result of `A[2, J, 3]` is an +array with size `size(J)`. Its `j`th element is populated by `A[2, J[j], 3]`. As a special part of this syntax, the `end` keyword may be used to represent the last index of each dimension within the indexing brackets, as determined by the size of the innermost array @@ -410,7 +410,7 @@ julia> searchsorted(a, 4) ## Assignment -The general syntax for assigning values in an n-dimensional array A is: +The general syntax for assigning values in an n-dimensional array `A` is: ``` A[I_1, I_2, ..., I_n] = X @@ -422,10 +422,18 @@ where each `I_k` may be a scalar integer, an array of integers, or any other ranges of the form `a:c` or `a:b:c` to select contiguous or strided subsections, and arrays of booleans to select elements at their `true` indices. -If `X` is an array, it must have the same number of elements as the product of the lengths of -the indices: `prod(length(I_1), length(I_2), ..., length(I_n))`. The value in location `I_1[i_1], I_2[i_2], ..., I_n[i_n]` -of `A` is overwritten with the value `X[i_1, i_2, ..., i_n]`. If `X` is a scalar, use the -element-wise assignment operator `.=` to write the value to all referenced locations of `A`: +If all indices `I_k` are integers, then the value in location `I_1, I_2, ..., I_n` of `A` is +overwritten with the value of `X`, [`convert`](@ref)ing to the +[`eltype`](@ref) of `A` if necessary. + + +If any index `I_k` selects more than one location, then the right hand side `X` must be an +array with the same shape as the result of indexing `A[I_1, I_2, ..., I_n]` or a vector with +the same number of elements. The value in location `I_1[i_1], I_2[i_2], ..., I_n[i_n]` of +`A` is overwritten with the value `X[I_1, I_2, ..., I_n]`, converting if necessary. The +element-wise assignment operator `.=` may be used to [broadcast](@ref Broadcasting) `X` +across the selected locations: + ``` A[I_1, I_2, ..., I_n] .= X diff --git a/codex/manual/constructors.md b/codex/manual/constructors.md index 9f41aca..6d64130 100644 --- a/codex/manual/constructors.md +++ b/codex/manual/constructors.md @@ -300,7 +300,7 @@ julia> Point{Int64}(1, 2) ## explicit T ## Point{Int64}(1, 2) julia> Point{Int64}(1.0,2.5) ## explicit T ## -ERROR: InexactError: Int64(Int64, 2.5) +ERROR: InexactError: Int64(2.5) Stacktrace: [...] diff --git a/codex/manual/getting-started.md b/codex/manual/getting-started.md index 9e5d55a..f6fa622 100644 --- a/codex/manual/getting-started.md +++ b/codex/manual/getting-started.md @@ -125,6 +125,11 @@ julia [switches] -- [programfile] [args...] |`--track-allocation={none\|user\|all}` |Count bytes allocated by each source line| |`--track-allocation` |equivalent to `--track-allocation=user`| +!!! compat "Julia 1.1" + In Julia 1.0, the default `--project=@.` option did not search up from the root + directory of a Git repository for the `Project.toml` file. From Julia 1.1 forward, it + does. + ## Resources A curated list of useful learning resources to help new users get started can be found on the [learning](https://julialang.org/learning/) page of the main Julia web site. diff --git a/codex/manual/mathematical-operations.md b/codex/manual/mathematical-operations.md index 6d451ea..6ba2588 100644 --- a/codex/manual/mathematical-operations.md +++ b/codex/manual/mathematical-operations.md @@ -432,12 +432,12 @@ julia> Int8(127.0) 127 julia> Int8(3.14) -ERROR: InexactError: Int8(Int8, 3.14) +ERROR: InexactError: Int8(3.14) Stacktrace: [...] julia> Int8(128.0) -ERROR: InexactError: Int8(Int8, 128.0) +ERROR: InexactError: Int8(128.0) Stacktrace: [...] diff --git a/codex/manual/types.md b/codex/manual/types.md index cd0fdd0..c219f37 100644 --- a/codex/manual/types.md +++ b/codex/manual/types.md @@ -344,7 +344,7 @@ must be convertible to `Int`: ```jldoctest footype julia> Foo((), 23.5, 1) -ERROR: InexactError: Int64(Int64, 23.5) +ERROR: InexactError: Int64(23.5) Stacktrace: [...] ``` diff --git a/src/NEWS.md b/src/NEWS.md index e69cd41..721d9ea 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -20,6 +20,14 @@ Language changes to the `Core` module ([#29968](https://github.com/JuliaLang/julia/issues/29968)). * Using the same name for both a local variable and a static parameter is now an error instead of a warning ([#29429](https://github.com/JuliaLang/julia/issues/29429)). + * `findall(in(b), a)` now returns a `CartesianIndex` when `a` is a matrix or a higher-dimensional array, + for consistency with other `findall` methods. Use `LinearIndices(a)[findall(in(b), a)]` to get + the old behavior, or `CartesianIndices(a)[findall(in(b), a)]` to get the new behavior + on previous Julia versions ([#30226](https://github.com/JuliaLang/julia/issues/30226)). + * `findmin(::BitArray)` and `findmax(::BitArray)` now return a `CartesianIndex` when `a` is a matrix + or a higher-dimensional array, for consistency with for other array types. + Use `LinearIndices(a)[findmin(a)[2]]` to get the old behavior, or `CartesianIndices(a)[findmin(a)[2]]` + to get the new behavior on previous Julia versions ([#30102](https://github.com/JuliaLang/julia/issues/30102)). * Method signatures such as `f(::Type{T}, ::T) where {T <: X}` and `f(::Type{X}, ::Any)` @@ -43,6 +51,9 @@ New library functions * `uuid5` has been added to the `UUIDs` standard library ([#28761](https://github.com/JuliaLang/julia/issues/28761)). * Predicate functions `Sys.isfreebsd`, `Sys.isopenbsd`, `Sys.isnetbsd`, and `Sys.isdragonfly` for detecting BSD systems have been added ([#30249](https://github.com/JuliaLang/julia/issues/30249)). + * Internal `Base.disable_library_threading` that sets libraries to use one thread. + It executes function hooks that have been registered with + `Base.at_disable_library_threading` ([#30004](https://github.com/JuliaLang/julia/issues/30004)). Standard library changes ------------------------ @@ -72,12 +83,16 @@ Standard library changes * New `ncodeunits(c::Char)` method as a fast equivalent to `ncodeunits(string(c))` ([#29153](https://github.com/JuliaLang/julia/issues/29153)). * New `sort!(::AbstractArray; dims)` method that can sort the array along the `dims` dimension ([#28902](https://github.com/JuliaLang/julia/issues/28902)). * `range` now accept `stop` as a positional argument ([#28708](https://github.com/JuliaLang/julia/issues/28708)). + * `get(A::AbstractArray, (), default)` now returns the result of `A[]` if it can instead of always + returning an empty array ([#30270](https://github.com/JuliaLang/julia/issues/30270)). * `parse(Bool, str)` is now supported ([#29997](https://github.com/JuliaLang/julia/issues/29997)). * `copyto!(::AbstractMatrix, ::UniformScaling)` supports rectangular matrices now ([#28790](https://github.com/JuliaLang/julia/issues/28790)). * In `put!(c::Channel{T}, v)`, `v` now gets converted to `T` as `put!` is being called ([#29092](https://github.com/JuliaLang/julia/issues/29092)). * `current_project()` now searches the parent directories of a Git repository for a `Project.toml` file. This also affects the behavior of the `--project` command line option when using the default `--project=@.` ([#29108](https://github.com/JuliaLang/julia/issues/29108)). + * The `spawn` API is now more flexible and supports taking IOBuffer directly as a I/O stream, + converting to a system pipe as needed ([#30278](https://github.com/JuliaLang/julia/issues/30278)). #### Dates * New `DateTime(::Date, ::Time)` constructor ([#29754](https://github.com/JuliaLang/julia/issues/29754)). diff --git a/src/index.md b/src/index.md index d838fcf..556d9cd 100644 --- a/src/index.md +++ b/src/index.md @@ -19,16 +19,12 @@ import Markdown Markdown.parse(String(take!(io))) ``` -전체적으로 언어를 훑어보며, 0.6 버전 이후 어떤 것들이 바뀌었는지 -[블로그 글](https://julialang.org/blog/2018/08/one-point-zero)(번역 필요)을 읽어 주세요. -0.7 버전은 기존의 패키지와 코드를 업그레이드 하기 위해, 1.0 릴리즈와 같이 출시한 버전입니다. -0.7과 1.0의 차이는 지원 중단 경고문(deprecation warnings) 부분을 삭제한 것입니다. -0.6으로부터 바뀐 모든 내용은 [0.7 버전 릴리즈 노트](https://github.com/juliakorea/translate-doc/wiki/NEWS)를 봐 주세요. +[지난 릴리즈](https://github.com/juliakorea/translate-doc/wiki/NEWS)로부터 바뀐 점은 [릴리즈 노트](NEWS.md)에 있습니다. ` ` !!! note "번역 안내" - 한글 문서 번역은 깃헙 [https://github.com/juliakorea/translate-doc](https://github.com/juliakorea/translate-doc)에서 누구나 참여하실 수 있습니다. + 한글 문서 번역은 깃헙 [https://github.com/juliakorea/translate-doc](https://github.com/juliakorea/translate-doc) 에서 누구나 참여하실 수 있습니다. 많은 참여 부탁드립니다. ### [소개글](@id man-introduction) diff --git a/src/manual/arrays.md b/src/manual/arrays.md index bfb8f6e..fc0acf4 100644 --- a/src/manual/arrays.md +++ b/src/manual/arrays.md @@ -145,7 +145,7 @@ julia> [[1 2]; [3 4]] 특정 원소 타입의 배열은 `T[A, B, C, ...]` 문법을 통해 생성할 수 있다. 이는 원소 타입이 `T`인 일차원 배열을 생성하고, 원소 `A`, `B`, `C` 등을 담도록 초기화한다. -예를 들어 `Any[x, y, z]`는 어떤 값이든 가질 수 있는 배열을 생성한다. +예를 들어, `Any[x, y, z]`는 어떤 값이든 가질 수 있는 배열을 생성한다. 병합 구문 또한 비슷한 방법으로 원소 타입을 지정할 수 있다. @@ -277,7 +277,7 @@ X = A[I_1, I_2, ..., I_n] 만약 모든 인덱스가 스칼라라면, 결과 `X`는 배열 `A`의 원소 중 하나이다. 그렇지 않을 경우 `X`는 배열이며, 모든 인덱스의 차원 수의 합이 `X`의 차원수가 된다. -예를들어 만약 모든 인덱스가 벡터라면 `X`의 크기는 `(length(I_1), length(I_2), ..., length(I_n))`가 되고, `X`의 `(i_1, i_2, ..., i_n)` 위치는 `A[I_1[i_1], I_2[i_2], ..., I_n[i_n]]` 값을 가지게 된다. +예를 들어, 모든 인덱스 `I_k`가 벡터라면 `X`의 크기는 `(length(I_1), length(I_2), ..., length(I_n))`가 되고, `X`의 `i_1, i_2, ..., i_n` 위치는 `A[I_1[i_1], I_2[i_2], ..., I_n[i_n]]` 값을 가지게 된다. Example: @@ -345,9 +345,8 @@ julia> A[[1 2; 1 2], 1, 2, 1] 5 6 ``` -`X`의 `(i_1, i_2, i_3, ..., i_{n+1})` 위치는 `A[I_1[i_1, i_2], I_2[i_3], ..., I_n[i_{n+1}]]` 값을 가진다. -스칼라 인덱스를 가진 모든 차원은 결과에서 빠진다. -예를 들어, `A[2, I, 3]`의 결과는 크기가 `size(I)`인 배열이며, `i`번째 원소의 값은 `A[2, I[i], 3]`이다. +`X`의 `i_1, i_2, i_3, ..., i_{n+1}` 위치는 `A[I_1[i_1, i_2], I_2[i_3], ..., I_n[i_{n+1}]]` 값을 가진다. +스칼라(scalars)로 인덱스된 모든 차원은 결과에서 빠진다. 예를 들어, `J`가 인덱스들의 배열이면 `A[2, J, 3]`의 결과는 크기가 `size(J)`인 배열이며, `j`번째 원소의 값은 `A[2, J[j], 3]`이다. 인덱싱 문법의 특수한 한 부분으로서, 각 차원의 마지막 인덱스를 나타내기 위해서 인덱싱 괄호 안에서 `end` 키워드를 사용할 수 있다. 마지막 인덱스는 인덱싱 되는 가장 안쪽의 배열의 크기에 따라 결정된다. @@ -399,9 +398,17 @@ A[I_1, I_2, ..., I_n] = X 여기서 `I_k` 는 스칼라 정수, 정수의 배열, 혹은 [지원하는 다른 인덱스](@ref man-supported-index-types) 중 하나이다. 여기에는 모든 인덱스를 선택하는 [`Colon`](@ref) (`:`), 연속되거나 일정한 간격의 부분수열을 선택하는 `a:c` 혹은 `a:b:c`와 같은 형태의 범위, 그리고 `true` 값을 선택하는 부울 배열도 포함된다. -만약 `X`가 배열이라면, 그 원소의 갯수는 모든 인덱스 길이의 곱인 `prod(length(I_1), length(I_2), ..., length(I_n))`와 같아야 한다. -`A`의 `I_1[i_1], I_2[i_2], ..., I_n[i_n]` 위치에 있는 값은 `X[i_1, i_2, ..., i_n]` 값으로 덮어쓰인다. -만약 `X`가 스칼라(scala)면, `A`의 모든 위치에 `.=` (element-wise assignment operator)를 적용한다: +If all indices `I_k` are integers, then the value in location `I_1, I_2, ..., I_n` of `A` is +overwritten with the value of `X`, [`convert`](@ref)ing to the +[`eltype`](@ref) of `A` if necessary. + + +If any index `I_k` selects more than one location, then the right hand side `X` must be an +array with the same shape as the result of indexing `A[I_1, I_2, ..., I_n]` or a vector with +the same number of elements. The value in location `I_1[i_1], I_2[i_2], ..., I_n[i_n]` of +`A` is overwritten with the value `X[I_1, I_2, ..., I_n]`, converting if necessary. The +element-wise assignment operator `.=` may be used to [broadcast](@ref Broadcasting) `X` +across the selected locations: ``` A[I_1, I_2, ..., I_n] .= X diff --git a/src/manual/constructors.md b/src/manual/constructors.md index 9f41aca..6d64130 100644 --- a/src/manual/constructors.md +++ b/src/manual/constructors.md @@ -300,7 +300,7 @@ julia> Point{Int64}(1, 2) ## explicit T ## Point{Int64}(1, 2) julia> Point{Int64}(1.0,2.5) ## explicit T ## -ERROR: InexactError: Int64(Int64, 2.5) +ERROR: InexactError: Int64(2.5) Stacktrace: [...] diff --git a/src/manual/getting-started.md b/src/manual/getting-started.md index 8248cec..c475917 100644 --- a/src/manual/getting-started.md +++ b/src/manual/getting-started.md @@ -105,6 +105,11 @@ julia [switches] -- [programfile] [args...] |`--track-allocation={none\|user\|all}` |각 소스 코드 라인에 의해 할당되는 바이트 수를 기록한다| |`--track-allocation` |`--track-allocation=user`와 같다| +!!! compat "Julia 1.1" + In Julia 1.0, the default `--project=@.` option did not search up from the root + directory of a Git repository for the `Project.toml` file. From Julia 1.1 forward, it + does. + ## 참고 자료 줄리아 웹사이트의 [배우기](https://juliakorea.github.io/learning/) 페이지에 사용자가 보면 유용한 자료를 엄선하여 모아두었다. diff --git a/src/manual/mathematical-operations.md b/src/manual/mathematical-operations.md index 6d451ea..6ba2588 100644 --- a/src/manual/mathematical-operations.md +++ b/src/manual/mathematical-operations.md @@ -432,12 +432,12 @@ julia> Int8(127.0) 127 julia> Int8(3.14) -ERROR: InexactError: Int8(Int8, 3.14) +ERROR: InexactError: Int8(3.14) Stacktrace: [...] julia> Int8(128.0) -ERROR: InexactError: Int8(Int8, 128.0) +ERROR: InexactError: Int8(128.0) Stacktrace: [...] diff --git a/src/manual/types.md b/src/manual/types.md index cd0fdd0..c219f37 100644 --- a/src/manual/types.md +++ b/src/manual/types.md @@ -344,7 +344,7 @@ must be convertible to `Int`: ```jldoctest footype julia> Foo((), 23.5, 1) -ERROR: InexactError: Int64(Int64, 23.5) +ERROR: InexactError: Int64(23.5) Stacktrace: [...] ``` From 6b3c3368e6d9ff2dcb6ce54aac75969fe1f28b20 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Sun, 9 Dec 2018 21:02:10 +0900 Subject: [PATCH 082/153] update Julia Commit 1bd316b972 --- codex/NEWS.md | 4 +++- codex/manual/control-flow.md | 2 +- codex/manual/stacktraces.md | 6 +++--- src/NEWS.md | 4 +++- src/manual/control-flow.md | 2 +- src/manual/stacktraces.md | 6 +++--- 6 files changed, 14 insertions(+), 10 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index 721d9ea..be0537f 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -4,7 +4,9 @@ Julia v1.1 Release Notes New language features --------------------- - * An *exception stack* is maintained on each task to make exception handling more robust and enable root cause analysis using `catch_stack` ([#28878](https://github.com/JuliaLang/julia/issues/28878)). + * An *exception stack* is maintained on each task to make exception handling + more robust and enable root cause analysis. The stack may be accessed using + the experimental function `Base.catch_stack` ([#28878](https://github.com/JuliaLang/julia/issues/28878)). * The experimental macro `Base.@locals` returns a dictionary of current local variable names and values ([#29733](https://github.com/JuliaLang/julia/issues/29733)). diff --git a/codex/manual/control-flow.md b/codex/manual/control-flow.md index 9de3b82..6d4cf72 100644 --- a/codex/manual/control-flow.md +++ b/codex/manual/control-flow.md @@ -794,7 +794,7 @@ The power of the `try/catch` construct lies in the ability to unwind a deeply ne immediately to a much higher level in the stack of calling functions. There are situations where no error has occurred, but the ability to unwind the stack and pass a value to a higher level is desirable. Julia provides the [`rethrow`](@ref), [`backtrace`](@ref), [`catch_backtrace`](@ref) -and [`catch_stack`](@ref) functions for more advanced error handling. +and [`Base.catch_stack`](@ref) functions for more advanced error handling. ### `finally` Clauses diff --git a/codex/manual/stacktraces.md b/codex/manual/stacktraces.md index 01a3417..8deff08 100644 --- a/codex/manual/stacktraces.md +++ b/codex/manual/stacktraces.md @@ -187,7 +187,7 @@ ERROR: Whoops! [...] ``` -## Exception stacks and [`catch_stack`](@ref) +## Exception stacks and `catch_stack` !!! compat "Julia 1.1" Exception stacks requires at least Julia 1.1. @@ -197,7 +197,7 @@ identify the root cause of a problem. The julia runtime supports this by pushing *exception stack* as it occurs. When the code exits a `catch` normally, any exceptions which were pushed onto the stack in the associated `try` are considered to be successfully handled and are removed from the stack. -The stack of current exceptions can be accessed using the [`catch_stack`](@ref) function. For example, +The stack of current exceptions can be accessed using the experimental [`Base.catch_stack`](@ref) function. For example, ```julia-repl julia> try @@ -206,7 +206,7 @@ julia> try try error("(B) An exception while handling the exception") catch - for (exc, bt) in catch_stack() + for (exc, bt) in Base.catch_stack() showerror(stdout, exc, bt) println() end diff --git a/src/NEWS.md b/src/NEWS.md index 721d9ea..be0537f 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -4,7 +4,9 @@ Julia v1.1 Release Notes New language features --------------------- - * An *exception stack* is maintained on each task to make exception handling more robust and enable root cause analysis using `catch_stack` ([#28878](https://github.com/JuliaLang/julia/issues/28878)). + * An *exception stack* is maintained on each task to make exception handling + more robust and enable root cause analysis. The stack may be accessed using + the experimental function `Base.catch_stack` ([#28878](https://github.com/JuliaLang/julia/issues/28878)). * The experimental macro `Base.@locals` returns a dictionary of current local variable names and values ([#29733](https://github.com/JuliaLang/julia/issues/29733)). diff --git a/src/manual/control-flow.md b/src/manual/control-flow.md index 335bf83..d1df619 100644 --- a/src/manual/control-flow.md +++ b/src/manual/control-flow.md @@ -692,7 +692,7 @@ catch end ``` -`try/catch`문의 장점은 호출 함수의 스택에서 훨씬 더 높은 레벨로 깊게 중첩된 계산을 즉시 풀 수 있는 능력에 있습니다. 오류가 발생하지 않은 상황이 있지만 스택을 풀어 더 높은 레벨로 값을 전달하는 것이 바람직합니다. Julia는 고급 오류 처리를 위해 `rethrow`, `backtrace`, `catch_backtrace` 그리고 [`catch_stack`](@ref)와 같은 함수들을 제공합니다. +`try/catch`문의 장점은 호출 함수의 스택에서 훨씬 더 높은 레벨로 깊게 중첩된 계산을 즉시 풀 수 있는 능력에 있습니다. 오류가 발생하지 않은 상황이 있지만 스택을 풀어 더 높은 레벨로 값을 전달하는 것이 바람직합니다. Julia는 고급 오류 처리를 위해 `rethrow`, `backtrace`, `catch_backtrace` 그리고 [`Base.catch_stack`](@ref)와 같은 함수들을 제공합니다. ### `finally`문 diff --git a/src/manual/stacktraces.md b/src/manual/stacktraces.md index 01a3417..8deff08 100644 --- a/src/manual/stacktraces.md +++ b/src/manual/stacktraces.md @@ -187,7 +187,7 @@ ERROR: Whoops! [...] ``` -## Exception stacks and [`catch_stack`](@ref) +## Exception stacks and `catch_stack` !!! compat "Julia 1.1" Exception stacks requires at least Julia 1.1. @@ -197,7 +197,7 @@ identify the root cause of a problem. The julia runtime supports this by pushing *exception stack* as it occurs. When the code exits a `catch` normally, any exceptions which were pushed onto the stack in the associated `try` are considered to be successfully handled and are removed from the stack. -The stack of current exceptions can be accessed using the [`catch_stack`](@ref) function. For example, +The stack of current exceptions can be accessed using the experimental [`Base.catch_stack`](@ref) function. For example, ```julia-repl julia> try @@ -206,7 +206,7 @@ julia> try try error("(B) An exception while handling the exception") catch - for (exc, bt) in catch_stack() + for (exc, bt) in Base.catch_stack() showerror(stdout, exc, bt) println() end From a0bae98e9515eebe9102592b703578310f1d6724 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Mon, 10 Dec 2018 18:16:28 +0900 Subject: [PATCH 083/153] update Julia Commit 0a401f2b5d --- codex/NEWS.md | 35 +++++++++++++++++------------------ src/NEWS.md | 35 +++++++++++++++++------------------ 2 files changed, 34 insertions(+), 36 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index be0537f..f791e75 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -1,5 +1,5 @@ Julia v1.1 Release Notes -========================== +======================== New language features --------------------- @@ -27,13 +27,14 @@ Language changes the old behavior, or `CartesianIndices(a)[findall(in(b), a)]` to get the new behavior on previous Julia versions ([#30226](https://github.com/JuliaLang/julia/issues/30226)). * `findmin(::BitArray)` and `findmax(::BitArray)` now return a `CartesianIndex` when `a` is a matrix - or a higher-dimensional array, for consistency with for other array types. + or a higher-dimensional array, for consistency with other array types. Use `LinearIndices(a)[findmin(a)[2]]` to get the old behavior, or `CartesianIndices(a)[findmin(a)[2]]` to get the new behavior on previous Julia versions ([#30102](https://github.com/JuliaLang/julia/issues/30102)). * Method signatures such as `f(::Type{T}, ::T) where {T <: X}` and `f(::Type{X}, ::Any)` - are now considered ambiguous. Previously a bug caused the first one to be considered more specific ([#30160](https://github.com/JuliaLang/julia/issues/30160)). + are now considered ambiguous. Previously a bug caused the first one to be considered more specific in + some cases ([#30160](https://github.com/JuliaLang/julia/issues/30160)). Command-line option changes --------------------------- @@ -45,13 +46,14 @@ Command-line option changes New library functions --------------------- - * `splitpath(p::String)` function, which is the opposite of `joinpath(parts...)`: it splits a filepath into its components ([#28156](https://github.com/JuliaLang/julia/issues/28156)). - * `isnothing(::Any)` function, to check whether something is a `Nothing`, returns a `Bool` ([#29679](https://github.com/JuliaLang/julia/issues/29679)). + * `splitpath(p::String)` function, which is the opposite of `joinpath(parts...)`: it splits a filepath + into its components ([#28156](https://github.com/JuliaLang/julia/issues/28156)). + * `isnothing(::Any)` predicate, to check whether the argument is `nothing`. ([#29679](https://github.com/JuliaLang/julia/issues/29679)). * `getpid(::Process)` method ([#24064](https://github.com/JuliaLang/julia/issues/24064)). * `eachrow`, `eachcol` and `eachslice` functions provide efficient iterators over slices of arrays ([#29749](https://github.com/JuliaLang/julia/issues/29749)). - * `fieldtypes(T::Type)` which return the declared types of the field in type T ([#29600](https://github.com/JuliaLang/julia/issues/29600)). + * `fieldtypes(T::Type)` which returns the declared types of the field in type T ([#29600](https://github.com/JuliaLang/julia/issues/29600)). * `uuid5` has been added to the `UUIDs` standard library ([#28761](https://github.com/JuliaLang/julia/issues/28761)). - * Predicate functions `Sys.isfreebsd`, `Sys.isopenbsd`, `Sys.isnetbsd`, and `Sys.isdragonfly` for + * Predicates `Sys.isfreebsd`, `Sys.isopenbsd`, `Sys.isnetbsd`, and `Sys.isdragonfly` for detecting BSD systems have been added ([#30249](https://github.com/JuliaLang/julia/issues/30249)). * Internal `Base.disable_library_threading` that sets libraries to use one thread. It executes function hooks that have been registered with @@ -72,7 +74,7 @@ Standard library changes argument ([#29157](https://github.com/JuliaLang/julia/issues/29157)). * The use of scientific notation when printing `BigFloat` values is now consistent with other floating point types ([#29211](https://github.com/JuliaLang/julia/issues/29211)). - * `Regex` now behave like a scalar when used in broadcasting ([#29913](https://github.com/JuliaLang/julia/issues/29913)). + * `Regex` now behaves like a scalar when used in broadcasting ([#29913](https://github.com/JuliaLang/julia/issues/29913)). * `Char` now behaves like a read-only 0-dimensional array ([#29819](https://github.com/JuliaLang/julia/issues/29819)). * `parse` now allows strings representing integer 0 and 1 for type `Bool` ([#29980](https://github.com/JuliaLang/julia/issues/29980)). * `Base.tail` now works on named tuples ([#29595](https://github.com/JuliaLang/julia/issues/29595)). @@ -81,24 +83,21 @@ Standard library changes * `Base.julia_cmd` now propagates the `--inline=(yes|no)` flag ([#29858](https://github.com/JuliaLang/julia/issues/29858)). * `Base.@kwdef` can now be used for parametric structs, and for structs with supertypes ([#29316](https://github.com/JuliaLang/julia/issues/29316)). * `merge(::NamedTuple, ::NamedTuple...)` can now be used with more than 2 `NamedTuple`s ([#29259](https://github.com/JuliaLang/julia/issues/29259)). - * `Future.copy!` has been moved to `Base` ([#29178](https://github.com/JuliaLang/julia/issues/29178)). * New `ncodeunits(c::Char)` method as a fast equivalent to `ncodeunits(string(c))` ([#29153](https://github.com/JuliaLang/julia/issues/29153)). * New `sort!(::AbstractArray; dims)` method that can sort the array along the `dims` dimension ([#28902](https://github.com/JuliaLang/julia/issues/28902)). - * `range` now accept `stop` as a positional argument ([#28708](https://github.com/JuliaLang/julia/issues/28708)). - * `get(A::AbstractArray, (), default)` now returns the result of `A[]` if it can instead of always - returning an empty array ([#30270](https://github.com/JuliaLang/julia/issues/30270)). + * `range` now accepts `stop` as a positional argument ([#28708](https://github.com/JuliaLang/julia/issues/28708)). + * `get(A::AbstractArray, (), default)` now returns `A[]` instead of an empty array ([#30270](https://github.com/JuliaLang/julia/issues/30270)). * `parse(Bool, str)` is now supported ([#29997](https://github.com/JuliaLang/julia/issues/29997)). - * `copyto!(::AbstractMatrix, ::UniformScaling)` supports rectangular matrices now ([#28790](https://github.com/JuliaLang/julia/issues/28790)). - * In `put!(c::Channel{T}, v)`, `v` now gets converted to `T` as `put!` is being called ([#29092](https://github.com/JuliaLang/julia/issues/29092)). + * `copyto!(::AbstractMatrix, ::UniformScaling)` now supports rectangular matrices ([#28790](https://github.com/JuliaLang/julia/issues/28790)). * `current_project()` now searches the parent directories of a Git repository for a `Project.toml` file. This also affects the behavior of the `--project` command line option when using the default `--project=@.` ([#29108](https://github.com/JuliaLang/julia/issues/29108)). - * The `spawn` API is now more flexible and supports taking IOBuffer directly as a I/O stream, + * The `spawn` API is now more flexible and supports taking IOBuffer directly as an I/O stream, converting to a system pipe as needed ([#30278](https://github.com/JuliaLang/julia/issues/30278)). #### Dates * New `DateTime(::Date, ::Time)` constructor ([#29754](https://github.com/JuliaLang/julia/issues/29754)). - * `TimeZone` now behave like a scalar when used in broadcasting ([#30159](https://github.com/JuliaLang/julia/issues/30159)). + * `TimeZone` now behaves like a scalar when used in broadcasting ([#30159](https://github.com/JuliaLang/julia/issues/30159)). #### InteractiveUtils * `edit` can now be called on a module to edit the file that defines it ([#29636](https://github.com/JuliaLang/julia/issues/29636)). @@ -110,7 +109,7 @@ Standard library changes * `isdiag` and `isposdef` for `Diagonal` and `UniformScaling` ([#29638](https://github.com/JuliaLang/julia/issues/29638)). * `mul!`, `rmul!` and `lmul!` methods for `UniformScaling` ([#29506](https://github.com/JuliaLang/julia/issues/29506)). * `Symmetric` and `Hermitian` matrices now preserve the wrapper when scaled with a number ([#29469](https://github.com/JuliaLang/julia/issues/29469)). - * Exponentiation operator `^` now supports raising a `Irrational` to an `AbstractMatrix` power ([#29782](https://github.com/JuliaLang/julia/issues/29782)). + * Exponentiation operator `^` now supports raising an `Irrational` to an `AbstractMatrix` power ([#29782](https://github.com/JuliaLang/julia/issues/29782)). #### Random * `randperm` and `randcycle` now use the type of their argument to determine the element type of @@ -122,7 +121,7 @@ Standard library changes * `sprandn` now supports specifying the output element type ([#30083](https://github.com/JuliaLang/julia/issues/30083)). #### Statistics - * `mean` and `var` now handles the empty case ([#29033](https://github.com/JuliaLang/julia/issues/29033)). + * `mean` and `var` now handle more kinds of empty inputs ([#29033](https://github.com/JuliaLang/julia/issues/29033)). External dependencies --------------------- diff --git a/src/NEWS.md b/src/NEWS.md index be0537f..f791e75 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -1,5 +1,5 @@ Julia v1.1 Release Notes -========================== +======================== New language features --------------------- @@ -27,13 +27,14 @@ Language changes the old behavior, or `CartesianIndices(a)[findall(in(b), a)]` to get the new behavior on previous Julia versions ([#30226](https://github.com/JuliaLang/julia/issues/30226)). * `findmin(::BitArray)` and `findmax(::BitArray)` now return a `CartesianIndex` when `a` is a matrix - or a higher-dimensional array, for consistency with for other array types. + or a higher-dimensional array, for consistency with other array types. Use `LinearIndices(a)[findmin(a)[2]]` to get the old behavior, or `CartesianIndices(a)[findmin(a)[2]]` to get the new behavior on previous Julia versions ([#30102](https://github.com/JuliaLang/julia/issues/30102)). * Method signatures such as `f(::Type{T}, ::T) where {T <: X}` and `f(::Type{X}, ::Any)` - are now considered ambiguous. Previously a bug caused the first one to be considered more specific ([#30160](https://github.com/JuliaLang/julia/issues/30160)). + are now considered ambiguous. Previously a bug caused the first one to be considered more specific in + some cases ([#30160](https://github.com/JuliaLang/julia/issues/30160)). Command-line option changes --------------------------- @@ -45,13 +46,14 @@ Command-line option changes New library functions --------------------- - * `splitpath(p::String)` function, which is the opposite of `joinpath(parts...)`: it splits a filepath into its components ([#28156](https://github.com/JuliaLang/julia/issues/28156)). - * `isnothing(::Any)` function, to check whether something is a `Nothing`, returns a `Bool` ([#29679](https://github.com/JuliaLang/julia/issues/29679)). + * `splitpath(p::String)` function, which is the opposite of `joinpath(parts...)`: it splits a filepath + into its components ([#28156](https://github.com/JuliaLang/julia/issues/28156)). + * `isnothing(::Any)` predicate, to check whether the argument is `nothing`. ([#29679](https://github.com/JuliaLang/julia/issues/29679)). * `getpid(::Process)` method ([#24064](https://github.com/JuliaLang/julia/issues/24064)). * `eachrow`, `eachcol` and `eachslice` functions provide efficient iterators over slices of arrays ([#29749](https://github.com/JuliaLang/julia/issues/29749)). - * `fieldtypes(T::Type)` which return the declared types of the field in type T ([#29600](https://github.com/JuliaLang/julia/issues/29600)). + * `fieldtypes(T::Type)` which returns the declared types of the field in type T ([#29600](https://github.com/JuliaLang/julia/issues/29600)). * `uuid5` has been added to the `UUIDs` standard library ([#28761](https://github.com/JuliaLang/julia/issues/28761)). - * Predicate functions `Sys.isfreebsd`, `Sys.isopenbsd`, `Sys.isnetbsd`, and `Sys.isdragonfly` for + * Predicates `Sys.isfreebsd`, `Sys.isopenbsd`, `Sys.isnetbsd`, and `Sys.isdragonfly` for detecting BSD systems have been added ([#30249](https://github.com/JuliaLang/julia/issues/30249)). * Internal `Base.disable_library_threading` that sets libraries to use one thread. It executes function hooks that have been registered with @@ -72,7 +74,7 @@ Standard library changes argument ([#29157](https://github.com/JuliaLang/julia/issues/29157)). * The use of scientific notation when printing `BigFloat` values is now consistent with other floating point types ([#29211](https://github.com/JuliaLang/julia/issues/29211)). - * `Regex` now behave like a scalar when used in broadcasting ([#29913](https://github.com/JuliaLang/julia/issues/29913)). + * `Regex` now behaves like a scalar when used in broadcasting ([#29913](https://github.com/JuliaLang/julia/issues/29913)). * `Char` now behaves like a read-only 0-dimensional array ([#29819](https://github.com/JuliaLang/julia/issues/29819)). * `parse` now allows strings representing integer 0 and 1 for type `Bool` ([#29980](https://github.com/JuliaLang/julia/issues/29980)). * `Base.tail` now works on named tuples ([#29595](https://github.com/JuliaLang/julia/issues/29595)). @@ -81,24 +83,21 @@ Standard library changes * `Base.julia_cmd` now propagates the `--inline=(yes|no)` flag ([#29858](https://github.com/JuliaLang/julia/issues/29858)). * `Base.@kwdef` can now be used for parametric structs, and for structs with supertypes ([#29316](https://github.com/JuliaLang/julia/issues/29316)). * `merge(::NamedTuple, ::NamedTuple...)` can now be used with more than 2 `NamedTuple`s ([#29259](https://github.com/JuliaLang/julia/issues/29259)). - * `Future.copy!` has been moved to `Base` ([#29178](https://github.com/JuliaLang/julia/issues/29178)). * New `ncodeunits(c::Char)` method as a fast equivalent to `ncodeunits(string(c))` ([#29153](https://github.com/JuliaLang/julia/issues/29153)). * New `sort!(::AbstractArray; dims)` method that can sort the array along the `dims` dimension ([#28902](https://github.com/JuliaLang/julia/issues/28902)). - * `range` now accept `stop` as a positional argument ([#28708](https://github.com/JuliaLang/julia/issues/28708)). - * `get(A::AbstractArray, (), default)` now returns the result of `A[]` if it can instead of always - returning an empty array ([#30270](https://github.com/JuliaLang/julia/issues/30270)). + * `range` now accepts `stop` as a positional argument ([#28708](https://github.com/JuliaLang/julia/issues/28708)). + * `get(A::AbstractArray, (), default)` now returns `A[]` instead of an empty array ([#30270](https://github.com/JuliaLang/julia/issues/30270)). * `parse(Bool, str)` is now supported ([#29997](https://github.com/JuliaLang/julia/issues/29997)). - * `copyto!(::AbstractMatrix, ::UniformScaling)` supports rectangular matrices now ([#28790](https://github.com/JuliaLang/julia/issues/28790)). - * In `put!(c::Channel{T}, v)`, `v` now gets converted to `T` as `put!` is being called ([#29092](https://github.com/JuliaLang/julia/issues/29092)). + * `copyto!(::AbstractMatrix, ::UniformScaling)` now supports rectangular matrices ([#28790](https://github.com/JuliaLang/julia/issues/28790)). * `current_project()` now searches the parent directories of a Git repository for a `Project.toml` file. This also affects the behavior of the `--project` command line option when using the default `--project=@.` ([#29108](https://github.com/JuliaLang/julia/issues/29108)). - * The `spawn` API is now more flexible and supports taking IOBuffer directly as a I/O stream, + * The `spawn` API is now more flexible and supports taking IOBuffer directly as an I/O stream, converting to a system pipe as needed ([#30278](https://github.com/JuliaLang/julia/issues/30278)). #### Dates * New `DateTime(::Date, ::Time)` constructor ([#29754](https://github.com/JuliaLang/julia/issues/29754)). - * `TimeZone` now behave like a scalar when used in broadcasting ([#30159](https://github.com/JuliaLang/julia/issues/30159)). + * `TimeZone` now behaves like a scalar when used in broadcasting ([#30159](https://github.com/JuliaLang/julia/issues/30159)). #### InteractiveUtils * `edit` can now be called on a module to edit the file that defines it ([#29636](https://github.com/JuliaLang/julia/issues/29636)). @@ -110,7 +109,7 @@ Standard library changes * `isdiag` and `isposdef` for `Diagonal` and `UniformScaling` ([#29638](https://github.com/JuliaLang/julia/issues/29638)). * `mul!`, `rmul!` and `lmul!` methods for `UniformScaling` ([#29506](https://github.com/JuliaLang/julia/issues/29506)). * `Symmetric` and `Hermitian` matrices now preserve the wrapper when scaled with a number ([#29469](https://github.com/JuliaLang/julia/issues/29469)). - * Exponentiation operator `^` now supports raising a `Irrational` to an `AbstractMatrix` power ([#29782](https://github.com/JuliaLang/julia/issues/29782)). + * Exponentiation operator `^` now supports raising an `Irrational` to an `AbstractMatrix` power ([#29782](https://github.com/JuliaLang/julia/issues/29782)). #### Random * `randperm` and `randcycle` now use the type of their argument to determine the element type of @@ -122,7 +121,7 @@ Standard library changes * `sprandn` now supports specifying the output element type ([#30083](https://github.com/JuliaLang/julia/issues/30083)). #### Statistics - * `mean` and `var` now handles the empty case ([#29033](https://github.com/JuliaLang/julia/issues/29033)). + * `mean` and `var` now handle more kinds of empty inputs ([#29033](https://github.com/JuliaLang/julia/issues/29033)). External dependencies --------------------- From 256f08b8ab23ae132eb12f6882cc69ab6ed0c975 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Wed, 12 Dec 2018 06:13:32 +0900 Subject: [PATCH 084/153] update Julia Commit 560e82906d --- codex/NEWS.md | 2 + codex/devdocs/sysimg.md | 24 +--- codex/manual/parallel-computing.md | 90 +++++++++++++ codex/manual/workflow-tips.md | 106 +++++++-------- contrib/build_sysimg.jl | 210 ----------------------------- make.jl | 7 +- src/NEWS.md | 2 + src/devdocs/sysimg.md | 24 +--- src/manual/parallel-computing.md | 90 +++++++++++++ src/manual/workflow-tips.md | 106 +++++++-------- 10 files changed, 279 insertions(+), 382 deletions(-) delete mode 100644 contrib/build_sysimg.jl diff --git a/codex/NEWS.md b/codex/NEWS.md index f791e75..91e0e5d 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -110,6 +110,7 @@ Standard library changes * `mul!`, `rmul!` and `lmul!` methods for `UniformScaling` ([#29506](https://github.com/JuliaLang/julia/issues/29506)). * `Symmetric` and `Hermitian` matrices now preserve the wrapper when scaled with a number ([#29469](https://github.com/JuliaLang/julia/issues/29469)). * Exponentiation operator `^` now supports raising an `Irrational` to an `AbstractMatrix` power ([#29782](https://github.com/JuliaLang/julia/issues/29782)). + * Added keyword arguments `rtol`, `atol` to `pinv`, `nullspace` and `rank` ([#29998](https://github.com/JuliaLang/julia/issues/29998), [#29926](https://github.com/JuliaLang/julia/issues/29926)). #### Random * `randperm` and `randcycle` now use the type of their argument to determine the element type of @@ -132,6 +133,7 @@ External dependencies * The source code for Pkg is no longer included in JuliaLang/julia. Pkg is instead downloaded during the build process ([#29615](https://github.com/JuliaLang/julia/issues/29615)). * LLVM has been upgraded to 6.0.1 and support for LLVM < 6.0 has been dropped ([#28745](https://github.com/JuliaLang/julia/issues/28745), [#28696](https://github.com/JuliaLang/julia/issues/28696)). + * Pkg has been upgraded to version 1.1 ([#30342](https://github.com/JuliaLang/julia/issues/30342)). Deprecated or removed --------------------- diff --git a/codex/devdocs/sysimg.md b/codex/devdocs/sysimg.md index 6c12278..a354a5f 100644 --- a/codex/devdocs/sysimg.md +++ b/codex/devdocs/sysimg.md @@ -16,28 +16,8 @@ This operation is useful for multiple reasons. A user may: * Include a `userimg.jl` file that includes packages into the system image, thereby creating a system image that has packages embedded into the startup environment. -Julia now ships with a script that automates the tasks of building the system image, wittingly -named `build_sysimg.jl` that lives in `DATAROOTDIR/julia/`. That is, to include it into a current -Julia session, type: - -```julia -include(joinpath(Sys.BINDIR, Base.DATAROOTDIR, "julia", "build_sysimg.jl")) -``` - -This will include a `build_sysimg` function: - -```@docs -BuildSysImg.build_sysimg -``` - -Note that this file can also be run as a script itself, with command line arguments taking the -place of arguments passed to the `build_sysimg` function. For example, to build a system image -in `/tmp/sys.{so,dll,dylib}`, with the `core2` CPU instruction set, a user image of `~/userimg.jl` -and `force` set to `true`, one would execute: - -``` -julia build_sysimg.jl /tmp/sys core2 ~/userimg.jl --force -``` +The [`PackageCompiler.jl` package](https://github.com/JuliaLang/PackageCompiler.jl) contains convenient +wrapper functions to automate this process. ## System image optimized for multiple microarchitectures diff --git a/codex/manual/parallel-computing.md b/codex/manual/parallel-computing.md index ab7052f..80e513b 100644 --- a/codex/manual/parallel-computing.md +++ b/codex/manual/parallel-computing.md @@ -1142,6 +1142,96 @@ sent to the remote node to go ahead and remove its reference to the value. Once finalized, a reference becomes invalid and cannot be used in any further calls. + +## Local invocations(@id man-distributed-local-invocations) + +Data is necessarily copied over to the remote node for execution. This is the case for both +remotecalls and when data is stored to a[`RemoteChannel`](@ref) / [`Future`](@ref) on +a different node. As expected, this results in a copy of the serialized objects +on the remote node. However, when the destination node is the local node, i.e. +the calling process id is the same as the remote node id, it is executed +as a local call. It is usually(not always) executed in a different task - but there is no +serialization/deserialization of data. Consequently, the call refers to the same object instances +as passed - no copies are created. This behavior is highlighted below: + +```julia-repl +julia> using Distributed; + +julia> rc = RemoteChannel(()->Channel(3)); # RemoteChannel created on local node + +julia> v = [0]; + +julia> for i in 1:3 + v[1] = i # Reusing `v` + put!(rc, v) + end; + +julia> result = [take!(rc) for _ in 1:3]; + +julia> println(result); +Array{Int64,1}[[3], [3], [3]] + +julia> println("Num Unique objects : ", length(unique(map(objectid, result)))); +Num Unique objects : 1 + +julia> addprocs(1); + +julia> rc = RemoteChannel(()->Channel(3), workers()[1]); # RemoteChannel created on remote node + +julia> v = [0]; + +julia> for i in 1:3 + v[1] = i + put!(rc, v) + end; + +julia> result = [take!(rc) for _ in 1:3]; + +julia> println(result); +Array{Int64,1}[[1], [2], [3]] + +julia> println("Num Unique objects : ", length(unique(map(objectid, result)))); +Num Unique objects : 3 +``` + +As can be seen, [`put!`](@ref) on a locally owned [`RemoteChannel`](@ref) with the same +object `v` modifed between calls results in the same single object instance stored. As +opposed to copies of `v` being created when the node owning `rc` is a different node. + +It is to be noted that this is generally not an issue. It is something to be factored in only +if the object is both being stored locally and modifed post the call. In such cases it may be +appropriate to store a `deepcopy` of the object. + +This is also true for remotecalls on the local node as seen in the following example: + +```julia-repl +julia> using Distributed; addprocs(1); + +julia> v = [0]; + +julia> v2 = remotecall_fetch(x->(x[1] = 1; x), myid(), v); # Executed on local node + +julia> println("v=$v, v2=$v2, ", v === v2); +v=[1], v2=[1], true + +julia> v = [0]; + +julia> v2 = remotecall_fetch(x->(x[1] = 1; x), workers()[1], v); # Executed on remote node + +julia> println("v=$v, v2=$v2, ", v === v2); +v=[0], v2=[1], false +``` + +As can be seen once again, a remote call onto the local node behaves just like a direct invocation. +The call modifies local objects passed as arguments. In the remote invocation, it operates on +a copy of the arguments. + +To repeat, in general this is not an issue. If the local node is also being used as a compute +node, and the arguments used post the call, this behavior needs to be factored in and if required +deep copies of arguments must be passed to the call invoked on the local node. Calls on remote nodes +will always operate on copies of arguments. + + ## [Shared Arrays](@id man-shared-arrays) Shared Arrays use system shared memory to map the same array across many processes. While there diff --git a/codex/manual/workflow-tips.md b/codex/manual/workflow-tips.md index 8cae4ce..cdc74a4 100644 --- a/codex/manual/workflow-tips.md +++ b/codex/manual/workflow-tips.md @@ -8,75 +8,59 @@ As already elaborated in [The Julia REPL](@ref), Julia's REPL provides rich func that facilitates an efficient interactive workflow. Here are some tips that might further enhance your experience at the command line. -## Command-line-based basic editor/REPL workflow +### A basic editor/REPL workflow The most basic Julia workflows involve using a text editor in conjunction with the `julia` command line. A common pattern includes the following elements: - * **Generate a new project** - - ``` - $ julia -e 'using Pkg;Pkg.generate("Tmp")' -Generating project Tmp: - Tmp/Project.toml - Tmp/src/Tmp.jl - $ ls -R Tmp -Tmp: -Project.toml src - -Tmp/src: -Tmp.jl - $ cat -n Tmp/src/Tmp.jl - 1 module Tmp - 2 - 3 greet() = print("Hello World!") - 4 - 5 end # module - ``` - - * **Create a test folder** - ``` - $ mkdir Tmp/test - ``` - * **Put your test code in `test/runtests.jl` file.** + * **Put code under development in a temporary module.** Create a file, say `Tmp.jl`, and include + within it + ```julia + module Tmp + export say_hello + + say_hello() = println("Hello!") + + # your other definitions here + + end ``` - $ cat -n Tmp/test/runtests.jl - 1 using Tmp - 2 Tmp.greet() + * **Put your test code in another file.** Create another file, say `tst.jl`, which looks like + + ```julia + include("Tmp.jl") + import .Tmp + # using .Tmp # we can use `using` to bring the exported symbols in `Tmp` into our namespace + + Tmp.say_hello() + # say_hello() + + # your other test code here ``` - * **Run test** - ``` - $ julia -e 'using Pkg;Pkg.activate("Tmp");Pkg.test()' - Updating registry at `~/.julia/registries/General` - Updating git-repo `https://github.com/JuliaRegistries/General.git` - Resolving package versions... - Updating `~/Tmp/Project.toml` - [no changes] - Testing Tmp - Resolving package versions... -Hello World! Testing Tmp tests passed - ``` - * **Lather. Rinse. Repeat.** Explore ideas at the `julia` command prompt. Save good ideas in `Tmp.jl` and test with `runtests.jl`. - -## Simplify initialization - -To simplify restarting the REPL, put project-specific initialization code in a file, say `_init.jl`, -which you can run on startup by issuing the command: - -``` -julia -L _init.jl -``` - -If you further add the following to your `~/.julia/config/startup.jl` file - -```julia -isfile("_init.jl") && include(joinpath(pwd(), "_init.jl")) -``` - -then calling `julia` from that directory will run the initialization code without the additional -command line argument. + and includes tests for the contents of `Tmp`. + Alternatively, you can wrap the contents of your test file in a module, as + + ```julia + module Tst + include("Tmp.jl") + import .Tmp + #using .Tmp + + Tmp.say_hello() + # say_hello() + + # your other test code here + end + ``` + + The advantage is that your testing code is now contained in a module and does not use the global scope in `Main` for + definitions, which is a bit more tidy. + + * `include` the `tst.jl` file in the Julia REPL with `include("tst.jl")`. + + * **Lather. Rinse. Repeat.** Explore ideas at the `julia` command prompt. Save good ideas in `tst.jl`. To execute `tst.jl` after it has been changed, just `include` it again. ## Browser-based workflow diff --git a/contrib/build_sysimg.jl b/contrib/build_sysimg.jl deleted file mode 100644 index 2d7f13d..0000000 --- a/contrib/build_sysimg.jl +++ /dev/null @@ -1,210 +0,0 @@ -#!/usr/bin/env julia -# This file is a part of Julia. License is MIT: https://julialang.org/license - -# Build a system image binary at sysimg_path.dlext. Allow insertion of a userimg via -# userimg_path. If sysimg_path.dlext is currently loaded into memory, don't continue -# unless force is set to true. Allow targeting of a CPU architecture via cpu_target. -function default_sysimg_path(debug=false) - if Sys.isunix() - splitext(Libdl.dlpath(debug ? "sys-debug" : "sys"))[1] - else - joinpath(dirname(JULIA_HOME), "lib", "julia", debug ? "sys-debug" : "sys") - end -end - -""" - build_sysimg(sysimg_path=default_sysimg_path(), cpu_target="native", userimg_path=nothing; force=false) - -Rebuild the system image. Store it in `sysimg_path`, which defaults to a file named `sys.ji` -that sits in the same folder as `libjulia.{so,dylib}`, except on Windows where it defaults -to `JULIA_HOME/../lib/julia/sys.ji`. Use the cpu instruction set given by `cpu_target`. -Valid CPU targets are the same as for the `-C` option to `julia`, or the `-march` option to -`gcc`. Defaults to `native`, which means to use all CPU instructions available on the -current processor. Include the user image file given by `userimg_path`, which should contain -directives such as `using MyPackage` to include that package in the new system image. New -system image will not replace an older image unless `force` is set to true. -""" -function build_sysimg(sysimg_path=nothing, cpu_target="native", userimg_path=nothing; force=false, debug=false) - if sysimg_path === nothing - sysimg_path = default_sysimg_path(debug) - end - - # Quit out if a sysimg is already loaded and is in the same spot as sysimg_path, unless forcing - sysimg = Libdl.dlopen_e("sys") - if sysimg != C_NULL - if !force && Base.samefile(Libdl.dlpath(sysimg), "$(sysimg_path).$(Libdl.dlext)") - info("System image already loaded at $(Libdl.dlpath(sysimg)), set force=true to override.") - return nothing - end - end - - # Canonicalize userimg_path before we enter the base_dir - if userimg_path !== nothing - userimg_path = abspath(userimg_path) - end - - # Enter base and setup some useful paths - base_dir = dirname(Base.find_source_file("sysimg.jl")) - cd(base_dir) do - julia = joinpath(JULIA_HOME, debug ? "julia-debug" : "julia") - cc, warn_msg = find_system_compiler() - - # Ensure we have write-permissions to wherever we're trying to write to - try - touch("$sysimg_path.ji") - catch - err_msg = "Unable to modify $sysimg_path.ji, ensure parent directory exists " - err_msg *= "and is writable; absolute paths work best.)" - error(err_msg) - end - - # Copy in userimg.jl if it exists - if userimg_path !== nothing - if !isfile(userimg_path) - error("$userimg_path is not found, ensure it is an absolute path.") - end - if isfile("userimg.jl") - error("$(joinpath(base_dir, "userimg.jl")) already exists, delete manually to continue.") - end - cp(userimg_path, "userimg.jl") - end - try - # Start by building inference.{ji,o} - inference_path = joinpath(dirname(sysimg_path), "inference") - info("Building inference.o") - info("$julia -C $cpu_target --output-ji $inference_path.ji --output-o $inference_path.o coreimg.jl") - run(`$julia -C $cpu_target --output-ji $inference_path.ji --output-o $inference_path.o coreimg.jl`) - - # Bootstrap off of that to create sys.{ji,o} - info("Building sys.o") - info("$julia -C $cpu_target --output-ji $sysimg_path.ji --output-o $sysimg_path.o -J $inference_path.ji --startup-file=no sysimg.jl") - run(`$julia -C $cpu_target --output-ji $sysimg_path.ji --output-o $sysimg_path.o -J $inference_path.ji --startup-file=no sysimg.jl`) - - if cc !== nothing - link_sysimg(sysimg_path, cc, debug) - !isempty(warn_msg) && foreach(warn, warn_msg) - else - !isempty(warn_msg) && foreach(warn, warn_msg) - info("System image successfully built at $sysimg_path.ji.") - end - - if !Base.samefile("$(default_sysimg_path(debug)).ji", "$sysimg_path.ji") - if isfile("$sysimg_path.$(Libdl.dlext)") - info("To run Julia with this image loaded, run: `julia -J $sysimg_path.$(Libdl.dlext)`.") - else - info("To run Julia with this image loaded, run: `julia -J $sysimg_path.ji`.") - end - else - info("Julia will automatically load this system image at next startup.") - end - finally - # Cleanup userimg.jl - if userimg_path !== nothing && isfile("userimg.jl") - rm("userimg.jl") - end - end - end -end - -# Search for a compiler to link sys.o into sys.dl_ext. Honor LD environment variable. -function find_system_compiler() - cc = nothing - warn_msg = String[] # save warning messages into an array - - # On Windows, check to see if WinRPM is installed, and if so, see if gcc is installed - if Sys.iswindows() - try - eval(Main, :(using WinRPM)) - winrpmgcc = joinpath(WinRPM.installdir, "usr", "$(Sys.ARCH)-w64-mingw32", - "sys-root", "mingw", "bin", "gcc.exe") - if success(`$winrpmgcc --version`) - cc = winrpmgcc - else - throw() - end - catch - push!(warn_msg, "Install GCC via `Pkg.add(\"WinRPM\"); WinRPM.install(\"gcc\")` to generate sys.dll for faster startup times.") - end - end - - if haskey(ENV, "CC") - if !success(`$(ENV["CC"]) -v`) - push!(warn_msg, "Using compiler override $(ENV["CC"]), but unable to run `$(ENV["CC"]) -v`.") - end - cc = ENV["CC"] - end - - # See if `cc` exists - try - if success(`cc -v`) - cc = "cc" - end - catch - end - - if cc === nothing - push!(warn_msg, "No supported compiler found; startup times will be longer.") - end - - return cc, warn_msg -end - -# Link sys.o into sys.$(dlext) -function link_sysimg(sysimg_path=nothing, cc=find_system_compiler(), debug=false) - if sysimg_path === nothing - sysimg_path = default_sysimg_path(debug) - end - julia_libdir = dirname(Libdl.dlpath(debug ? "libjulia-debug" : "libjulia")) - - FLAGS = ["-L$julia_libdir"] - - push!(FLAGS, "-shared") - push!(FLAGS, debug ? "-ljulia-debug" : "-ljulia") - if Sys.iswindows() - push!(FLAGS, "-lssp") - end - - sysimg_file = "$sysimg_path.$(Libdl.dlext)" - info("Linking sys.$(Libdl.dlext)") - info("$cc $(join(FLAGS, ' ')) -o $sysimg_file $sysimg_path.o") - # Windows has difficulties overwriting a file in use so we first link to a temp file - if Sys.iswindows() && isfile(sysimg_file) - if success(pipeline(`$cc $FLAGS -o $sysimg_path.tmp $sysimg_path.o`; stdout=STDOUT, stderr=STDERR)) - mv(sysimg_file, "$sysimg_file.old"; remove_destination=true) - mv("$sysimg_path.tmp", sysimg_file; remove_destination=true) - end - else - run(`$cc $FLAGS -o $sysimg_file $sysimg_path.o`) - end - info("System image successfully built at $sysimg_path.$(Libdl.dlext)") - return -end - -# When running this file as a script, try to do so with default values. If arguments are passed -# in, use them as the arguments to build_sysimg above. -# Also check whether we are running `genstdlib.jl`, in which case we don't want to build a -# system image and instead only need `build_sysimg`'s docstring to be available. -if !isdefined(Main, :GenStdLib) && !isinteractive() - if length(ARGS) > 5 || ("--help" in ARGS || "-h" in ARGS) - println("Usage: build_sysimg.jl [--force] [--debug] [--help]") - println(" is an absolute, extensionless path to store the system image at") - println(" is an LLVM cpu target to build the system image against") - println(" is the path to a user image to be baked into the system image") - println(" --debug Using julia-debug instead of julia to build the system image") - println(" --force Set if you wish to overwrite the default system image") - println(" --help Print out this help text and exit") - println() - println(" Example:") - println(" build_sysimg.jl /usr/local/lib/julia/sys core2 ~/my_usrimg.jl --force") - println() - println(" Running this script with no arguments is equivalent to:") - println(" build_sysimg.jl $(default_sysimg_path()) native") - return 0 - end - - debug_flag = "--debug" in ARGS - filter!(x -> x != "--debug", ARGS) - force_flag = "--force" in ARGS - filter!(x -> x != "--force", ARGS) - build_sysimg(ARGS...; force=force_flag, debug=debug_flag) -end diff --git a/make.jl b/make.jl index 893628d..f7e9b69 100644 --- a/make.jl +++ b/make.jl @@ -14,12 +14,7 @@ end using Documenter include("contrib/html_writer.jl") -# Include the `build_sysimg` file. - baremodule GenStdLib end -@isdefined(build_sysimg) || @eval module BuildSysImg - include(joinpath(@__DIR__, "contrib", "build_sysimg.jl")) -end # make links for stdlib package docs, this is needed until #522 in Documenter.jl is finished const STDLIB_DIR = Sys.STDLIB @@ -145,7 +140,7 @@ const t_html_canonical = "https://juliakorea.github.io/ko/latest/" makedocs( build = joinpath(pwd(), "local" in ARGS ? "_build_local" : "_build/html/ko/latest"), - modules = [Base, Core, BuildSysImg, [Base.root_module(Base, stdlib.stdlib) for stdlib in STDLIB_DOCS]...], + modules = [Base, Core, [Base.root_module(Base, stdlib.stdlib) for stdlib in STDLIB_DOCS]...], clean = false, # true doctest = ("doctest=fix" in ARGS) ? (:fix) : ("doctest=true" in ARGS) ? true : false, linkcheck = "linkcheck=true" in ARGS, diff --git a/src/NEWS.md b/src/NEWS.md index f791e75..91e0e5d 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -110,6 +110,7 @@ Standard library changes * `mul!`, `rmul!` and `lmul!` methods for `UniformScaling` ([#29506](https://github.com/JuliaLang/julia/issues/29506)). * `Symmetric` and `Hermitian` matrices now preserve the wrapper when scaled with a number ([#29469](https://github.com/JuliaLang/julia/issues/29469)). * Exponentiation operator `^` now supports raising an `Irrational` to an `AbstractMatrix` power ([#29782](https://github.com/JuliaLang/julia/issues/29782)). + * Added keyword arguments `rtol`, `atol` to `pinv`, `nullspace` and `rank` ([#29998](https://github.com/JuliaLang/julia/issues/29998), [#29926](https://github.com/JuliaLang/julia/issues/29926)). #### Random * `randperm` and `randcycle` now use the type of their argument to determine the element type of @@ -132,6 +133,7 @@ External dependencies * The source code for Pkg is no longer included in JuliaLang/julia. Pkg is instead downloaded during the build process ([#29615](https://github.com/JuliaLang/julia/issues/29615)). * LLVM has been upgraded to 6.0.1 and support for LLVM < 6.0 has been dropped ([#28745](https://github.com/JuliaLang/julia/issues/28745), [#28696](https://github.com/JuliaLang/julia/issues/28696)). + * Pkg has been upgraded to version 1.1 ([#30342](https://github.com/JuliaLang/julia/issues/30342)). Deprecated or removed --------------------- diff --git a/src/devdocs/sysimg.md b/src/devdocs/sysimg.md index 6c12278..a354a5f 100644 --- a/src/devdocs/sysimg.md +++ b/src/devdocs/sysimg.md @@ -16,28 +16,8 @@ This operation is useful for multiple reasons. A user may: * Include a `userimg.jl` file that includes packages into the system image, thereby creating a system image that has packages embedded into the startup environment. -Julia now ships with a script that automates the tasks of building the system image, wittingly -named `build_sysimg.jl` that lives in `DATAROOTDIR/julia/`. That is, to include it into a current -Julia session, type: - -```julia -include(joinpath(Sys.BINDIR, Base.DATAROOTDIR, "julia", "build_sysimg.jl")) -``` - -This will include a `build_sysimg` function: - -```@docs -BuildSysImg.build_sysimg -``` - -Note that this file can also be run as a script itself, with command line arguments taking the -place of arguments passed to the `build_sysimg` function. For example, to build a system image -in `/tmp/sys.{so,dll,dylib}`, with the `core2` CPU instruction set, a user image of `~/userimg.jl` -and `force` set to `true`, one would execute: - -``` -julia build_sysimg.jl /tmp/sys core2 ~/userimg.jl --force -``` +The [`PackageCompiler.jl` package](https://github.com/JuliaLang/PackageCompiler.jl) contains convenient +wrapper functions to automate this process. ## System image optimized for multiple microarchitectures diff --git a/src/manual/parallel-computing.md b/src/manual/parallel-computing.md index ab7052f..80e513b 100644 --- a/src/manual/parallel-computing.md +++ b/src/manual/parallel-computing.md @@ -1142,6 +1142,96 @@ sent to the remote node to go ahead and remove its reference to the value. Once finalized, a reference becomes invalid and cannot be used in any further calls. + +## Local invocations(@id man-distributed-local-invocations) + +Data is necessarily copied over to the remote node for execution. This is the case for both +remotecalls and when data is stored to a[`RemoteChannel`](@ref) / [`Future`](@ref) on +a different node. As expected, this results in a copy of the serialized objects +on the remote node. However, when the destination node is the local node, i.e. +the calling process id is the same as the remote node id, it is executed +as a local call. It is usually(not always) executed in a different task - but there is no +serialization/deserialization of data. Consequently, the call refers to the same object instances +as passed - no copies are created. This behavior is highlighted below: + +```julia-repl +julia> using Distributed; + +julia> rc = RemoteChannel(()->Channel(3)); # RemoteChannel created on local node + +julia> v = [0]; + +julia> for i in 1:3 + v[1] = i # Reusing `v` + put!(rc, v) + end; + +julia> result = [take!(rc) for _ in 1:3]; + +julia> println(result); +Array{Int64,1}[[3], [3], [3]] + +julia> println("Num Unique objects : ", length(unique(map(objectid, result)))); +Num Unique objects : 1 + +julia> addprocs(1); + +julia> rc = RemoteChannel(()->Channel(3), workers()[1]); # RemoteChannel created on remote node + +julia> v = [0]; + +julia> for i in 1:3 + v[1] = i + put!(rc, v) + end; + +julia> result = [take!(rc) for _ in 1:3]; + +julia> println(result); +Array{Int64,1}[[1], [2], [3]] + +julia> println("Num Unique objects : ", length(unique(map(objectid, result)))); +Num Unique objects : 3 +``` + +As can be seen, [`put!`](@ref) on a locally owned [`RemoteChannel`](@ref) with the same +object `v` modifed between calls results in the same single object instance stored. As +opposed to copies of `v` being created when the node owning `rc` is a different node. + +It is to be noted that this is generally not an issue. It is something to be factored in only +if the object is both being stored locally and modifed post the call. In such cases it may be +appropriate to store a `deepcopy` of the object. + +This is also true for remotecalls on the local node as seen in the following example: + +```julia-repl +julia> using Distributed; addprocs(1); + +julia> v = [0]; + +julia> v2 = remotecall_fetch(x->(x[1] = 1; x), myid(), v); # Executed on local node + +julia> println("v=$v, v2=$v2, ", v === v2); +v=[1], v2=[1], true + +julia> v = [0]; + +julia> v2 = remotecall_fetch(x->(x[1] = 1; x), workers()[1], v); # Executed on remote node + +julia> println("v=$v, v2=$v2, ", v === v2); +v=[0], v2=[1], false +``` + +As can be seen once again, a remote call onto the local node behaves just like a direct invocation. +The call modifies local objects passed as arguments. In the remote invocation, it operates on +a copy of the arguments. + +To repeat, in general this is not an issue. If the local node is also being used as a compute +node, and the arguments used post the call, this behavior needs to be factored in and if required +deep copies of arguments must be passed to the call invoked on the local node. Calls on remote nodes +will always operate on copies of arguments. + + ## [Shared Arrays](@id man-shared-arrays) Shared Arrays use system shared memory to map the same array across many processes. While there diff --git a/src/manual/workflow-tips.md b/src/manual/workflow-tips.md index 8cae4ce..cdc74a4 100644 --- a/src/manual/workflow-tips.md +++ b/src/manual/workflow-tips.md @@ -8,75 +8,59 @@ As already elaborated in [The Julia REPL](@ref), Julia's REPL provides rich func that facilitates an efficient interactive workflow. Here are some tips that might further enhance your experience at the command line. -## Command-line-based basic editor/REPL workflow +### A basic editor/REPL workflow The most basic Julia workflows involve using a text editor in conjunction with the `julia` command line. A common pattern includes the following elements: - * **Generate a new project** - - ``` - $ julia -e 'using Pkg;Pkg.generate("Tmp")' -Generating project Tmp: - Tmp/Project.toml - Tmp/src/Tmp.jl - $ ls -R Tmp -Tmp: -Project.toml src - -Tmp/src: -Tmp.jl - $ cat -n Tmp/src/Tmp.jl - 1 module Tmp - 2 - 3 greet() = print("Hello World!") - 4 - 5 end # module - ``` - - * **Create a test folder** - ``` - $ mkdir Tmp/test - ``` - * **Put your test code in `test/runtests.jl` file.** + * **Put code under development in a temporary module.** Create a file, say `Tmp.jl`, and include + within it + ```julia + module Tmp + export say_hello + + say_hello() = println("Hello!") + + # your other definitions here + + end ``` - $ cat -n Tmp/test/runtests.jl - 1 using Tmp - 2 Tmp.greet() + * **Put your test code in another file.** Create another file, say `tst.jl`, which looks like + + ```julia + include("Tmp.jl") + import .Tmp + # using .Tmp # we can use `using` to bring the exported symbols in `Tmp` into our namespace + + Tmp.say_hello() + # say_hello() + + # your other test code here ``` - * **Run test** - ``` - $ julia -e 'using Pkg;Pkg.activate("Tmp");Pkg.test()' - Updating registry at `~/.julia/registries/General` - Updating git-repo `https://github.com/JuliaRegistries/General.git` - Resolving package versions... - Updating `~/Tmp/Project.toml` - [no changes] - Testing Tmp - Resolving package versions... -Hello World! Testing Tmp tests passed - ``` - * **Lather. Rinse. Repeat.** Explore ideas at the `julia` command prompt. Save good ideas in `Tmp.jl` and test with `runtests.jl`. - -## Simplify initialization - -To simplify restarting the REPL, put project-specific initialization code in a file, say `_init.jl`, -which you can run on startup by issuing the command: - -``` -julia -L _init.jl -``` - -If you further add the following to your `~/.julia/config/startup.jl` file - -```julia -isfile("_init.jl") && include(joinpath(pwd(), "_init.jl")) -``` - -then calling `julia` from that directory will run the initialization code without the additional -command line argument. + and includes tests for the contents of `Tmp`. + Alternatively, you can wrap the contents of your test file in a module, as + + ```julia + module Tst + include("Tmp.jl") + import .Tmp + #using .Tmp + + Tmp.say_hello() + # say_hello() + + # your other test code here + end + ``` + + The advantage is that your testing code is now contained in a module and does not use the global scope in `Main` for + definitions, which is a bit more tidy. + + * `include` the `tst.jl` file in the Julia REPL with `include("tst.jl")`. + + * **Lather. Rinse. Repeat.** Explore ideas at the `julia` command prompt. Save good ideas in `tst.jl`. To execute `tst.jl` after it has been changed, just `include` it again. ## Browser-based workflow From 291065c4e27a741e9326daf7fc138f176751e037 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Thu, 13 Dec 2018 19:57:06 +0900 Subject: [PATCH 085/153] update Julia Commit 3ee8798fc4 --- codex/NEWS.md | 116 +------------------------- codex/manual/control-flow.md | 31 ++++--- codex/manual/environment-variables.md | 40 ++++----- src/NEWS.md | 116 +------------------------- src/index.md | 2 +- src/manual/control-flow.md | 28 +++---- src/manual/environment-variables.md | 40 ++++----- 7 files changed, 73 insertions(+), 300 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index 91e0e5d..3f11a8a 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -1,148 +1,36 @@ -Julia v1.1 Release Notes +Julia v1.2 Release Notes ======================== New language features --------------------- - * An *exception stack* is maintained on each task to make exception handling - more robust and enable root cause analysis. The stack may be accessed using - the experimental function `Base.catch_stack` ([#28878](https://github.com/JuliaLang/julia/issues/28878)). - * The experimental macro `Base.@locals` returns a dictionary of current local variable names - and values ([#29733](https://github.com/JuliaLang/julia/issues/29733)). Language changes ---------------- - * Parser inputs ending with a comma are now consistently treated as incomplete. - Previously they were sometimes parsed as tuples, depending on whitespace ([#28506](https://github.com/JuliaLang/julia/issues/28506)). - * Spaces were accidentally allowed in broadcast call syntax, e.g. `f. (x)`. They are now - disallowed, consistent with normal function call syntax ([#29781](https://github.com/JuliaLang/julia/issues/29781)). - * Big integer literals and command syntax (backticks) are now parsed with the name of - the macro (`@int128_str`, `@uint128_str`, `@big_str`, `@cmd`) qualified to refer - to the `Core` module ([#29968](https://github.com/JuliaLang/julia/issues/29968)). - * Using the same name for both a local variable and a static parameter is now an error instead - of a warning ([#29429](https://github.com/JuliaLang/julia/issues/29429)). - * `findall(in(b), a)` now returns a `CartesianIndex` when `a` is a matrix or a higher-dimensional array, - for consistency with other `findall` methods. Use `LinearIndices(a)[findall(in(b), a)]` to get - the old behavior, or `CartesianIndices(a)[findall(in(b), a)]` to get the new behavior - on previous Julia versions ([#30226](https://github.com/JuliaLang/julia/issues/30226)). - * `findmin(::BitArray)` and `findmax(::BitArray)` now return a `CartesianIndex` when `a` is a matrix - or a higher-dimensional array, for consistency with other array types. - Use `LinearIndices(a)[findmin(a)[2]]` to get the old behavior, or `CartesianIndices(a)[findmin(a)[2]]` - to get the new behavior on previous Julia versions ([#30102](https://github.com/JuliaLang/julia/issues/30102)). - * Method signatures such as - `f(::Type{T}, ::T) where {T <: X}` and - `f(::Type{X}, ::Any)` - are now considered ambiguous. Previously a bug caused the first one to be considered more specific in - some cases ([#30160](https://github.com/JuliaLang/julia/issues/30160)). Command-line option changes --------------------------- - * When a script run in interactive mode (`-i`) throws an error, the REPL now starts after - the error is displayed. Previously the REPL only started if the script completed without - error ([#21233](https://github.com/JuliaLang/julia/issues/21233)). New library functions --------------------- - * `splitpath(p::String)` function, which is the opposite of `joinpath(parts...)`: it splits a filepath - into its components ([#28156](https://github.com/JuliaLang/julia/issues/28156)). - * `isnothing(::Any)` predicate, to check whether the argument is `nothing`. ([#29679](https://github.com/JuliaLang/julia/issues/29679)). - * `getpid(::Process)` method ([#24064](https://github.com/JuliaLang/julia/issues/24064)). - * `eachrow`, `eachcol` and `eachslice` functions provide efficient iterators over slices of arrays ([#29749](https://github.com/JuliaLang/julia/issues/29749)). - * `fieldtypes(T::Type)` which returns the declared types of the field in type T ([#29600](https://github.com/JuliaLang/julia/issues/29600)). - * `uuid5` has been added to the `UUIDs` standard library ([#28761](https://github.com/JuliaLang/julia/issues/28761)). - * Predicates `Sys.isfreebsd`, `Sys.isopenbsd`, `Sys.isnetbsd`, and `Sys.isdragonfly` for - detecting BSD systems have been added ([#30249](https://github.com/JuliaLang/julia/issues/30249)). - * Internal `Base.disable_library_threading` that sets libraries to use one thread. - It executes function hooks that have been registered with - `Base.at_disable_library_threading` ([#30004](https://github.com/JuliaLang/julia/issues/30004)). Standard library changes ------------------------ - * `CartesianIndices` can now be constructed from two `CartesianIndex`es `I` and `J` with `I:J` ([#29440](https://github.com/JuliaLang/julia/issues/29440)). - * `CartesianIndices` support broadcasting arithmetic (+ and -) with a `CartesianIndex` ([#29890](https://github.com/JuliaLang/julia/issues/29890)). - * `copy!` support for arrays, dicts, and sets has been moved to Base from the Future package ([#29173](https://github.com/JuliaLang/julia/issues/29173)). - * Channels now convert inserted values (like containers) instead of requiring types to match ([#29092](https://github.com/JuliaLang/julia/issues/29092)). - * `range` can accept the stop value as a positional argument, e.g. `range(1,10,step=2)` ([#28708](https://github.com/JuliaLang/julia/issues/28708)). - * `diff` now supports arrays of arbitrary dimensionality and can operate over any dimension ([#29827](https://github.com/JuliaLang/julia/issues/29827)). - * The constructor `BigFloat(::BigFloat)` now respects the global precision setting and always - returns a `BigFloat` with precision equal to `precision(BigFloat)` ([#29127](https://github.com/JuliaLang/julia/issues/29127)). The optional - `precision` argument to override the global setting is now a keyword instead of positional - argument ([#29157](https://github.com/JuliaLang/julia/issues/29157)). - * The use of scientific notation when printing `BigFloat` values is now consistent with other floating point - types ([#29211](https://github.com/JuliaLang/julia/issues/29211)). - * `Regex` now behaves like a scalar when used in broadcasting ([#29913](https://github.com/JuliaLang/julia/issues/29913)). - * `Char` now behaves like a read-only 0-dimensional array ([#29819](https://github.com/JuliaLang/julia/issues/29819)). - * `parse` now allows strings representing integer 0 and 1 for type `Bool` ([#29980](https://github.com/JuliaLang/julia/issues/29980)). - * `Base.tail` now works on named tuples ([#29595](https://github.com/JuliaLang/julia/issues/29595)). - * The process id is appended to malloc log files in order to track memory allocations of - multiple processes ([#29969](https://github.com/JuliaLang/julia/issues/29969)). - * `Base.julia_cmd` now propagates the `--inline=(yes|no)` flag ([#29858](https://github.com/JuliaLang/julia/issues/29858)). - * `Base.@kwdef` can now be used for parametric structs, and for structs with supertypes ([#29316](https://github.com/JuliaLang/julia/issues/29316)). - * `merge(::NamedTuple, ::NamedTuple...)` can now be used with more than 2 `NamedTuple`s ([#29259](https://github.com/JuliaLang/julia/issues/29259)). - * New `ncodeunits(c::Char)` method as a fast equivalent to `ncodeunits(string(c))` ([#29153](https://github.com/JuliaLang/julia/issues/29153)). - * New `sort!(::AbstractArray; dims)` method that can sort the array along the `dims` dimension ([#28902](https://github.com/JuliaLang/julia/issues/28902)). - * `range` now accepts `stop` as a positional argument ([#28708](https://github.com/JuliaLang/julia/issues/28708)). - * `get(A::AbstractArray, (), default)` now returns `A[]` instead of an empty array ([#30270](https://github.com/JuliaLang/julia/issues/30270)). - * `parse(Bool, str)` is now supported ([#29997](https://github.com/JuliaLang/julia/issues/29997)). - * `copyto!(::AbstractMatrix, ::UniformScaling)` now supports rectangular matrices ([#28790](https://github.com/JuliaLang/julia/issues/28790)). - * `current_project()` now searches the parent directories of a Git repository for a `Project.toml` file. - This also affects the behavior of the `--project` command line option when using the default - `--project=@.` ([#29108](https://github.com/JuliaLang/julia/issues/29108)). - * The `spawn` API is now more flexible and supports taking IOBuffer directly as an I/O stream, - converting to a system pipe as needed ([#30278](https://github.com/JuliaLang/julia/issues/30278)). - -#### Dates - * New `DateTime(::Date, ::Time)` constructor ([#29754](https://github.com/JuliaLang/julia/issues/29754)). - * `TimeZone` now behaves like a scalar when used in broadcasting ([#30159](https://github.com/JuliaLang/julia/issues/30159)). - -#### InteractiveUtils - * `edit` can now be called on a module to edit the file that defines it ([#29636](https://github.com/JuliaLang/julia/issues/29636)). - * All compiler-reflection tools (i.e. the `code_` class of functions and macros) now print accurate - line number and inlining information in a common style, and take an optional parameter (debuginfo=:default) - to control the verbosity of the metadata shown ([#29893](https://github.com/JuliaLang/julia/issues/29893)). #### LinearAlgebra - * `isdiag` and `isposdef` for `Diagonal` and `UniformScaling` ([#29638](https://github.com/JuliaLang/julia/issues/29638)). - * `mul!`, `rmul!` and `lmul!` methods for `UniformScaling` ([#29506](https://github.com/JuliaLang/julia/issues/29506)). - * `Symmetric` and `Hermitian` matrices now preserve the wrapper when scaled with a number ([#29469](https://github.com/JuliaLang/julia/issues/29469)). - * Exponentiation operator `^` now supports raising an `Irrational` to an `AbstractMatrix` power ([#29782](https://github.com/JuliaLang/julia/issues/29782)). - * Added keyword arguments `rtol`, `atol` to `pinv`, `nullspace` and `rank` ([#29998](https://github.com/JuliaLang/julia/issues/29998), [#29926](https://github.com/JuliaLang/julia/issues/29926)). -#### Random - * `randperm` and `randcycle` now use the type of their argument to determine the element type of - the returned array ([#29670](https://github.com/JuliaLang/julia/issues/29670)). - * A new method `rand(::Tuple)` implements sampling from the values of a tuple ([#25278](https://github.com/JuliaLang/julia/issues/25278)). - * `serialize` and `deserialize` now accept a filename argument, like `write` and `read` ([#30151](https://github.com/JuliaLang/julia/issues/30151)). +* Added keyword arguments `rtol`, `atol` to `pinv` and `nullspace` ([#29998](https://github.com/JuliaLang/julia/issues/29998)). -#### SparseArrays - * `sprandn` now supports specifying the output element type ([#30083](https://github.com/JuliaLang/julia/issues/30083)). - -#### Statistics - * `mean` and `var` now handle more kinds of empty inputs ([#29033](https://github.com/JuliaLang/julia/issues/29033)). External dependencies --------------------- - * 7zip (bundled with Julia on Windows) has been upgraded from version 16.04 to 18.05 ([#30035](https://github.com/JuliaLang/julia/issues/30035)). - * Busybox is no longer bundled with Julia on Windows ([#30022](https://github.com/JuliaLang/julia/issues/30022)). - * OpenBLAS has been upgraded from 0.3.2 to 0.3.3 ([#29845](https://github.com/JuliaLang/julia/issues/29845)). - * The source code for Pkg is no longer included in JuliaLang/julia. Pkg is instead - downloaded during the build process ([#29615](https://github.com/JuliaLang/julia/issues/29615)). - * LLVM has been upgraded to 6.0.1 and support for LLVM < 6.0 has been dropped ([#28745](https://github.com/JuliaLang/julia/issues/28745), [#28696](https://github.com/JuliaLang/julia/issues/28696)). - * Pkg has been upgraded to version 1.1 ([#30342](https://github.com/JuliaLang/julia/issues/30342)). Deprecated or removed --------------------- - * `one(i::CartesianIndex)` should be replaced with `oneunit(i::CartesianIndex)` ([#29442](https://github.com/JuliaLang/julia/issues/29442)). - * The internal array `Base.Grisu.DIGITS` is deprecated; new code should use `Base.Grisu.getbuf()` - to get an appropriate task-local buffer and pass it to `grisu()` instead ([#29907](https://github.com/JuliaLang/julia/issues/29907)). - * The internal function `Base._default_type(T)` has been removed. Calls to it should be - replaced with just the argument `T` ([#29739](https://github.com/JuliaLang/julia/issues/29739)). - * `peakflops` has been scheduled to move from `InteractiveUtils` to `LinearAlgebra` - but is already now available as `LinearAlgebra.peakflops` ([#29978](https://github.com/JuliaLang/julia/issues/29978)). diff --git a/codex/manual/control-flow.md b/codex/manual/control-flow.md index 6d4cf72..a8611b4 100644 --- a/codex/manual/control-flow.md +++ b/codex/manual/control-flow.md @@ -717,28 +717,25 @@ Stacktrace: ### The `try/catch` statement -The `try/catch` statement allows for `Exception`s to be tested for. For example, a customized -square root function can be written to automatically call either the real or complex square root -method on demand using `Exception`s : +The `try/catch` statement allows for `Exception`s to be tested for, and for the +graceful handling of things that may ordinarily break your application. For example, +in the below code the function for square root would normally throw an exception. By +placing a `try/catch` block around it we can mitigate that here. You may choose how +you wish to handle this exception, whether logging it, return a placeholder value or +as in the case below where we just printed out a statement. One thing to think about +when deciding how to handle unexpected situations is that using a `try/catch` block is +much slower than using conditional branching to handle those situations. +Below there are more examples of handling exceptions with a `try/catch` block: ```jldoctest -julia> f(x) = try - sqrt(x) - catch - sqrt(complex(x, 0)) +julia> try + sqrt("ten") + catch e + println("You should have entered a numeric value") end -f (generic function with 1 method) - -julia> f(1) -1.0 - -julia> f(-1) -0.0 + 1.0im +You should have entered a numeric value ``` -It is important to note that in real code computing this function, one would compare `x` to zero -instead of catching an exception. The exception is much slower than simply comparing and branching. - `try/catch` statements also allow the `Exception` to be saved in a variable. The following contrived example calculates the square root of the second element of `x` if `x` is indexable, otherwise assumes `x` is a real number and returns its square root: diff --git a/codex/manual/environment-variables.md b/codex/manual/environment-variables.md index d92260d..7bc47ba 100644 --- a/codex/manual/environment-variables.md +++ b/codex/manual/environment-variables.md @@ -1,25 +1,26 @@ # Environment Variables -Julia may be configured with a number of environment variables, either in the -usual way of the operating system, or in a portable way from within Julia. -Suppose you want to set the environment variable `JULIA_EDITOR` to -`vim`, then either type `ENV["JULIA_EDITOR"] = "vim"` for instance in the REPL -to make this change on a case by case basis, or add the same to the user -configuration file `~/.julia/config/startup.jl` in the user's home directory to have -a permanent effect. The current value of the same environment variable is +Julia can be configured with a number of environment variables, set either in +the usual way for each operating system, or in a portable way from within Julia. +Supposing that you want to set the environment variable `JULIA_EDITOR` to `vim`, +you can type `ENV["JULIA_EDITOR"] = "vim"` (for instance, in the REPL) to make +this change on a case by case basis, or add the same to the user configuration +file `~/.julia/config/startup.jl` in the user's home directory to have a +permanent effect. The current value of the same environment variable can be determined by evaluating `ENV["JULIA_EDITOR"]`. The environment variables that Julia uses generally start with `JULIA`. If -[`InteractiveUtils.versioninfo`](@ref) is called with `verbose` equal to `true`, then the +[`InteractiveUtils.versioninfo`](@ref) is called with the keyword `verbose=true`, then the output will list defined environment variables relevant for Julia, including those for which `JULIA` appears in the name. !!! note - Some variables, such as `JULIA_NUM_THREADS` and `JULIA_PROJECT` need to be set before Julia + Some variables, such as `JULIA_NUM_THREADS` and `JULIA_PROJECT`, need to be set before Julia starts, therefore adding these to `~/.julia/config/startup.jl` is too late in the startup process. - These must either be set manually before launching Julia through bash with - `export JULIA_NUM_THREADS=4` etc. or added to `-/.bashrc` and/or `~/.bash_profile` to achieve persistence. + In Bash, environment variables can either be set manually by running, e.g., + `export JULIA_NUM_THREADS=4` before starting Julia, or by adding the same command to + `-/.bashrc` or `~/.bash_profile` to set the variable each time Bash is started. ## File locations @@ -76,7 +77,7 @@ and a global configuration search path of A directory path that points to the current Julia project. Setting this environment variable has the same effect as specifying the `--project` start-up -option, but `--project` has higher precedence. If the variable is set to `@.`, +option, but `--project` has higher precedence. If the variable is set to `@.` then Julia tries to find a project directory that contains `Project.toml` or `JuliaProject.toml` file from the current directory and its parents. See also the chapter on [Code Loading](@ref). @@ -88,8 +89,8 @@ the chapter on [Code Loading](@ref). ### `JULIA_LOAD_PATH` A separated list of absolute paths that are to be appended to the variable -[`LOAD_PATH`](@ref). (In Unix-like systems, the path separator is `:`; in -Windows systems, the path separator is `;`.) The `LOAD_PATH` variable is where +[`LOAD_PATH`](@ref). (In Unix-like systems, `:` is the path separator; in +Windows systems, `;` is the path separator.) The `LOAD_PATH` variable is where [`Base.require`](@ref) and `Base.load_in_path()` look for code; it defaults to the absolute path `$JULIA_HOME/../share/julia/stdlib/v$(VERSION.major).$(VERSION.minor)` so that, @@ -185,7 +186,7 @@ affinitized. Otherwise, Julia lets the operating system handle thread policy. Environment variables that determine how REPL output should be formatted at the terminal. Generally, these variables should be set to [ANSI terminal escape sequences](http://ascii-table.com/ansi-escape-sequences.php). Julia provides -a high-level interface with much of the same functionality: see the section on +a high-level interface with much of the same functionality; see the section on [The Julia REPL](@ref). ### `JULIA_ERROR_COLOR` @@ -283,11 +284,10 @@ event listener for just-in-time (JIT) profiling. This environment variable only has an effect if Julia was compiled with JIT profiling support, using either - -* Intel's [VTune™ Amplifier](https://software.intel.com/en-us/intel-vtune-amplifier-xe) - (`USE_INTEL_JITEVENTS` set to `1` in the build configuration), or -* [OProfile](http://oprofile.sourceforge.net/news/) (`USE_OPROFILE_JITEVENTS` set to `1` - in the build configuration). + * Intel's [VTune™ Amplifier](https://software.intel.com/en-us/intel-vtune-amplifier-xe) + (`USE_INTEL_JITEVENTS` set to `1` in the build configuration), or + * [OProfile](http://oprofile.sourceforge.net/news/) (`USE_OPROFILE_JITEVENTS` set to `1` + in the build configuration). ### `JULIA_LLVM_ARGS` diff --git a/src/NEWS.md b/src/NEWS.md index 91e0e5d..3f11a8a 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -1,148 +1,36 @@ -Julia v1.1 Release Notes +Julia v1.2 Release Notes ======================== New language features --------------------- - * An *exception stack* is maintained on each task to make exception handling - more robust and enable root cause analysis. The stack may be accessed using - the experimental function `Base.catch_stack` ([#28878](https://github.com/JuliaLang/julia/issues/28878)). - * The experimental macro `Base.@locals` returns a dictionary of current local variable names - and values ([#29733](https://github.com/JuliaLang/julia/issues/29733)). Language changes ---------------- - * Parser inputs ending with a comma are now consistently treated as incomplete. - Previously they were sometimes parsed as tuples, depending on whitespace ([#28506](https://github.com/JuliaLang/julia/issues/28506)). - * Spaces were accidentally allowed in broadcast call syntax, e.g. `f. (x)`. They are now - disallowed, consistent with normal function call syntax ([#29781](https://github.com/JuliaLang/julia/issues/29781)). - * Big integer literals and command syntax (backticks) are now parsed with the name of - the macro (`@int128_str`, `@uint128_str`, `@big_str`, `@cmd`) qualified to refer - to the `Core` module ([#29968](https://github.com/JuliaLang/julia/issues/29968)). - * Using the same name for both a local variable and a static parameter is now an error instead - of a warning ([#29429](https://github.com/JuliaLang/julia/issues/29429)). - * `findall(in(b), a)` now returns a `CartesianIndex` when `a` is a matrix or a higher-dimensional array, - for consistency with other `findall` methods. Use `LinearIndices(a)[findall(in(b), a)]` to get - the old behavior, or `CartesianIndices(a)[findall(in(b), a)]` to get the new behavior - on previous Julia versions ([#30226](https://github.com/JuliaLang/julia/issues/30226)). - * `findmin(::BitArray)` and `findmax(::BitArray)` now return a `CartesianIndex` when `a` is a matrix - or a higher-dimensional array, for consistency with other array types. - Use `LinearIndices(a)[findmin(a)[2]]` to get the old behavior, or `CartesianIndices(a)[findmin(a)[2]]` - to get the new behavior on previous Julia versions ([#30102](https://github.com/JuliaLang/julia/issues/30102)). - * Method signatures such as - `f(::Type{T}, ::T) where {T <: X}` and - `f(::Type{X}, ::Any)` - are now considered ambiguous. Previously a bug caused the first one to be considered more specific in - some cases ([#30160](https://github.com/JuliaLang/julia/issues/30160)). Command-line option changes --------------------------- - * When a script run in interactive mode (`-i`) throws an error, the REPL now starts after - the error is displayed. Previously the REPL only started if the script completed without - error ([#21233](https://github.com/JuliaLang/julia/issues/21233)). New library functions --------------------- - * `splitpath(p::String)` function, which is the opposite of `joinpath(parts...)`: it splits a filepath - into its components ([#28156](https://github.com/JuliaLang/julia/issues/28156)). - * `isnothing(::Any)` predicate, to check whether the argument is `nothing`. ([#29679](https://github.com/JuliaLang/julia/issues/29679)). - * `getpid(::Process)` method ([#24064](https://github.com/JuliaLang/julia/issues/24064)). - * `eachrow`, `eachcol` and `eachslice` functions provide efficient iterators over slices of arrays ([#29749](https://github.com/JuliaLang/julia/issues/29749)). - * `fieldtypes(T::Type)` which returns the declared types of the field in type T ([#29600](https://github.com/JuliaLang/julia/issues/29600)). - * `uuid5` has been added to the `UUIDs` standard library ([#28761](https://github.com/JuliaLang/julia/issues/28761)). - * Predicates `Sys.isfreebsd`, `Sys.isopenbsd`, `Sys.isnetbsd`, and `Sys.isdragonfly` for - detecting BSD systems have been added ([#30249](https://github.com/JuliaLang/julia/issues/30249)). - * Internal `Base.disable_library_threading` that sets libraries to use one thread. - It executes function hooks that have been registered with - `Base.at_disable_library_threading` ([#30004](https://github.com/JuliaLang/julia/issues/30004)). Standard library changes ------------------------ - * `CartesianIndices` can now be constructed from two `CartesianIndex`es `I` and `J` with `I:J` ([#29440](https://github.com/JuliaLang/julia/issues/29440)). - * `CartesianIndices` support broadcasting arithmetic (+ and -) with a `CartesianIndex` ([#29890](https://github.com/JuliaLang/julia/issues/29890)). - * `copy!` support for arrays, dicts, and sets has been moved to Base from the Future package ([#29173](https://github.com/JuliaLang/julia/issues/29173)). - * Channels now convert inserted values (like containers) instead of requiring types to match ([#29092](https://github.com/JuliaLang/julia/issues/29092)). - * `range` can accept the stop value as a positional argument, e.g. `range(1,10,step=2)` ([#28708](https://github.com/JuliaLang/julia/issues/28708)). - * `diff` now supports arrays of arbitrary dimensionality and can operate over any dimension ([#29827](https://github.com/JuliaLang/julia/issues/29827)). - * The constructor `BigFloat(::BigFloat)` now respects the global precision setting and always - returns a `BigFloat` with precision equal to `precision(BigFloat)` ([#29127](https://github.com/JuliaLang/julia/issues/29127)). The optional - `precision` argument to override the global setting is now a keyword instead of positional - argument ([#29157](https://github.com/JuliaLang/julia/issues/29157)). - * The use of scientific notation when printing `BigFloat` values is now consistent with other floating point - types ([#29211](https://github.com/JuliaLang/julia/issues/29211)). - * `Regex` now behaves like a scalar when used in broadcasting ([#29913](https://github.com/JuliaLang/julia/issues/29913)). - * `Char` now behaves like a read-only 0-dimensional array ([#29819](https://github.com/JuliaLang/julia/issues/29819)). - * `parse` now allows strings representing integer 0 and 1 for type `Bool` ([#29980](https://github.com/JuliaLang/julia/issues/29980)). - * `Base.tail` now works on named tuples ([#29595](https://github.com/JuliaLang/julia/issues/29595)). - * The process id is appended to malloc log files in order to track memory allocations of - multiple processes ([#29969](https://github.com/JuliaLang/julia/issues/29969)). - * `Base.julia_cmd` now propagates the `--inline=(yes|no)` flag ([#29858](https://github.com/JuliaLang/julia/issues/29858)). - * `Base.@kwdef` can now be used for parametric structs, and for structs with supertypes ([#29316](https://github.com/JuliaLang/julia/issues/29316)). - * `merge(::NamedTuple, ::NamedTuple...)` can now be used with more than 2 `NamedTuple`s ([#29259](https://github.com/JuliaLang/julia/issues/29259)). - * New `ncodeunits(c::Char)` method as a fast equivalent to `ncodeunits(string(c))` ([#29153](https://github.com/JuliaLang/julia/issues/29153)). - * New `sort!(::AbstractArray; dims)` method that can sort the array along the `dims` dimension ([#28902](https://github.com/JuliaLang/julia/issues/28902)). - * `range` now accepts `stop` as a positional argument ([#28708](https://github.com/JuliaLang/julia/issues/28708)). - * `get(A::AbstractArray, (), default)` now returns `A[]` instead of an empty array ([#30270](https://github.com/JuliaLang/julia/issues/30270)). - * `parse(Bool, str)` is now supported ([#29997](https://github.com/JuliaLang/julia/issues/29997)). - * `copyto!(::AbstractMatrix, ::UniformScaling)` now supports rectangular matrices ([#28790](https://github.com/JuliaLang/julia/issues/28790)). - * `current_project()` now searches the parent directories of a Git repository for a `Project.toml` file. - This also affects the behavior of the `--project` command line option when using the default - `--project=@.` ([#29108](https://github.com/JuliaLang/julia/issues/29108)). - * The `spawn` API is now more flexible and supports taking IOBuffer directly as an I/O stream, - converting to a system pipe as needed ([#30278](https://github.com/JuliaLang/julia/issues/30278)). - -#### Dates - * New `DateTime(::Date, ::Time)` constructor ([#29754](https://github.com/JuliaLang/julia/issues/29754)). - * `TimeZone` now behaves like a scalar when used in broadcasting ([#30159](https://github.com/JuliaLang/julia/issues/30159)). - -#### InteractiveUtils - * `edit` can now be called on a module to edit the file that defines it ([#29636](https://github.com/JuliaLang/julia/issues/29636)). - * All compiler-reflection tools (i.e. the `code_` class of functions and macros) now print accurate - line number and inlining information in a common style, and take an optional parameter (debuginfo=:default) - to control the verbosity of the metadata shown ([#29893](https://github.com/JuliaLang/julia/issues/29893)). #### LinearAlgebra - * `isdiag` and `isposdef` for `Diagonal` and `UniformScaling` ([#29638](https://github.com/JuliaLang/julia/issues/29638)). - * `mul!`, `rmul!` and `lmul!` methods for `UniformScaling` ([#29506](https://github.com/JuliaLang/julia/issues/29506)). - * `Symmetric` and `Hermitian` matrices now preserve the wrapper when scaled with a number ([#29469](https://github.com/JuliaLang/julia/issues/29469)). - * Exponentiation operator `^` now supports raising an `Irrational` to an `AbstractMatrix` power ([#29782](https://github.com/JuliaLang/julia/issues/29782)). - * Added keyword arguments `rtol`, `atol` to `pinv`, `nullspace` and `rank` ([#29998](https://github.com/JuliaLang/julia/issues/29998), [#29926](https://github.com/JuliaLang/julia/issues/29926)). -#### Random - * `randperm` and `randcycle` now use the type of their argument to determine the element type of - the returned array ([#29670](https://github.com/JuliaLang/julia/issues/29670)). - * A new method `rand(::Tuple)` implements sampling from the values of a tuple ([#25278](https://github.com/JuliaLang/julia/issues/25278)). - * `serialize` and `deserialize` now accept a filename argument, like `write` and `read` ([#30151](https://github.com/JuliaLang/julia/issues/30151)). +* Added keyword arguments `rtol`, `atol` to `pinv` and `nullspace` ([#29998](https://github.com/JuliaLang/julia/issues/29998)). -#### SparseArrays - * `sprandn` now supports specifying the output element type ([#30083](https://github.com/JuliaLang/julia/issues/30083)). - -#### Statistics - * `mean` and `var` now handle more kinds of empty inputs ([#29033](https://github.com/JuliaLang/julia/issues/29033)). External dependencies --------------------- - * 7zip (bundled with Julia on Windows) has been upgraded from version 16.04 to 18.05 ([#30035](https://github.com/JuliaLang/julia/issues/30035)). - * Busybox is no longer bundled with Julia on Windows ([#30022](https://github.com/JuliaLang/julia/issues/30022)). - * OpenBLAS has been upgraded from 0.3.2 to 0.3.3 ([#29845](https://github.com/JuliaLang/julia/issues/29845)). - * The source code for Pkg is no longer included in JuliaLang/julia. Pkg is instead - downloaded during the build process ([#29615](https://github.com/JuliaLang/julia/issues/29615)). - * LLVM has been upgraded to 6.0.1 and support for LLVM < 6.0 has been dropped ([#28745](https://github.com/JuliaLang/julia/issues/28745), [#28696](https://github.com/JuliaLang/julia/issues/28696)). - * Pkg has been upgraded to version 1.1 ([#30342](https://github.com/JuliaLang/julia/issues/30342)). Deprecated or removed --------------------- - * `one(i::CartesianIndex)` should be replaced with `oneunit(i::CartesianIndex)` ([#29442](https://github.com/JuliaLang/julia/issues/29442)). - * The internal array `Base.Grisu.DIGITS` is deprecated; new code should use `Base.Grisu.getbuf()` - to get an appropriate task-local buffer and pass it to `grisu()` instead ([#29907](https://github.com/JuliaLang/julia/issues/29907)). - * The internal function `Base._default_type(T)` has been removed. Calls to it should be - replaced with just the argument `T` ([#29739](https://github.com/JuliaLang/julia/issues/29739)). - * `peakflops` has been scheduled to move from `InteractiveUtils` to `LinearAlgebra` - but is already now available as `LinearAlgebra.peakflops` ([#29978](https://github.com/JuliaLang/julia/issues/29978)). diff --git a/src/index.md b/src/index.md index 556d9cd..0b0f10c 100644 --- a/src/index.md +++ b/src/index.md @@ -19,7 +19,7 @@ import Markdown Markdown.parse(String(take!(io))) ``` -[지난 릴리즈](https://github.com/juliakorea/translate-doc/wiki/NEWS)로부터 바뀐 점은 [릴리즈 노트](NEWS.md)에 있습니다. +지난 릴리즈에서 부터 바뀐 점은 [릴리즈 노트](NEWS.md)에 있습니다. ` ` diff --git a/src/manual/control-flow.md b/src/manual/control-flow.md index d1df619..f86478c 100644 --- a/src/manual/control-flow.md +++ b/src/manual/control-flow.md @@ -626,25 +626,25 @@ Stacktrace: ### `try/catch`문 -`try/catch`문은 `Exception`을 테스트할 수 있습니다. 예를 들어, 사용자 정의 제곱근 함수를 `Exception`을 사용하여 필요에 따라 실수 또는 복소수 제곱근 방법을 자동으로 호출하도록 작성할 수 있습니다. +The `try/catch` statement allows for `Exception`s to be tested for, and for the +graceful handling of things that may ordinarily break your application. For example, +in the below code the function for square root would normally throw an exception. By +placing a `try/catch` block around it we can mitigate that here. You may choose how +you wish to handle this exception, whether logging it, return a placeholder value or +as in the case below where we just printed out a statement. One thing to think about +when deciding how to handle unexpected situations is that using a `try/catch` block is +much slower than using conditional branching to handle those situations. +Below there are more examples of handling exceptions with a `try/catch` block: ```jldoctest -julia> f(x) = try - sqrt(x) - catch - sqrt(complex(x, 0)) +julia> try + sqrt("ten") + catch e + println("You should have entered a numeric value") end -f (generic function with 1 method) - -julia> f(1) -1.0 - -julia> f(-1) -0.0 + 1.0im +You should have entered a numeric value ``` -이 함수를 계산하는 실제 코드에서는 예외를 잡는 대신 `x`와 0을 비교한다는 점에 유의해야 합니다. 단순히 비교하고 분기하는 것보다 예외는 훨씬 느립니다. - 또한 `try/catch`문은 `Exception`이 변수에 저장되도록 합니다. 이 고안된 예제에서, 다음 예제는 `x`가 색인 가능한 경우 `x`의 두 번째 요소의 제곱근을 계산하고, 그렇지 않으면 `x`가 실수임을 가정하고 제곱근을 반환합니다. ```jldoctest diff --git a/src/manual/environment-variables.md b/src/manual/environment-variables.md index d92260d..7bc47ba 100644 --- a/src/manual/environment-variables.md +++ b/src/manual/environment-variables.md @@ -1,25 +1,26 @@ # Environment Variables -Julia may be configured with a number of environment variables, either in the -usual way of the operating system, or in a portable way from within Julia. -Suppose you want to set the environment variable `JULIA_EDITOR` to -`vim`, then either type `ENV["JULIA_EDITOR"] = "vim"` for instance in the REPL -to make this change on a case by case basis, or add the same to the user -configuration file `~/.julia/config/startup.jl` in the user's home directory to have -a permanent effect. The current value of the same environment variable is +Julia can be configured with a number of environment variables, set either in +the usual way for each operating system, or in a portable way from within Julia. +Supposing that you want to set the environment variable `JULIA_EDITOR` to `vim`, +you can type `ENV["JULIA_EDITOR"] = "vim"` (for instance, in the REPL) to make +this change on a case by case basis, or add the same to the user configuration +file `~/.julia/config/startup.jl` in the user's home directory to have a +permanent effect. The current value of the same environment variable can be determined by evaluating `ENV["JULIA_EDITOR"]`. The environment variables that Julia uses generally start with `JULIA`. If -[`InteractiveUtils.versioninfo`](@ref) is called with `verbose` equal to `true`, then the +[`InteractiveUtils.versioninfo`](@ref) is called with the keyword `verbose=true`, then the output will list defined environment variables relevant for Julia, including those for which `JULIA` appears in the name. !!! note - Some variables, such as `JULIA_NUM_THREADS` and `JULIA_PROJECT` need to be set before Julia + Some variables, such as `JULIA_NUM_THREADS` and `JULIA_PROJECT`, need to be set before Julia starts, therefore adding these to `~/.julia/config/startup.jl` is too late in the startup process. - These must either be set manually before launching Julia through bash with - `export JULIA_NUM_THREADS=4` etc. or added to `-/.bashrc` and/or `~/.bash_profile` to achieve persistence. + In Bash, environment variables can either be set manually by running, e.g., + `export JULIA_NUM_THREADS=4` before starting Julia, or by adding the same command to + `-/.bashrc` or `~/.bash_profile` to set the variable each time Bash is started. ## File locations @@ -76,7 +77,7 @@ and a global configuration search path of A directory path that points to the current Julia project. Setting this environment variable has the same effect as specifying the `--project` start-up -option, but `--project` has higher precedence. If the variable is set to `@.`, +option, but `--project` has higher precedence. If the variable is set to `@.` then Julia tries to find a project directory that contains `Project.toml` or `JuliaProject.toml` file from the current directory and its parents. See also the chapter on [Code Loading](@ref). @@ -88,8 +89,8 @@ the chapter on [Code Loading](@ref). ### `JULIA_LOAD_PATH` A separated list of absolute paths that are to be appended to the variable -[`LOAD_PATH`](@ref). (In Unix-like systems, the path separator is `:`; in -Windows systems, the path separator is `;`.) The `LOAD_PATH` variable is where +[`LOAD_PATH`](@ref). (In Unix-like systems, `:` is the path separator; in +Windows systems, `;` is the path separator.) The `LOAD_PATH` variable is where [`Base.require`](@ref) and `Base.load_in_path()` look for code; it defaults to the absolute path `$JULIA_HOME/../share/julia/stdlib/v$(VERSION.major).$(VERSION.minor)` so that, @@ -185,7 +186,7 @@ affinitized. Otherwise, Julia lets the operating system handle thread policy. Environment variables that determine how REPL output should be formatted at the terminal. Generally, these variables should be set to [ANSI terminal escape sequences](http://ascii-table.com/ansi-escape-sequences.php). Julia provides -a high-level interface with much of the same functionality: see the section on +a high-level interface with much of the same functionality; see the section on [The Julia REPL](@ref). ### `JULIA_ERROR_COLOR` @@ -283,11 +284,10 @@ event listener for just-in-time (JIT) profiling. This environment variable only has an effect if Julia was compiled with JIT profiling support, using either - -* Intel's [VTune™ Amplifier](https://software.intel.com/en-us/intel-vtune-amplifier-xe) - (`USE_INTEL_JITEVENTS` set to `1` in the build configuration), or -* [OProfile](http://oprofile.sourceforge.net/news/) (`USE_OPROFILE_JITEVENTS` set to `1` - in the build configuration). + * Intel's [VTune™ Amplifier](https://software.intel.com/en-us/intel-vtune-amplifier-xe) + (`USE_INTEL_JITEVENTS` set to `1` in the build configuration), or + * [OProfile](http://oprofile.sourceforge.net/news/) (`USE_OPROFILE_JITEVENTS` set to `1` + in the build configuration). ### `JULIA_LLVM_ARGS` From 0e3704bf946832556fdba3626df5387185f8efef Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Tue, 18 Dec 2018 18:02:36 +0900 Subject: [PATCH 086/153] update Julia Commit a0b7a76103 --- codex/NEWS.md | 8 ++ codex/base/multi-threading.md | 19 ++-- codex/base/parallel.md | 38 ++++++-- codex/manual/code-loading.md | 161 +++++++++++++++++++--------------- codex/manual/faq.md | 3 +- codex/stdlib/Distributed.md | 4 - src/NEWS.md | 8 ++ src/base/multi-threading.md | 19 ++-- src/base/parallel.md | 38 ++++++-- src/manual/code-loading.md | 161 +++++++++++++++++++--------------- src/manual/faq.md | 3 +- src/stdlib/Distributed.md | 4 - 12 files changed, 278 insertions(+), 188 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index 3f11a8a..150601f 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -4,6 +4,14 @@ Julia v1.2 Release Notes New language features --------------------- +* The `extrema` function now accepts a function argument in the same manner as `minimum` and + `maximum` ([#30323](https://github.com/JuliaLang/julia/issues/30323)). + +Multi-threading changes +----------------------- + + * The `Condition` type now has a thread-safe replacement, accessed as `Threads.Condition`. + With that addition, task scheduling primitives such as `ReentrantLock` are now thread-safe ([#30061](https://github.com/JuliaLang/julia/issues/30061)). Language changes ---------------- diff --git a/codex/base/multi-threading.md b/codex/base/multi-threading.md index 508c2f3..93f36b5 100644 --- a/codex/base/multi-threading.md +++ b/codex/base/multi-threading.md @@ -1,4 +1,3 @@ - # Multi-Threading This experimental interface supports Julia's multi-threading capabilities. Types and functions @@ -8,6 +7,9 @@ described here might (and likely will) change in the future. Base.Threads.threadid Base.Threads.nthreads Base.Threads.@threads +``` + +```@docs Base.Threads.Atomic Base.Threads.atomic_cas! Base.Threads.atomic_xchg! @@ -28,20 +30,11 @@ Base.Threads.atomic_fence Base.@threadcall ``` -## Synchronization Primitives +# Low-level synchronization primitives + +These building blocks are used to create the regular synchronization objects. ```@docs -Base.Threads.AbstractLock -Base.lock -Base.unlock -Base.trylock -Base.islocked -Base.ReentrantLock Base.Threads.Mutex Base.Threads.SpinLock -Base.Threads.RecursiveSpinLock -Base.Semaphore -Base.acquire -Base.release ``` - diff --git a/codex/base/parallel.md b/codex/base/parallel.md index cd689e1..5a669b2 100644 --- a/codex/base/parallel.md +++ b/codex/base/parallel.md @@ -2,19 +2,47 @@ ```@docs Core.Task +Base.@task +Base.@async +Base.@sync +Base.asyncmap +Base.asyncmap! +Base.fetch(t::Task) Base.current_task Base.istaskdone Base.istaskstarted -Base.yield -Base.yieldto Base.task_local_storage(::Any) Base.task_local_storage(::Any, ::Any) Base.task_local_storage(::Function, ::Any, ::Any) +``` + +# Scheduling + +```@docs +Base.yield +Base.yieldto +Base.sleep +Base.wait +Base.timedwait + Base.Condition +Base.Threads.Condition Base.notify Base.schedule -Base.@task -Base.sleep + +Base.Event + +Base.Semaphore +Base.acquire +Base.release + +Base.AbstractLock +Base.lock +Base.unlock +Base.trylock +Base.islocked +Base.ReentrantLock + Base.Channel Base.put!(::Channel, ::Any) Base.take!(::Channel) @@ -22,6 +50,4 @@ Base.isready(::Channel) Base.fetch(::Channel) Base.close(::Channel) Base.bind(c::Channel, task::Task) -Base.asyncmap -Base.asyncmap! ``` diff --git a/codex/manual/code-loading.md b/codex/manual/code-loading.md index e88dbdc..7e2652a 100644 --- a/codex/manual/code-loading.md +++ b/codex/manual/code-loading.md @@ -1,66 +1,71 @@ # Code Loading -Julia has two mechanisms for loading code: +!!! note + This chapter covers the technical details of package loading. To install packages, use [`Pkg`](@ref Pkg), Julia's built-in package manager, to add packages to your active environment. To use packages already in your active environment, write `import X` or `using X`, as described in the [Modules documentation](@ref modules). -1. **Code inclusion:** e.g. `include("source.jl")`. Inclusion allows you to split a single program across multiple source files. The expression `include("source.jl")` causes the contents of the file `source.jl` to be evaluated in the global scope of the module where the `include` call occurs. If `include("source.jl")` is called multiple times, `source.jl` is evaluated multiple times. The included path, `source.jl`, is interpreted relative to the file where the `include` call occurs. This makes it simple to relocate a subtree of source files. In the REPL, included paths are interpreted relative to the current working directory, `pwd()`. -2. **Package loading:** e.g. `import X` or `using X`. The import mechanism allows you to load a package—i.e. an independent, reusable collection of Julia code, wrapped in a module—and makes the resulting module available by the name `X` inside of the importing module. If the same `X` package is imported multiple times in the same Julia session, it is only loaded the first time—on subsequent imports, the importing module gets a reference to the same module. Note though, that `import X` can load different packages in different contexts: `X` can refer to one package named `X` in the main project but potentially different packages named `X` in each dependency. More on this below. +## Definitions -Code inclusion is quite straightforward: it simply parses and evaluates a source file in the context of the caller. Package loading is built on top of code inclusion and is a lot more complex. Therefore, the rest of this chapter focuses on the behavior and mechanics of package loading. +Julia has two mechanisms for loading code: -!!! note - You only need to read this chapter if you want to understand the technical details of package loading. If you just want to install and use packages, simply use Julia's built-in package manager to add packages to your environment and write `import X` or `using X` in your code to load packages that you've added. +1. **Code inclusion:** e.g. `include("source.jl")`. Inclusion allows you to split a single program across multiple source files. The expression `include("source.jl")` causes the contents of the file `source.jl` to be evaluated in the global scope of the module where the `include` call occurs. If `include("source.jl")` is called multiple times, `source.jl` is evaluated multiple times. The included path, `source.jl`, is interpreted relative to the file where the `include` call occurs. This makes it simple to relocate a subtree of source files. In the REPL, included paths are interpreted relative to the current working directory, [`pwd()`](@ref). +2. **Package loading:** e.g. `import X` or `using X`. The import mechanism allows you to load a package—i.e. an independent, reusable collection of Julia code, wrapped in a module—and makes the resulting module available by the name `X` inside of the importing module. If the same `X` package is imported multiple times in the same Julia session, it is only loaded the first time—on subsequent imports, the importing module gets a reference to the same module. Note though, that `import X` can load different packages in different contexts: `X` can refer to one package named `X` in the main project but potentially to different packages also named `X` in each dependency. More on this below. -A *package* is a source tree with a standard layout providing functionality that can be reused by other Julia projects. A package is loaded by `import X` or `using X` statements. These statements also make the module named `X`, which results from loading the package code, available within the module where the import statement occurs. The meaning of `X` in `import X` is context-dependent: which `X` package is loaded depends on what code the statement occurs in. The effect of `import X` depends on two questions: +Code inclusion is quite straightforward and simple: it evaluates the given source file in the context of the caller. Package loading is built on top of code inclusion and serves a [different purpose](@ref modules). The rest of this chapter focuses on the behavior and mechanics of package loading. -1. **What** package is `X` in this context? -2. **Where** can that `X` package be found? +A *package* is a source tree with a standard layout providing functionality that can be reused by other Julia projects. A package is loaded by `import X` or `using X` statements. These statements also make the module named `X`—which results from loading the package code—available within the module where the import statement occurs. The meaning of `X` in `import X` is context-dependent: which `X` package is loaded depends on what code the statement occurs in. Thus, handling of `import X` happens in two stages: first, it determines **what** package is defined to be `X` in this context; second, it determines **where** that particular `X` package is found. + +These questions are answered by searching through the project environments listed in [`LOAD_PATH`](@ref) for project files (`Project.toml` or `JuliaProject.toml`), manifest files (`Manifest.toml` or `JuliaManifest.toml`), or folders of source files. -Understanding how Julia answers these questions is key to understanding package loading. ## Federation of packages -Julia supports federated management of packages. This means that multiple independent parties can maintain both public and private packages and registries of them, and that projects can depend on a mix of public and private packages from different registries. Packages from various registries are installed and managed using a common set of tools and workflows. The `Pkg` package manager ships with Julia 0.7/1.0 and lets you install and manage your projects' dependencies. It does this by creating and manipulating project files that describe what your project depends on, and manifest files that snapshot exact versions of your project's complete dependency graph. +Most of the time, a package is uniquely identifiable simply from its name. However, sometimes a project might encounter a situation where it needs to use two different packages that share the same name. While you might be able fix this by renaming one of the packages, being forced to do so can be highly disruptive in a large, shared code base. Instead, Julia's code loading mechanism allows the same package name to refer to different packages in different components of an application. + +Julia supports federated package management, which means that multiple independent parties can maintain both public and private packages and registries of packages, and that projects can depend on a mix of public and private packages from different registries. Packages from various registries are installed and managed using a common set of tools and workflows. The `Pkg` package manager that ships with Julia lets you install and manage your projects' dependencies. It assists in creating and manipulating project files (which describe what other projects that your project depends on), and manifest files (which snapshot exact versions of your project's complete dependency graph). -One consequence of federation is that there cannot be a central authority for package naming. Different entities may use the same name to refer to unrelated packages. This possibility is unavoidable since these entities do not coordinate and may not even know about each other. Because of the lack of a central naming authority, a single project can quite possibly end up depending on different packages that have the same name. Julia's package loading mechanism handles this by not requiring package names to be globally unique, even within the dependency graph of a single project. Instead, packages are identified by [universally unique identifiers](https://en.wikipedia.org/wiki/Universally_unique_identifier) (UUIDs) which are assigned to them before they are registered. The question *"what is `X`?"* is answered by determining the UUID of `X`. +One consequence of federation is that there cannot be a central authority for package naming. Different entities may use the same name to refer to unrelated packages. This possibility is unavoidable since these entities do not coordinate and may not even know about each other. Because of the lack of a central naming authority, a single project may end up depending on different packages that have the same name. Julia's package loading mechanism does not require package names to be globally unique, even within the dependency graph of a single project. Instead, packages are identified by [universally unique identifiers](https://en.wikipedia.org/wiki/Universally_unique_identifier) (UUIDs), which get assigned when each package is created. Usually you won't have to work directly with these somewhat cumbersome 128-bit identifiers since `Pkg` will take care of generating and tracking them for you. However, these UUIDs provide the definitive answer to the question of *"what package does `X` refer to?"* -Since the decentralized naming problem is somewhat abstract, it may help to walk through a concrete scenario to understand the issue. Suppose you're developing an application called `App`, which uses two packages: `Pub` and `Priv`. `Priv` is a private package that you created, whereas `Pub` is a public package that you use but don't control. When you created `Priv`, there was no public package by that name. Subsequently, however, an unrelated package also named `Priv` has been published and become popular. In fact, the `Pub` package has started to use it. Therefore, when you next upgrade `Pub` to get the latest bug fixes and features, `App` will end up—through no action of yours other than upgrading—depending on two different packages named `Priv`. `App` has a direct dependency on your private `Priv` package, and an indirect dependency, through `Pub`, on the new public `Priv` package. Since these two `Priv` packages are different but both required for `App` to continue working correctly, the expression `import Priv` must refer to different `Priv` packages depending on whether it occurs in `App`'s code or in `Pub`'s code. Julia's package loading mechanism allows this by distinguishing the two `Priv` packages by context and UUID. How this distinction works is determined by environments, as explained in the following sections. +Since the decentralized naming problem is somewhat abstract, it may help to walk through a concrete scenario to understand the issue. Suppose you're developing an application called `App`, which uses two packages: `Pub` and `Priv`. `Priv` is a private package that you created, whereas `Pub` is a public package that you use but don't control. When you created `Priv`, there was no public package by the name `Priv`. Subsequently, however, an unrelated package also named `Priv` has been published and become popular. In fact, the `Pub` package has started to use it. Therefore, when you next upgrade `Pub` to get the latest bug fixes and features, `App` will end up depending on two different packages named `Priv`—through no action of yours other than upgrading. `App` has a direct dependency on your private `Priv` package, and an indirect dependency, through `Pub`, on the new public `Priv` package. Since these two `Priv` packages are different but are both required for `App` to continue working correctly, the expression `import Priv` must refer to different `Priv` packages depending on whether it occurs in `App`'s code or in `Pub`'s code. To handle this, Julia's package loading mechanism distinguishes the two `Priv` packages by their UUID and picks the correct one based on its context (the module that called `import`). How this distinction works is determined by environments, as explained in the following sections. ## Environments -An *environment* determines what `import X` and `using X` mean in various code contexts and what files these statements cause to be loaded. Julia understands three kinds of environments: +An *environment* determines what `import X` and `using X` mean in various code contexts and what files these statements cause to be loaded. Julia understands two kinds of environments: + +1. **A project environment** is a directory with a project file and an optional manifest file, and forms an *explicit environement*. The project file determines what the names and identities of the direct dependencies of a project are. The manifest file, if present, gives a complete dependency graph, including all direct and indirect dependencies, exact versions of each dependency, and sufficient information to locate and load the correct version. +2. **A package directory** is a directory containing the source trees of a set of packages as subdirectories, and forms an *implicit environment*. If `X` is a subdirectory of a package directory and `X/src/X.jl` exists, then the package `X` is available in the package directory environment and `X/src/X.jl` is the source file by which it is loaded. -1. **A project environment** is a directory with a project file and an optional manifest file. The project file determines what the names and identities of the direct dependencies of a project are. The manifest file, if present, gives a complete dependency graph, including all direct and indirect dependencies, exact versions of each dependency, and sufficient information to locate and load the correct version. -2. **A package directory** is a directory containing the source trees of a set of packages as subdirectories. This kind of environment was the only kind that existed in Julia 0.6 and earlier. If `X` is a subdirectory of a package directory and `X/src/X.jl` exists, then the package `X` is available in the package directory environment and `X/src/X.jl` is the source file by which it is loaded. -3. **A stacked environment** is an ordered set of project environments and package directories, overlaid to make a single composite environment in which all the packages available in its constituent environments are available. Julia's load path is a stacked environment, for example. +These can be intermixed to create **a stacked environment**: an ordered set of project environments and package directories, overlaid to make a single composite environment. The precedence and visibility rules then combine to determine which packages are available and where they get loaded from. Julia's load path forms a stacked environment, for example. -These three kinds of environment each serve a different purpose: +These environment each serve a different purpose: -* Project environments provide **reproducibility.** By checking a project environment into version control—e.g. a git repository—along with the rest of the project's source code, you can reproduce the exact state of the project _and_ all of its dependencies since the manifest file captures the exact version of every dependency. -* Package directories provide low-overhead **convenience** when a project environment isn't needed. Package directories are handy when you have a set of packages that you just want to put somewhere and use them as they are, without having to create and maintain a project environment for them. -* Stacked environments allow for **augmentation** of the primary environment with additional tools. You can push an environment including development tools onto the stack and they will be available from the REPL and scripts but not from inside packages. +* Project environments provide **reproducibility**. By checking a project environment into version control—e.g. a git repository—along with the rest of the project's source code, you can reproduce the exact state of the project and all of its dependencies. The manifest file, in particular, captures the exact version of every dependency, identified by a cryptographic hash of its source tree, which makes it possible for `Pkg` to retrieve the correct versions and be sure that you are running the exact code that was recorded for all dependencies. +* Package directories provide **convenience** when a full carefully-tracked project environment is unnecessary. They are useful when you want to put a set of packages somewhere and be able to directly use them, without needing to create a project environment for them. +* Stacked environments allow for **adding** tools to the primary environment. You can push an environment of development tools onto the end of the stack to make them available from the REPL and scripts, but not from inside packages. -As an abstraction, an environment provides three maps: `roots`, `graph` and `paths`. When resolving the meaning of `import X`, `roots` and `graph` are used to determine the identity of `X` and answer the question *"what is `X`?"*, while the `paths` map is used to locate the source code of `X` and answer the question *"where is `X`?"* The specific roles of the three maps are: +At a high-level, each environment conceptually defines three maps: roots, graph and paths. When resolving the meaning of `import X`, the roots and graph maps are used to determine the identity of `X`, while the paths map is used to locate the source code of `X`. The specific roles of the three maps are: - **roots:** `name::Symbol` ⟶ `uuid::UUID` - An environment's `roots` map assigns package names to UUIDs for all the top-level dependencies that the environment makes available to the main project (i.e. the ones that can be loaded in `Main`). When Julia encounters `import X` in the main project, it looks up the identity of `X` as `roots[:X]`. + An environment's roots map assigns package names to UUIDs for all the top-level dependencies that the environment makes available to the main project (i.e. the ones that can be loaded in `Main`). When Julia encounters `import X` in the main project, it looks up the identity of `X` as `roots[:X]`. - **graph:** `context::UUID` ⟶ `name::Symbol` ⟶ `uuid::UUID` - An environment's `graph` is a multilevel map which assigns, for each `context` UUID, a map from names to UUIDs, similar to the `roots` map but specific to that `context`. When Julia sees `import X` in the code of the package whose UUID is `context`, it looks up the identity of `X` as `graph[context][:X]`. In particular, this means that `import X` can refer to different packages depending on `context`. + An environment's graph is a multilevel map which assigns, for each `context` UUID, a map from names to UUIDs, similar to the roots map but specific to that `context`. When Julia sees `import X` in the code of the package whose UUID is `context`, it looks up the identity of `X` as `graph[context][:X]`. In particular, this means that `import X` can refer to different packages depending on `context`. - **paths:** `uuid::UUID` × `name::Symbol` ⟶ `path::String` - The `paths` map assigns to each package UUID-name pair, the location of that package's entry-point source file. After the identity of `X` in `import X` has been resolved to a UUID via `roots` or `graph` (depending on whether it is loaded from the main project or a dependency), Julia determines what file to load to acquire `X` by looking up `paths[uuid,:X]` in the environment. Including this file should create a module named `X`. Once this package is loaded, i.e. after its first import, any subsequent import resolving to the same `uuid` will simply create a new binding to the original already-loaded package module. + The paths map assigns to each package UUID-name pair, the location of that package's entry-point source file. After the identity of `X` in `import X` has been resolved to a UUID via roots or graph (depending on whether it is loaded from the main project or a dependency), Julia determines what file to load to acquire `X` by looking up `paths[uuid,:X]` in the environment. Including this file should define a module named `X`. Once this package is loaded, any subsequent import resolving to the same `uuid` will create a new binding to the already-loaded package module. Each kind of environment defines these three maps differently, as detailed in the following sections. !!! note - For ease of understanding, the examples throughout this chapter show full data structures for `roots`, `graph` and `paths`. However, for efficiency, Julia's package loading code does not actually create them. Instead, it queries them through internal APIs and lazily computes only as much of each structure as it needs to load a given package. + For ease of understanding, the examples throughout this chapter show full data structures for roots, graph and paths. However, Julia's package loading code does not explicitly create these. Instead, it lazily computes only as much of each structure as it needs to load a given package. ### Project environments -A project environment is determined by a directory containing a project file called `Project.toml`, and optionally a manifest file called `Manifest.toml`. These files may also be called `JuliaProject.toml` and `JuliaManifest.toml`, in which case `Project.toml` and `Manifest.toml` are ignored. (This allows for coexistence with other tools that might consider files called `Project.toml` and `Manifest.toml` significant.) For pure Julia projects, however, the names `Project.toml` and `Manifest.toml` are preferred. The `roots`, `graph` and `paths` maps of a project environment are defined as follows. +A project environment is determined by a directory containing a project file called `Project.toml`, and optionally a manifest file called `Manifest.toml`. These files may also be called `JuliaProject.toml` and `JuliaManifest.toml`, in which case `Project.toml` and `Manifest.toml` are ignored. This allows for coexistence with other tools that might consider files called `Project.toml` and `Manifest.toml` significant. For pure Julia projects, however, the names `Project.toml` and `Manifest.toml` are preferred. + +The roots, graph and paths maps of a project environment are defined as follows: **The roots map** of the environment is determined by the contents of the project file, specifically, its top-level `name` and `uuid` entries and its `[deps]` section (all optional). Consider the following example project file for the hypothetical application, `App`, as described earlier: @@ -73,7 +78,7 @@ Priv = "ba13f791-ae1d-465a-978b-69c3ad90f72b" Pub = "c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1" ``` -This project file implies the following `roots` map, if it was represented by a Julia dictionary: +This project file implies the following roots map, if it was represented by a Julia dictionary: ```julia roots = Dict( @@ -83,9 +88,9 @@ roots = Dict( ) ``` -Given this `roots` map, in `App`'s code the statement `import Priv` will cause Julia to look up `roots[:Priv]`, which yields `ba13f791-ae1d-465a-978b-69c3ad90f72b`, the UUID of the `Priv` package that is to be loaded in that context. This UUID identifies which `Priv` package to load and use when the main application evaluates `import Priv`. +Given this roots map, in `App`'s code the statement `import Priv` will cause Julia to look up `roots[:Priv]`, which yields `ba13f791-ae1d-465a-978b-69c3ad90f72b`, the UUID of the `Priv` package that is to be loaded in that context. This UUID identifies which `Priv` package to load and use when the main application evaluates `import Priv`. -**The dependency graph** of a project environment is determined by the contents of the manifest file, if present. If there is no manifest file, `graph` is empty. A manifest file contains a stanza for each of a project's direct or indirect dependencies, including for each one, its UUID and a source tree hash or an explicit path to the source code. Consider the following example manifest file for `App`: +**The dependency graph** of a project environment is determined by the contents of the manifest file, if present. If there is no manifest file, graph is empty. A manifest file contains a stanza for each of a project's direct or indirect dependencies. For each dependency, the file lists the package's UUID and a source tree hash or an explicit path to the source code. Consider the following example manifest file for `App`: ```toml [[Priv]] # the private one @@ -115,29 +120,30 @@ version = "3.4.2" This manifest file describes a possible complete dependency graph for the `App` project: -- There are two different `Priv` packages that the application needs—a private one which is a direct dependency and a public one which is an indirect dependency through `Pub`: +- There are two different packages named `Priv` that the application uses. It uses a private package, which is a root dependency, and a public one, which is an indirect dependency through `Pub`. These are differentiated by their distinct UUIDs, and they have different deps: * The private `Priv` depends on the `Pub` and `Zebra` packages. * The public `Priv` has no dependencies. -- The application also depends on the `Pub` package, which in turn depends on the public `Priv ` and the same `Zebra` package which the private `Priv` package depends on. +- The application also depends on the `Pub` package, which in turn depends on the public `Priv ` and the same `Zebra` package that the private `Priv` package depends on. + -This dependency `graph` represented as a dictionary, looks like this: +This dependency graph represented as a dictionary, looks like this: ```julia -graph = Dict{UUID,Dict{Symbol,UUID}}( +graph = Dict( # Priv – the private one: - UUID("ba13f791-ae1d-465a-978b-69c3ad90f72b") => Dict{Symbol,UUID}( + UUID("ba13f791-ae1d-465a-978b-69c3ad90f72b") => Dict( :Pub => UUID("c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1"), :Zebra => UUID("f7a24cb4-21fc-4002-ac70-f0e3a0dd3f62"), ), # Priv – the public one: - UUID("2d15fe94-a1f7-436c-a4d8-07a9a496e01c") => Dict{Symbol,UUID}(), + UUID("2d15fe94-a1f7-436c-a4d8-07a9a496e01c") => Dict(), # Pub: - UUID("c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1") => Dict{Symbol,UUID}( + UUID("c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1") => Dict( :Priv => UUID("2d15fe94-a1f7-436c-a4d8-07a9a496e01c"), :Zebra => UUID("f7a24cb4-21fc-4002-ac70-f0e3a0dd3f62"), ), # Zebra: - UUID("f7a24cb4-21fc-4002-ac70-f0e3a0dd3f62") => Dict{Symbol,UUID}(), + UUID("f7a24cb4-21fc-4002-ac70-f0e3a0dd3f62") => Dict(), ) ``` @@ -151,26 +157,32 @@ and gets `2d15fe94-a1f7-436c-a4d8-07a9a496e01c`, which indicates that in the con What happens if `import Zebra` is evaluated in the main `App` code base? Since `Zebra` does not appear in the project file, the import will fail even though `Zebra` *does* appear in the manifest file. Moreover, if `import Zebra` occurs in the public `Priv` package—the one with UUID `2d15fe94-a1f7-436c-a4d8-07a9a496e01c`—then that would also fail since that `Priv` package has no declared dependencies in the manifest file and therefore cannot load any packages. The `Zebra` package can only be loaded by packages for which it appear as an explicit dependency in the manifest file: the `Pub` package and one of the `Priv` packages. -**The paths map** of a project environment is also determined by the manifest file if present and is empty if there is no manifest. The path of a package `uuid` named `X` is determined by these two rules: +**The paths map** of a project environment is extracted from the manifest file. The path of a package `uuid` named `X` is determined by these rules (in order): -1. If the manifest stanza matching `uuid` has a `path` entry, use that path relative to the manifest file. -2. Otherwise, if the manifest stanza matching `uuid` has a `git-tree-sha1` entry, compute a deterministic hash function of `uuid` and `git-tree-sha1`—call it `slug`—and look for `packages/X/$slug` in each directory in the Julia `DEPOT_PATH` global array. Use the first such directory that exists. +1. If the project file in the directory matches `uuid` and name `X`, then either: + - It has a toplevel `path` entry, then `uuid` will be mapped to that path, interpreted relative to the directory containing the project file. + - Otherwise, `uuid` is mapped to `src/X.jl` relative to the directory containing the project file. +2. If the above is not the case and the project file has a corresponding manifest file and the manifest contains a stanza matching `uuid` then: + - If it has a `path` entry, use that path (relative to the directory containing the manifest file). + - If it has a `git-tree-sha1` entry, compute a deterministic hash function of `uuid` and `git-tree-sha1`—call it `slug`—and look for a directory named `packages/X/$slug` in each directory in the Julia `DEPOT_PATH` global array. Use the first such directory that exists. -If applying these rules doesn't find a loadable path, the package should be considered not installed and the system should raise an error or prompt the user to install the appropriate package version. +If any of these result in success, the path to the source code entry point will be either that result, the relative path from that result plus `src/X.jl`; otherwise, there is no path mapping for `uuid`. When loading `X`, if no source code path is found, the lookup will fail, and the user may be prompted to install the appropriate package version or to take other corrective action (e.g. declaring `X` as a dependency). In the example manifest file above, to find the path of the first `Priv` package—the one with UUID `ba13f791-ae1d-465a-978b-69c3ad90f72b`—Julia looks for its stanza in the manifest file, sees that it has a `path` entry, looks at `deps/Priv` relative to the `App` project directory—let's suppose the `App` code lives in `/home/me/projects/App`—sees that `/home/me/projects/App/deps/Priv` exists and therefore loads `Priv` from there. -If, on the other hand, Julia was loading the *other* `Priv` package—the one with UUID `2d15fe94-a1f7-436c-a4d8-07a9a496e01c`—it finds its stanza in the manifest, see that it does *not* have a `path` entry, but that it does have a `git-tree-sha1` entry. It then computes the `slug` for this UUID/SHA-1 pair, which is `HDkr` (the exact details of this computation aren't important, but it is consistent and deterministic). This means that the path to this `Priv` package will be `packages/Priv/HDkr/src/Priv.jl` in one of the package depots. Suppose the contents of `DEPOT_PATH` is `["/home/me/.julia", "/usr/local/julia"]`; then Julia will look at the following paths to see if they exist: +If, on the other hand, Julia was loading the *other* `Priv` package—the one with UUID `2d15fe94-a1f7-436c-a4d8-07a9a496e01c`—it finds its stanza in the manifest, see that it does *not* have a `path` entry, but that it does have a `git-tree-sha1` entry. It then computes the `slug` for this UUID/SHA-1 pair, which is `HDkrT` (the exact details of this computation aren't important, but it is consistent and deterministic). This means that the path to this `Priv` package will be `packages/Priv/HDkrT/src/Priv.jl` in one of the package depots. Suppose the contents of `DEPOT_PATH` is `["/home/me/.julia", "/usr/local/julia"]`, then Julia will look at the following paths to see if they exist: -1. `/home/me/.julia/packages/Priv/HDkr/src/Priv.jl` -2. `/usr/local/julia/packages/Priv/HDkr/src/Priv.jl` +1. `/home/me/.julia/packages/Priv/HDkrT` +2. `/usr/local/julia/packages/Priv/HDkrT` -Julia uses the first of these that exists to load the public `Priv` package. +Julia uses the first of these that exists to try to load the public `Priv` package from the file `packages/Priv/HDKrT/src/Priv.jl` in the depot where it was found. -Here is a representation of the `paths` map for the `App` project environment: +Here is a representation of a possible paths map for our example `App` project environment, +as provided in the Manifest given above for the dependency graph, +after searching the local file system: ```julia -paths = Dict{Tuple{UUID,Symbol},String}( +paths = Dict( # Priv – the private one: (UUID("ba13f791-ae1d-465a-978b-69c3ad90f72b"), :Priv) => # relative entry-point inside `App` repo: @@ -190,26 +202,37 @@ paths = Dict{Tuple{UUID,Symbol},String}( ) ``` -This example map includes three different kinds of package locations: +This example map includes three different kinds of package locations (the first and third are part of the default load path): 1. The private `Priv` package is "[vendored](https://stackoverflow.com/a/35109534/659248)" inside the `App` repository. 2. The public `Priv` and `Zebra` packages are in the system depot, where packages installed and managed by the system administrator live. These are available to all users on the system. 3. The `Pub` package is in the user depot, where packages installed by the user live. These are only available to the user who installed them. + ### Package directories -Package directories provide a kind of environment that approximates package loading in Julia 0.6 and earlier, and which resembles package loading in many other dynamic languages. The set of packages available in a package directory corresponds to the set of subdirectories it contains that look like packages: if `X/src/X.jl` is a file in a package directory, then `X` is considered to be a package and `X/src/X.jl` is the file Julia loads to get `X`. Which packages can "see" each other as dependencies depends on whether they contain project files, and if they do, on what appears in those project files' `[deps]` sections. +Package directories provide a simpler kind of environment without the ability to handle name collisions. In a package directory, the set of top-level packages is the set of subdirectories that "look like" packages. A package `X` is exists in a package directory if the directory contains one of the following "entry point" files: + +- `X.jl` +- `X/src/X.jl` +- `X.jl/src/X.jl` -**The roots map** is determined by the subdirectories `X` of a package directory for which `X/src/X.jl` exists and whether `X/Project.toml` exists and has a top-level `uuid` entry. Specifically `:X => uuid` goes in `roots` for each such `X` where `uuid` is defined as: +Which dependencies a package in a package directory can import depends on whether the package contains a project file: + +* If it has a project file, it can only import those packages which are identified in the `[deps]` section of the project file. +* If it does not have a project file, it can import any top-level package—i.e. the same packages that can be loaded in `Main` or the REPL. + +**The roots map** is determined by examining the contents of the package directory to generate a list of all packages that exist. +Additionally, a UUID will be assigned to each entry as follows: For a given package found inside the folder `X`... 1. If `X/Project.toml` exists and has a `uuid` entry, then `uuid` is that value. -2. If `X/Project.toml` exists and but does *not* have a top-level UUID entry, `uuid` is a dummy UUID generated by hashing the canonical path of `X/Project.toml`. -3. If `X/Project.toml` does not exist, then `uuid` is the all-zero [nil UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Nil_UUID). +2. If `X/Project.toml` exists and but does *not* have a top-level UUID entry, `uuid` is a dummy UUID generated by hashing the canonical (real) path to `X/Project.toml`. +3. Otherwise (if `Project.toml` does not exist), then `uuid` is the all-zero [nil UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Nil_UUID). **The dependency graph** of a project directory is determined by the presence and contents of project files in the subdirectory of each package. The rules are: -- If a package subdirectory has no project file, then it is omitted from `graph` and import statements in its code are treated as top-level, the same as the main project and REPL. -- If a package subdirectory has a project file, then the `graph` entry for its UUID is the `[deps]` map of the project file, which is considered to be empty if the section is absent. +- If a package subdirectory has no project file, then it is omitted from graph and import statements in its code are treated as top-level, the same as the main project and REPL. +- If a package subdirectory has a project file, then the graph entry for its UUID is the `[deps]` map of the project file, which is considered to be empty if the section is absent. As an example, suppose a package directory has the following structure and content: @@ -246,10 +269,10 @@ Dingo/ # no imports ``` -Here is a corresponding `roots` structure, represented as a dictionary: +Here is a corresponding roots structure, represented as a dictionary: ```julia -roots = Dict{Symbol,UUID}( +roots = Dict( :Aardvark => UUID("00000000-0000-0000-0000-000000000000"), # no project file, nil UUID :Bobcat => UUID("85ad11c7-31f6-5d08-84db-0a4914d4cadf"), # dummy UUID based on path :Cobra => UUID("4725e24d-f727-424b-bca0-c4307a3456fa"), # UUID from project file @@ -257,21 +280,21 @@ roots = Dict{Symbol,UUID}( ) ``` -Here is the corresponding `graph` structure, represented as a dictionary: +Here is the corresponding graph structure, represented as a dictionary: ```julia -graph = Dict{UUID,Dict{Symbol,UUID}}( +graph = Dict( # Bobcat: - UUID("85ad11c7-31f6-5d08-84db-0a4914d4cadf") => Dict{Symbol,UUID}( + UUID("85ad11c7-31f6-5d08-84db-0a4914d4cadf") => Dict( :Cobra => UUID("4725e24d-f727-424b-bca0-c4307a3456fa"), :Dingo => UUID("7a7925be-828c-4418-bbeb-bac8dfc843bc"), ), # Cobra: - UUID("4725e24d-f727-424b-bca0-c4307a3456fa") => Dict{Symbol,UUID}( + UUID("4725e24d-f727-424b-bca0-c4307a3456fa") => Dict( :Dingo => UUID("7a7925be-828c-4418-bbeb-bac8dfc843bc"), ), # Dingo: - UUID("7a7925be-828c-4418-bbeb-bac8dfc843bc") => Dict{Symbol,UUID}(), + UUID("7a7925be-828c-4418-bbeb-bac8dfc843bc") => Dict(), ) ``` @@ -293,7 +316,7 @@ Observe the following specific instances of these rules in our example: **The paths map** in a package directory is simple: it maps subdirectory names to their corresponding entry-point paths. In other words, if the path to our example project directory is `/home/me/animals` then the `paths` map could be represented by this dictionary: ```julia -paths = Dict{Tuple{UUID,Symbol},String}( +paths = Dict( (UUID("00000000-0000-0000-0000-000000000000"), :Aardvark) => "/home/me/AnimalPackages/Aardvark/src/Aardvark.jl", (UUID("85ad11c7-31f6-5d08-84db-0a4914d4cadf"), :Bobcat) => @@ -309,9 +332,9 @@ Since all packages in a package directory environment are, by definition, subdir ### Environment stacks -The third and final kind of environment is one that combines other environments by overlaying several of them, making the packages in each available in a single composite environment. These composite environments are called *environment stacks*. The Julia `LOAD_PATH` global defines an environment stack—the environment in which the Julia process operates. If you want your Julia process to have access only to the packages in one project or package directory, make it the only entry in `LOAD_PATH`. It is often quite useful, however, to have access to some of your favorite tools—standard libraries, profilers, debuggers, personal utilities, etc.—even if they are not dependencies of the project you're working on. By pushing an environment containing these tools onto the load path, you immediately have access to them in top-level code without needing to add them to your project. +The third and final kind of environment is one that combines other environments by overlaying several of them, making the packages in each available in a single composite environment. These composite environments are called *environment stacks*. The Julia `LOAD_PATH` global defines an environment stack—the environment in which the Julia process operates. If you want your Julia process to have access only to the packages in one project or package directory, make it the only entry in `LOAD_PATH`. It is often quite useful, however, to have access to some of your favorite tools—standard libraries, profilers, debuggers, personal utilities, etc.—even if they are not dependencies of the project you're working on. By adding an environment containing these tools to the load path, you immediately have access to them in top-level code without needing to add them to your project. -The mechanism for combining the `roots`, `graph` and `paths` data structures of the components of an environment stack is simple: they are simply merged as dictionaries, favoring earlier entries over later ones in the case of key collisions. In other words, if we have `stack = [env₁, env₂, …]` then we have: +The mechanism for combining the roots, graph and paths data structures of the components of an environment stack is simple: they are merged as dictionaries, favoring earlier entries over later ones in the case of key collisions. In other words, if we have `stack = [env₁, env₂, …]` then we have: ```julia roots = reduce(merge, reverse([roots₁, roots₂, …])) @@ -319,13 +342,13 @@ graph = reduce(merge, reverse([graph₁, graph₂, …])) paths = reduce(merge, reverse([paths₁, paths₂, …])) ``` -The subscripted `rootsᵢ`, `graphᵢ` and `pathsᵢ` variables correspond to the subscripted environments, `envᵢ`, contained `stack`. The `reverse` is present because `merge` favors the last argument rather than first when there are collisions between keys in its argument dictionaries. That's all there is to stacked environments. There are a couple of noteworthy features of this design: +The subscripted `rootsᵢ`, `graphᵢ` and `pathsᵢ` variables correspond to the subscripted environments, `envᵢ`, contained in `stack`. The `reverse` is present because `merge` favors the last argument rather than first when there are collisions between keys in its argument dictionaries. There are a couple of noteworthy features of this design: 1. The *primary environment*—i.e. the first environment in a stack—is faithfully embedded in a stacked environment. The full dependency graph of the first environment in a stack is guaranteed to be included intact in the stacked environment including the same versions of all dependencies. -2. Packages in non-primary environments can end up using incompatible versions of their dependencies even if their own environments are entirely compatible. This can happen when one of their dependencies is shadowed by a version in an earlier environment in the stack. +2. Packages in non-primary environments can end up using incompatible versions of their dependencies even if their own environments are entirely compatible. This can happen when one of their dependencies is shadowed by a version in an earlier environment in the stack (either by graph or path, or both). -Since the primary environment is typically the environment of a project you're working on, while environments later in the stack contain additional tools, this is the right tradeoff: it's better to break your dev tools but keep the project working. When such incompatibilities occur, you'll typically want to upgrade your dev tools to versions that are compatible with the main project. +Since the primary environment is typically the environment of a project you're working on, while environments later in the stack contain additional tools, this is the right trade-off: it's better to break your development tools but keep the project working. When such incompatibilities occur, you'll typically want to upgrade your dev tools to versions that are compatible with the main project. ## Conclusion -Federated package management and precise software reproducibility are difficult but worthy goals in a package system. In combination, these goals lead to a more complex package loading mechanism than most dynamic languages have, but it also yields scalability and reproducibility that is more commonly associated with static languages. Fortunately, most Julia users can remain oblivious to the technical details of code loading and simply use the built-in package manager to add a package `X` to the appropriate project and manifest files and then write `import X` to load `X` without a further thought. +Federated package management and precise software reproducibility are difficult but worthy goals in a package system. In combination, these goals lead to a more complex package loading mechanism than most dynamic languages have, but it also yields scalability and reproducibility that is more commonly associated with static languages. Typically, Julia users should be able to use the built-in package manager to manage their projects without needing a precise understanding of these interactions. A call to `Pkg.add("X")` will add to the appropriate project and manifest files, selected via `Pkg.activate("Y")`, so that a future call to `import X` will load `X` without further thought. diff --git a/codex/manual/faq.md b/codex/manual/faq.md index e6ae749..4db755c 100644 --- a/codex/manual/faq.md +++ b/codex/manual/faq.md @@ -774,8 +774,7 @@ julia> @sync for i in 1:3 You can lock your writes with a `ReentrantLock` like this: ```jldoctest -julia> l = ReentrantLock() -ReentrantLock(nothing, Condition(Any[]), 0) +julia> l = ReentrantLock(); julia> @sync for i in 1:3 @async begin diff --git a/codex/stdlib/Distributed.md b/codex/stdlib/Distributed.md index da0b822..4653a26 100644 --- a/codex/stdlib/Distributed.md +++ b/codex/stdlib/Distributed.md @@ -18,7 +18,6 @@ Distributed.pmap Distributed.RemoteException Distributed.Future Distributed.RemoteChannel -Distributed.wait Distributed.fetch(::Any) Distributed.remotecall(::Any, ::Integer, ::Any...) Distributed.remotecall_wait(::Any, ::Integer, ::Any...) @@ -38,13 +37,10 @@ Distributed.remotecall(::Any, ::AbstractWorkerPool, ::Any...) Distributed.remotecall_wait(::Any, ::AbstractWorkerPool, ::Any...) Distributed.remotecall_fetch(::Any, ::AbstractWorkerPool, ::Any...) Distributed.remote_do(::Any, ::AbstractWorkerPool, ::Any...) -Distributed.timedwait Distributed.@spawn Distributed.@spawnat Distributed.@fetch Distributed.@fetchfrom -Distributed.@async -Distributed.@sync Distributed.@distributed Distributed.@everywhere Distributed.clear!(::Any, ::Any; ::Any) diff --git a/src/NEWS.md b/src/NEWS.md index 3f11a8a..150601f 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -4,6 +4,14 @@ Julia v1.2 Release Notes New language features --------------------- +* The `extrema` function now accepts a function argument in the same manner as `minimum` and + `maximum` ([#30323](https://github.com/JuliaLang/julia/issues/30323)). + +Multi-threading changes +----------------------- + + * The `Condition` type now has a thread-safe replacement, accessed as `Threads.Condition`. + With that addition, task scheduling primitives such as `ReentrantLock` are now thread-safe ([#30061](https://github.com/JuliaLang/julia/issues/30061)). Language changes ---------------- diff --git a/src/base/multi-threading.md b/src/base/multi-threading.md index 508c2f3..93f36b5 100644 --- a/src/base/multi-threading.md +++ b/src/base/multi-threading.md @@ -1,4 +1,3 @@ - # Multi-Threading This experimental interface supports Julia's multi-threading capabilities. Types and functions @@ -8,6 +7,9 @@ described here might (and likely will) change in the future. Base.Threads.threadid Base.Threads.nthreads Base.Threads.@threads +``` + +```@docs Base.Threads.Atomic Base.Threads.atomic_cas! Base.Threads.atomic_xchg! @@ -28,20 +30,11 @@ Base.Threads.atomic_fence Base.@threadcall ``` -## Synchronization Primitives +# Low-level synchronization primitives + +These building blocks are used to create the regular synchronization objects. ```@docs -Base.Threads.AbstractLock -Base.lock -Base.unlock -Base.trylock -Base.islocked -Base.ReentrantLock Base.Threads.Mutex Base.Threads.SpinLock -Base.Threads.RecursiveSpinLock -Base.Semaphore -Base.acquire -Base.release ``` - diff --git a/src/base/parallel.md b/src/base/parallel.md index cd689e1..5a669b2 100644 --- a/src/base/parallel.md +++ b/src/base/parallel.md @@ -2,19 +2,47 @@ ```@docs Core.Task +Base.@task +Base.@async +Base.@sync +Base.asyncmap +Base.asyncmap! +Base.fetch(t::Task) Base.current_task Base.istaskdone Base.istaskstarted -Base.yield -Base.yieldto Base.task_local_storage(::Any) Base.task_local_storage(::Any, ::Any) Base.task_local_storage(::Function, ::Any, ::Any) +``` + +# Scheduling + +```@docs +Base.yield +Base.yieldto +Base.sleep +Base.wait +Base.timedwait + Base.Condition +Base.Threads.Condition Base.notify Base.schedule -Base.@task -Base.sleep + +Base.Event + +Base.Semaphore +Base.acquire +Base.release + +Base.AbstractLock +Base.lock +Base.unlock +Base.trylock +Base.islocked +Base.ReentrantLock + Base.Channel Base.put!(::Channel, ::Any) Base.take!(::Channel) @@ -22,6 +50,4 @@ Base.isready(::Channel) Base.fetch(::Channel) Base.close(::Channel) Base.bind(c::Channel, task::Task) -Base.asyncmap -Base.asyncmap! ``` diff --git a/src/manual/code-loading.md b/src/manual/code-loading.md index e88dbdc..7e2652a 100644 --- a/src/manual/code-loading.md +++ b/src/manual/code-loading.md @@ -1,66 +1,71 @@ # Code Loading -Julia has two mechanisms for loading code: +!!! note + This chapter covers the technical details of package loading. To install packages, use [`Pkg`](@ref Pkg), Julia's built-in package manager, to add packages to your active environment. To use packages already in your active environment, write `import X` or `using X`, as described in the [Modules documentation](@ref modules). -1. **Code inclusion:** e.g. `include("source.jl")`. Inclusion allows you to split a single program across multiple source files. The expression `include("source.jl")` causes the contents of the file `source.jl` to be evaluated in the global scope of the module where the `include` call occurs. If `include("source.jl")` is called multiple times, `source.jl` is evaluated multiple times. The included path, `source.jl`, is interpreted relative to the file where the `include` call occurs. This makes it simple to relocate a subtree of source files. In the REPL, included paths are interpreted relative to the current working directory, `pwd()`. -2. **Package loading:** e.g. `import X` or `using X`. The import mechanism allows you to load a package—i.e. an independent, reusable collection of Julia code, wrapped in a module—and makes the resulting module available by the name `X` inside of the importing module. If the same `X` package is imported multiple times in the same Julia session, it is only loaded the first time—on subsequent imports, the importing module gets a reference to the same module. Note though, that `import X` can load different packages in different contexts: `X` can refer to one package named `X` in the main project but potentially different packages named `X` in each dependency. More on this below. +## Definitions -Code inclusion is quite straightforward: it simply parses and evaluates a source file in the context of the caller. Package loading is built on top of code inclusion and is a lot more complex. Therefore, the rest of this chapter focuses on the behavior and mechanics of package loading. +Julia has two mechanisms for loading code: -!!! note - You only need to read this chapter if you want to understand the technical details of package loading. If you just want to install and use packages, simply use Julia's built-in package manager to add packages to your environment and write `import X` or `using X` in your code to load packages that you've added. +1. **Code inclusion:** e.g. `include("source.jl")`. Inclusion allows you to split a single program across multiple source files. The expression `include("source.jl")` causes the contents of the file `source.jl` to be evaluated in the global scope of the module where the `include` call occurs. If `include("source.jl")` is called multiple times, `source.jl` is evaluated multiple times. The included path, `source.jl`, is interpreted relative to the file where the `include` call occurs. This makes it simple to relocate a subtree of source files. In the REPL, included paths are interpreted relative to the current working directory, [`pwd()`](@ref). +2. **Package loading:** e.g. `import X` or `using X`. The import mechanism allows you to load a package—i.e. an independent, reusable collection of Julia code, wrapped in a module—and makes the resulting module available by the name `X` inside of the importing module. If the same `X` package is imported multiple times in the same Julia session, it is only loaded the first time—on subsequent imports, the importing module gets a reference to the same module. Note though, that `import X` can load different packages in different contexts: `X` can refer to one package named `X` in the main project but potentially to different packages also named `X` in each dependency. More on this below. -A *package* is a source tree with a standard layout providing functionality that can be reused by other Julia projects. A package is loaded by `import X` or `using X` statements. These statements also make the module named `X`, which results from loading the package code, available within the module where the import statement occurs. The meaning of `X` in `import X` is context-dependent: which `X` package is loaded depends on what code the statement occurs in. The effect of `import X` depends on two questions: +Code inclusion is quite straightforward and simple: it evaluates the given source file in the context of the caller. Package loading is built on top of code inclusion and serves a [different purpose](@ref modules). The rest of this chapter focuses on the behavior and mechanics of package loading. -1. **What** package is `X` in this context? -2. **Where** can that `X` package be found? +A *package* is a source tree with a standard layout providing functionality that can be reused by other Julia projects. A package is loaded by `import X` or `using X` statements. These statements also make the module named `X`—which results from loading the package code—available within the module where the import statement occurs. The meaning of `X` in `import X` is context-dependent: which `X` package is loaded depends on what code the statement occurs in. Thus, handling of `import X` happens in two stages: first, it determines **what** package is defined to be `X` in this context; second, it determines **where** that particular `X` package is found. + +These questions are answered by searching through the project environments listed in [`LOAD_PATH`](@ref) for project files (`Project.toml` or `JuliaProject.toml`), manifest files (`Manifest.toml` or `JuliaManifest.toml`), or folders of source files. -Understanding how Julia answers these questions is key to understanding package loading. ## Federation of packages -Julia supports federated management of packages. This means that multiple independent parties can maintain both public and private packages and registries of them, and that projects can depend on a mix of public and private packages from different registries. Packages from various registries are installed and managed using a common set of tools and workflows. The `Pkg` package manager ships with Julia 0.7/1.0 and lets you install and manage your projects' dependencies. It does this by creating and manipulating project files that describe what your project depends on, and manifest files that snapshot exact versions of your project's complete dependency graph. +Most of the time, a package is uniquely identifiable simply from its name. However, sometimes a project might encounter a situation where it needs to use two different packages that share the same name. While you might be able fix this by renaming one of the packages, being forced to do so can be highly disruptive in a large, shared code base. Instead, Julia's code loading mechanism allows the same package name to refer to different packages in different components of an application. + +Julia supports federated package management, which means that multiple independent parties can maintain both public and private packages and registries of packages, and that projects can depend on a mix of public and private packages from different registries. Packages from various registries are installed and managed using a common set of tools and workflows. The `Pkg` package manager that ships with Julia lets you install and manage your projects' dependencies. It assists in creating and manipulating project files (which describe what other projects that your project depends on), and manifest files (which snapshot exact versions of your project's complete dependency graph). -One consequence of federation is that there cannot be a central authority for package naming. Different entities may use the same name to refer to unrelated packages. This possibility is unavoidable since these entities do not coordinate and may not even know about each other. Because of the lack of a central naming authority, a single project can quite possibly end up depending on different packages that have the same name. Julia's package loading mechanism handles this by not requiring package names to be globally unique, even within the dependency graph of a single project. Instead, packages are identified by [universally unique identifiers](https://en.wikipedia.org/wiki/Universally_unique_identifier) (UUIDs) which are assigned to them before they are registered. The question *"what is `X`?"* is answered by determining the UUID of `X`. +One consequence of federation is that there cannot be a central authority for package naming. Different entities may use the same name to refer to unrelated packages. This possibility is unavoidable since these entities do not coordinate and may not even know about each other. Because of the lack of a central naming authority, a single project may end up depending on different packages that have the same name. Julia's package loading mechanism does not require package names to be globally unique, even within the dependency graph of a single project. Instead, packages are identified by [universally unique identifiers](https://en.wikipedia.org/wiki/Universally_unique_identifier) (UUIDs), which get assigned when each package is created. Usually you won't have to work directly with these somewhat cumbersome 128-bit identifiers since `Pkg` will take care of generating and tracking them for you. However, these UUIDs provide the definitive answer to the question of *"what package does `X` refer to?"* -Since the decentralized naming problem is somewhat abstract, it may help to walk through a concrete scenario to understand the issue. Suppose you're developing an application called `App`, which uses two packages: `Pub` and `Priv`. `Priv` is a private package that you created, whereas `Pub` is a public package that you use but don't control. When you created `Priv`, there was no public package by that name. Subsequently, however, an unrelated package also named `Priv` has been published and become popular. In fact, the `Pub` package has started to use it. Therefore, when you next upgrade `Pub` to get the latest bug fixes and features, `App` will end up—through no action of yours other than upgrading—depending on two different packages named `Priv`. `App` has a direct dependency on your private `Priv` package, and an indirect dependency, through `Pub`, on the new public `Priv` package. Since these two `Priv` packages are different but both required for `App` to continue working correctly, the expression `import Priv` must refer to different `Priv` packages depending on whether it occurs in `App`'s code or in `Pub`'s code. Julia's package loading mechanism allows this by distinguishing the two `Priv` packages by context and UUID. How this distinction works is determined by environments, as explained in the following sections. +Since the decentralized naming problem is somewhat abstract, it may help to walk through a concrete scenario to understand the issue. Suppose you're developing an application called `App`, which uses two packages: `Pub` and `Priv`. `Priv` is a private package that you created, whereas `Pub` is a public package that you use but don't control. When you created `Priv`, there was no public package by the name `Priv`. Subsequently, however, an unrelated package also named `Priv` has been published and become popular. In fact, the `Pub` package has started to use it. Therefore, when you next upgrade `Pub` to get the latest bug fixes and features, `App` will end up depending on two different packages named `Priv`—through no action of yours other than upgrading. `App` has a direct dependency on your private `Priv` package, and an indirect dependency, through `Pub`, on the new public `Priv` package. Since these two `Priv` packages are different but are both required for `App` to continue working correctly, the expression `import Priv` must refer to different `Priv` packages depending on whether it occurs in `App`'s code or in `Pub`'s code. To handle this, Julia's package loading mechanism distinguishes the two `Priv` packages by their UUID and picks the correct one based on its context (the module that called `import`). How this distinction works is determined by environments, as explained in the following sections. ## Environments -An *environment* determines what `import X` and `using X` mean in various code contexts and what files these statements cause to be loaded. Julia understands three kinds of environments: +An *environment* determines what `import X` and `using X` mean in various code contexts and what files these statements cause to be loaded. Julia understands two kinds of environments: + +1. **A project environment** is a directory with a project file and an optional manifest file, and forms an *explicit environement*. The project file determines what the names and identities of the direct dependencies of a project are. The manifest file, if present, gives a complete dependency graph, including all direct and indirect dependencies, exact versions of each dependency, and sufficient information to locate and load the correct version. +2. **A package directory** is a directory containing the source trees of a set of packages as subdirectories, and forms an *implicit environment*. If `X` is a subdirectory of a package directory and `X/src/X.jl` exists, then the package `X` is available in the package directory environment and `X/src/X.jl` is the source file by which it is loaded. -1. **A project environment** is a directory with a project file and an optional manifest file. The project file determines what the names and identities of the direct dependencies of a project are. The manifest file, if present, gives a complete dependency graph, including all direct and indirect dependencies, exact versions of each dependency, and sufficient information to locate and load the correct version. -2. **A package directory** is a directory containing the source trees of a set of packages as subdirectories. This kind of environment was the only kind that existed in Julia 0.6 and earlier. If `X` is a subdirectory of a package directory and `X/src/X.jl` exists, then the package `X` is available in the package directory environment and `X/src/X.jl` is the source file by which it is loaded. -3. **A stacked environment** is an ordered set of project environments and package directories, overlaid to make a single composite environment in which all the packages available in its constituent environments are available. Julia's load path is a stacked environment, for example. +These can be intermixed to create **a stacked environment**: an ordered set of project environments and package directories, overlaid to make a single composite environment. The precedence and visibility rules then combine to determine which packages are available and where they get loaded from. Julia's load path forms a stacked environment, for example. -These three kinds of environment each serve a different purpose: +These environment each serve a different purpose: -* Project environments provide **reproducibility.** By checking a project environment into version control—e.g. a git repository—along with the rest of the project's source code, you can reproduce the exact state of the project _and_ all of its dependencies since the manifest file captures the exact version of every dependency. -* Package directories provide low-overhead **convenience** when a project environment isn't needed. Package directories are handy when you have a set of packages that you just want to put somewhere and use them as they are, without having to create and maintain a project environment for them. -* Stacked environments allow for **augmentation** of the primary environment with additional tools. You can push an environment including development tools onto the stack and they will be available from the REPL and scripts but not from inside packages. +* Project environments provide **reproducibility**. By checking a project environment into version control—e.g. a git repository—along with the rest of the project's source code, you can reproduce the exact state of the project and all of its dependencies. The manifest file, in particular, captures the exact version of every dependency, identified by a cryptographic hash of its source tree, which makes it possible for `Pkg` to retrieve the correct versions and be sure that you are running the exact code that was recorded for all dependencies. +* Package directories provide **convenience** when a full carefully-tracked project environment is unnecessary. They are useful when you want to put a set of packages somewhere and be able to directly use them, without needing to create a project environment for them. +* Stacked environments allow for **adding** tools to the primary environment. You can push an environment of development tools onto the end of the stack to make them available from the REPL and scripts, but not from inside packages. -As an abstraction, an environment provides three maps: `roots`, `graph` and `paths`. When resolving the meaning of `import X`, `roots` and `graph` are used to determine the identity of `X` and answer the question *"what is `X`?"*, while the `paths` map is used to locate the source code of `X` and answer the question *"where is `X`?"* The specific roles of the three maps are: +At a high-level, each environment conceptually defines three maps: roots, graph and paths. When resolving the meaning of `import X`, the roots and graph maps are used to determine the identity of `X`, while the paths map is used to locate the source code of `X`. The specific roles of the three maps are: - **roots:** `name::Symbol` ⟶ `uuid::UUID` - An environment's `roots` map assigns package names to UUIDs for all the top-level dependencies that the environment makes available to the main project (i.e. the ones that can be loaded in `Main`). When Julia encounters `import X` in the main project, it looks up the identity of `X` as `roots[:X]`. + An environment's roots map assigns package names to UUIDs for all the top-level dependencies that the environment makes available to the main project (i.e. the ones that can be loaded in `Main`). When Julia encounters `import X` in the main project, it looks up the identity of `X` as `roots[:X]`. - **graph:** `context::UUID` ⟶ `name::Symbol` ⟶ `uuid::UUID` - An environment's `graph` is a multilevel map which assigns, for each `context` UUID, a map from names to UUIDs, similar to the `roots` map but specific to that `context`. When Julia sees `import X` in the code of the package whose UUID is `context`, it looks up the identity of `X` as `graph[context][:X]`. In particular, this means that `import X` can refer to different packages depending on `context`. + An environment's graph is a multilevel map which assigns, for each `context` UUID, a map from names to UUIDs, similar to the roots map but specific to that `context`. When Julia sees `import X` in the code of the package whose UUID is `context`, it looks up the identity of `X` as `graph[context][:X]`. In particular, this means that `import X` can refer to different packages depending on `context`. - **paths:** `uuid::UUID` × `name::Symbol` ⟶ `path::String` - The `paths` map assigns to each package UUID-name pair, the location of that package's entry-point source file. After the identity of `X` in `import X` has been resolved to a UUID via `roots` or `graph` (depending on whether it is loaded from the main project or a dependency), Julia determines what file to load to acquire `X` by looking up `paths[uuid,:X]` in the environment. Including this file should create a module named `X`. Once this package is loaded, i.e. after its first import, any subsequent import resolving to the same `uuid` will simply create a new binding to the original already-loaded package module. + The paths map assigns to each package UUID-name pair, the location of that package's entry-point source file. After the identity of `X` in `import X` has been resolved to a UUID via roots or graph (depending on whether it is loaded from the main project or a dependency), Julia determines what file to load to acquire `X` by looking up `paths[uuid,:X]` in the environment. Including this file should define a module named `X`. Once this package is loaded, any subsequent import resolving to the same `uuid` will create a new binding to the already-loaded package module. Each kind of environment defines these three maps differently, as detailed in the following sections. !!! note - For ease of understanding, the examples throughout this chapter show full data structures for `roots`, `graph` and `paths`. However, for efficiency, Julia's package loading code does not actually create them. Instead, it queries them through internal APIs and lazily computes only as much of each structure as it needs to load a given package. + For ease of understanding, the examples throughout this chapter show full data structures for roots, graph and paths. However, Julia's package loading code does not explicitly create these. Instead, it lazily computes only as much of each structure as it needs to load a given package. ### Project environments -A project environment is determined by a directory containing a project file called `Project.toml`, and optionally a manifest file called `Manifest.toml`. These files may also be called `JuliaProject.toml` and `JuliaManifest.toml`, in which case `Project.toml` and `Manifest.toml` are ignored. (This allows for coexistence with other tools that might consider files called `Project.toml` and `Manifest.toml` significant.) For pure Julia projects, however, the names `Project.toml` and `Manifest.toml` are preferred. The `roots`, `graph` and `paths` maps of a project environment are defined as follows. +A project environment is determined by a directory containing a project file called `Project.toml`, and optionally a manifest file called `Manifest.toml`. These files may also be called `JuliaProject.toml` and `JuliaManifest.toml`, in which case `Project.toml` and `Manifest.toml` are ignored. This allows for coexistence with other tools that might consider files called `Project.toml` and `Manifest.toml` significant. For pure Julia projects, however, the names `Project.toml` and `Manifest.toml` are preferred. + +The roots, graph and paths maps of a project environment are defined as follows: **The roots map** of the environment is determined by the contents of the project file, specifically, its top-level `name` and `uuid` entries and its `[deps]` section (all optional). Consider the following example project file for the hypothetical application, `App`, as described earlier: @@ -73,7 +78,7 @@ Priv = "ba13f791-ae1d-465a-978b-69c3ad90f72b" Pub = "c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1" ``` -This project file implies the following `roots` map, if it was represented by a Julia dictionary: +This project file implies the following roots map, if it was represented by a Julia dictionary: ```julia roots = Dict( @@ -83,9 +88,9 @@ roots = Dict( ) ``` -Given this `roots` map, in `App`'s code the statement `import Priv` will cause Julia to look up `roots[:Priv]`, which yields `ba13f791-ae1d-465a-978b-69c3ad90f72b`, the UUID of the `Priv` package that is to be loaded in that context. This UUID identifies which `Priv` package to load and use when the main application evaluates `import Priv`. +Given this roots map, in `App`'s code the statement `import Priv` will cause Julia to look up `roots[:Priv]`, which yields `ba13f791-ae1d-465a-978b-69c3ad90f72b`, the UUID of the `Priv` package that is to be loaded in that context. This UUID identifies which `Priv` package to load and use when the main application evaluates `import Priv`. -**The dependency graph** of a project environment is determined by the contents of the manifest file, if present. If there is no manifest file, `graph` is empty. A manifest file contains a stanza for each of a project's direct or indirect dependencies, including for each one, its UUID and a source tree hash or an explicit path to the source code. Consider the following example manifest file for `App`: +**The dependency graph** of a project environment is determined by the contents of the manifest file, if present. If there is no manifest file, graph is empty. A manifest file contains a stanza for each of a project's direct or indirect dependencies. For each dependency, the file lists the package's UUID and a source tree hash or an explicit path to the source code. Consider the following example manifest file for `App`: ```toml [[Priv]] # the private one @@ -115,29 +120,30 @@ version = "3.4.2" This manifest file describes a possible complete dependency graph for the `App` project: -- There are two different `Priv` packages that the application needs—a private one which is a direct dependency and a public one which is an indirect dependency through `Pub`: +- There are two different packages named `Priv` that the application uses. It uses a private package, which is a root dependency, and a public one, which is an indirect dependency through `Pub`. These are differentiated by their distinct UUIDs, and they have different deps: * The private `Priv` depends on the `Pub` and `Zebra` packages. * The public `Priv` has no dependencies. -- The application also depends on the `Pub` package, which in turn depends on the public `Priv ` and the same `Zebra` package which the private `Priv` package depends on. +- The application also depends on the `Pub` package, which in turn depends on the public `Priv ` and the same `Zebra` package that the private `Priv` package depends on. + -This dependency `graph` represented as a dictionary, looks like this: +This dependency graph represented as a dictionary, looks like this: ```julia -graph = Dict{UUID,Dict{Symbol,UUID}}( +graph = Dict( # Priv – the private one: - UUID("ba13f791-ae1d-465a-978b-69c3ad90f72b") => Dict{Symbol,UUID}( + UUID("ba13f791-ae1d-465a-978b-69c3ad90f72b") => Dict( :Pub => UUID("c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1"), :Zebra => UUID("f7a24cb4-21fc-4002-ac70-f0e3a0dd3f62"), ), # Priv – the public one: - UUID("2d15fe94-a1f7-436c-a4d8-07a9a496e01c") => Dict{Symbol,UUID}(), + UUID("2d15fe94-a1f7-436c-a4d8-07a9a496e01c") => Dict(), # Pub: - UUID("c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1") => Dict{Symbol,UUID}( + UUID("c07ecb7d-0dc9-4db7-8803-fadaaeaf08e1") => Dict( :Priv => UUID("2d15fe94-a1f7-436c-a4d8-07a9a496e01c"), :Zebra => UUID("f7a24cb4-21fc-4002-ac70-f0e3a0dd3f62"), ), # Zebra: - UUID("f7a24cb4-21fc-4002-ac70-f0e3a0dd3f62") => Dict{Symbol,UUID}(), + UUID("f7a24cb4-21fc-4002-ac70-f0e3a0dd3f62") => Dict(), ) ``` @@ -151,26 +157,32 @@ and gets `2d15fe94-a1f7-436c-a4d8-07a9a496e01c`, which indicates that in the con What happens if `import Zebra` is evaluated in the main `App` code base? Since `Zebra` does not appear in the project file, the import will fail even though `Zebra` *does* appear in the manifest file. Moreover, if `import Zebra` occurs in the public `Priv` package—the one with UUID `2d15fe94-a1f7-436c-a4d8-07a9a496e01c`—then that would also fail since that `Priv` package has no declared dependencies in the manifest file and therefore cannot load any packages. The `Zebra` package can only be loaded by packages for which it appear as an explicit dependency in the manifest file: the `Pub` package and one of the `Priv` packages. -**The paths map** of a project environment is also determined by the manifest file if present and is empty if there is no manifest. The path of a package `uuid` named `X` is determined by these two rules: +**The paths map** of a project environment is extracted from the manifest file. The path of a package `uuid` named `X` is determined by these rules (in order): -1. If the manifest stanza matching `uuid` has a `path` entry, use that path relative to the manifest file. -2. Otherwise, if the manifest stanza matching `uuid` has a `git-tree-sha1` entry, compute a deterministic hash function of `uuid` and `git-tree-sha1`—call it `slug`—and look for `packages/X/$slug` in each directory in the Julia `DEPOT_PATH` global array. Use the first such directory that exists. +1. If the project file in the directory matches `uuid` and name `X`, then either: + - It has a toplevel `path` entry, then `uuid` will be mapped to that path, interpreted relative to the directory containing the project file. + - Otherwise, `uuid` is mapped to `src/X.jl` relative to the directory containing the project file. +2. If the above is not the case and the project file has a corresponding manifest file and the manifest contains a stanza matching `uuid` then: + - If it has a `path` entry, use that path (relative to the directory containing the manifest file). + - If it has a `git-tree-sha1` entry, compute a deterministic hash function of `uuid` and `git-tree-sha1`—call it `slug`—and look for a directory named `packages/X/$slug` in each directory in the Julia `DEPOT_PATH` global array. Use the first such directory that exists. -If applying these rules doesn't find a loadable path, the package should be considered not installed and the system should raise an error or prompt the user to install the appropriate package version. +If any of these result in success, the path to the source code entry point will be either that result, the relative path from that result plus `src/X.jl`; otherwise, there is no path mapping for `uuid`. When loading `X`, if no source code path is found, the lookup will fail, and the user may be prompted to install the appropriate package version or to take other corrective action (e.g. declaring `X` as a dependency). In the example manifest file above, to find the path of the first `Priv` package—the one with UUID `ba13f791-ae1d-465a-978b-69c3ad90f72b`—Julia looks for its stanza in the manifest file, sees that it has a `path` entry, looks at `deps/Priv` relative to the `App` project directory—let's suppose the `App` code lives in `/home/me/projects/App`—sees that `/home/me/projects/App/deps/Priv` exists and therefore loads `Priv` from there. -If, on the other hand, Julia was loading the *other* `Priv` package—the one with UUID `2d15fe94-a1f7-436c-a4d8-07a9a496e01c`—it finds its stanza in the manifest, see that it does *not* have a `path` entry, but that it does have a `git-tree-sha1` entry. It then computes the `slug` for this UUID/SHA-1 pair, which is `HDkr` (the exact details of this computation aren't important, but it is consistent and deterministic). This means that the path to this `Priv` package will be `packages/Priv/HDkr/src/Priv.jl` in one of the package depots. Suppose the contents of `DEPOT_PATH` is `["/home/me/.julia", "/usr/local/julia"]`; then Julia will look at the following paths to see if they exist: +If, on the other hand, Julia was loading the *other* `Priv` package—the one with UUID `2d15fe94-a1f7-436c-a4d8-07a9a496e01c`—it finds its stanza in the manifest, see that it does *not* have a `path` entry, but that it does have a `git-tree-sha1` entry. It then computes the `slug` for this UUID/SHA-1 pair, which is `HDkrT` (the exact details of this computation aren't important, but it is consistent and deterministic). This means that the path to this `Priv` package will be `packages/Priv/HDkrT/src/Priv.jl` in one of the package depots. Suppose the contents of `DEPOT_PATH` is `["/home/me/.julia", "/usr/local/julia"]`, then Julia will look at the following paths to see if they exist: -1. `/home/me/.julia/packages/Priv/HDkr/src/Priv.jl` -2. `/usr/local/julia/packages/Priv/HDkr/src/Priv.jl` +1. `/home/me/.julia/packages/Priv/HDkrT` +2. `/usr/local/julia/packages/Priv/HDkrT` -Julia uses the first of these that exists to load the public `Priv` package. +Julia uses the first of these that exists to try to load the public `Priv` package from the file `packages/Priv/HDKrT/src/Priv.jl` in the depot where it was found. -Here is a representation of the `paths` map for the `App` project environment: +Here is a representation of a possible paths map for our example `App` project environment, +as provided in the Manifest given above for the dependency graph, +after searching the local file system: ```julia -paths = Dict{Tuple{UUID,Symbol},String}( +paths = Dict( # Priv – the private one: (UUID("ba13f791-ae1d-465a-978b-69c3ad90f72b"), :Priv) => # relative entry-point inside `App` repo: @@ -190,26 +202,37 @@ paths = Dict{Tuple{UUID,Symbol},String}( ) ``` -This example map includes three different kinds of package locations: +This example map includes three different kinds of package locations (the first and third are part of the default load path): 1. The private `Priv` package is "[vendored](https://stackoverflow.com/a/35109534/659248)" inside the `App` repository. 2. The public `Priv` and `Zebra` packages are in the system depot, where packages installed and managed by the system administrator live. These are available to all users on the system. 3. The `Pub` package is in the user depot, where packages installed by the user live. These are only available to the user who installed them. + ### Package directories -Package directories provide a kind of environment that approximates package loading in Julia 0.6 and earlier, and which resembles package loading in many other dynamic languages. The set of packages available in a package directory corresponds to the set of subdirectories it contains that look like packages: if `X/src/X.jl` is a file in a package directory, then `X` is considered to be a package and `X/src/X.jl` is the file Julia loads to get `X`. Which packages can "see" each other as dependencies depends on whether they contain project files, and if they do, on what appears in those project files' `[deps]` sections. +Package directories provide a simpler kind of environment without the ability to handle name collisions. In a package directory, the set of top-level packages is the set of subdirectories that "look like" packages. A package `X` is exists in a package directory if the directory contains one of the following "entry point" files: + +- `X.jl` +- `X/src/X.jl` +- `X.jl/src/X.jl` -**The roots map** is determined by the subdirectories `X` of a package directory for which `X/src/X.jl` exists and whether `X/Project.toml` exists and has a top-level `uuid` entry. Specifically `:X => uuid` goes in `roots` for each such `X` where `uuid` is defined as: +Which dependencies a package in a package directory can import depends on whether the package contains a project file: + +* If it has a project file, it can only import those packages which are identified in the `[deps]` section of the project file. +* If it does not have a project file, it can import any top-level package—i.e. the same packages that can be loaded in `Main` or the REPL. + +**The roots map** is determined by examining the contents of the package directory to generate a list of all packages that exist. +Additionally, a UUID will be assigned to each entry as follows: For a given package found inside the folder `X`... 1. If `X/Project.toml` exists and has a `uuid` entry, then `uuid` is that value. -2. If `X/Project.toml` exists and but does *not* have a top-level UUID entry, `uuid` is a dummy UUID generated by hashing the canonical path of `X/Project.toml`. -3. If `X/Project.toml` does not exist, then `uuid` is the all-zero [nil UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Nil_UUID). +2. If `X/Project.toml` exists and but does *not* have a top-level UUID entry, `uuid` is a dummy UUID generated by hashing the canonical (real) path to `X/Project.toml`. +3. Otherwise (if `Project.toml` does not exist), then `uuid` is the all-zero [nil UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier#Nil_UUID). **The dependency graph** of a project directory is determined by the presence and contents of project files in the subdirectory of each package. The rules are: -- If a package subdirectory has no project file, then it is omitted from `graph` and import statements in its code are treated as top-level, the same as the main project and REPL. -- If a package subdirectory has a project file, then the `graph` entry for its UUID is the `[deps]` map of the project file, which is considered to be empty if the section is absent. +- If a package subdirectory has no project file, then it is omitted from graph and import statements in its code are treated as top-level, the same as the main project and REPL. +- If a package subdirectory has a project file, then the graph entry for its UUID is the `[deps]` map of the project file, which is considered to be empty if the section is absent. As an example, suppose a package directory has the following structure and content: @@ -246,10 +269,10 @@ Dingo/ # no imports ``` -Here is a corresponding `roots` structure, represented as a dictionary: +Here is a corresponding roots structure, represented as a dictionary: ```julia -roots = Dict{Symbol,UUID}( +roots = Dict( :Aardvark => UUID("00000000-0000-0000-0000-000000000000"), # no project file, nil UUID :Bobcat => UUID("85ad11c7-31f6-5d08-84db-0a4914d4cadf"), # dummy UUID based on path :Cobra => UUID("4725e24d-f727-424b-bca0-c4307a3456fa"), # UUID from project file @@ -257,21 +280,21 @@ roots = Dict{Symbol,UUID}( ) ``` -Here is the corresponding `graph` structure, represented as a dictionary: +Here is the corresponding graph structure, represented as a dictionary: ```julia -graph = Dict{UUID,Dict{Symbol,UUID}}( +graph = Dict( # Bobcat: - UUID("85ad11c7-31f6-5d08-84db-0a4914d4cadf") => Dict{Symbol,UUID}( + UUID("85ad11c7-31f6-5d08-84db-0a4914d4cadf") => Dict( :Cobra => UUID("4725e24d-f727-424b-bca0-c4307a3456fa"), :Dingo => UUID("7a7925be-828c-4418-bbeb-bac8dfc843bc"), ), # Cobra: - UUID("4725e24d-f727-424b-bca0-c4307a3456fa") => Dict{Symbol,UUID}( + UUID("4725e24d-f727-424b-bca0-c4307a3456fa") => Dict( :Dingo => UUID("7a7925be-828c-4418-bbeb-bac8dfc843bc"), ), # Dingo: - UUID("7a7925be-828c-4418-bbeb-bac8dfc843bc") => Dict{Symbol,UUID}(), + UUID("7a7925be-828c-4418-bbeb-bac8dfc843bc") => Dict(), ) ``` @@ -293,7 +316,7 @@ Observe the following specific instances of these rules in our example: **The paths map** in a package directory is simple: it maps subdirectory names to their corresponding entry-point paths. In other words, if the path to our example project directory is `/home/me/animals` then the `paths` map could be represented by this dictionary: ```julia -paths = Dict{Tuple{UUID,Symbol},String}( +paths = Dict( (UUID("00000000-0000-0000-0000-000000000000"), :Aardvark) => "/home/me/AnimalPackages/Aardvark/src/Aardvark.jl", (UUID("85ad11c7-31f6-5d08-84db-0a4914d4cadf"), :Bobcat) => @@ -309,9 +332,9 @@ Since all packages in a package directory environment are, by definition, subdir ### Environment stacks -The third and final kind of environment is one that combines other environments by overlaying several of them, making the packages in each available in a single composite environment. These composite environments are called *environment stacks*. The Julia `LOAD_PATH` global defines an environment stack—the environment in which the Julia process operates. If you want your Julia process to have access only to the packages in one project or package directory, make it the only entry in `LOAD_PATH`. It is often quite useful, however, to have access to some of your favorite tools—standard libraries, profilers, debuggers, personal utilities, etc.—even if they are not dependencies of the project you're working on. By pushing an environment containing these tools onto the load path, you immediately have access to them in top-level code without needing to add them to your project. +The third and final kind of environment is one that combines other environments by overlaying several of them, making the packages in each available in a single composite environment. These composite environments are called *environment stacks*. The Julia `LOAD_PATH` global defines an environment stack—the environment in which the Julia process operates. If you want your Julia process to have access only to the packages in one project or package directory, make it the only entry in `LOAD_PATH`. It is often quite useful, however, to have access to some of your favorite tools—standard libraries, profilers, debuggers, personal utilities, etc.—even if they are not dependencies of the project you're working on. By adding an environment containing these tools to the load path, you immediately have access to them in top-level code without needing to add them to your project. -The mechanism for combining the `roots`, `graph` and `paths` data structures of the components of an environment stack is simple: they are simply merged as dictionaries, favoring earlier entries over later ones in the case of key collisions. In other words, if we have `stack = [env₁, env₂, …]` then we have: +The mechanism for combining the roots, graph and paths data structures of the components of an environment stack is simple: they are merged as dictionaries, favoring earlier entries over later ones in the case of key collisions. In other words, if we have `stack = [env₁, env₂, …]` then we have: ```julia roots = reduce(merge, reverse([roots₁, roots₂, …])) @@ -319,13 +342,13 @@ graph = reduce(merge, reverse([graph₁, graph₂, …])) paths = reduce(merge, reverse([paths₁, paths₂, …])) ``` -The subscripted `rootsᵢ`, `graphᵢ` and `pathsᵢ` variables correspond to the subscripted environments, `envᵢ`, contained `stack`. The `reverse` is present because `merge` favors the last argument rather than first when there are collisions between keys in its argument dictionaries. That's all there is to stacked environments. There are a couple of noteworthy features of this design: +The subscripted `rootsᵢ`, `graphᵢ` and `pathsᵢ` variables correspond to the subscripted environments, `envᵢ`, contained in `stack`. The `reverse` is present because `merge` favors the last argument rather than first when there are collisions between keys in its argument dictionaries. There are a couple of noteworthy features of this design: 1. The *primary environment*—i.e. the first environment in a stack—is faithfully embedded in a stacked environment. The full dependency graph of the first environment in a stack is guaranteed to be included intact in the stacked environment including the same versions of all dependencies. -2. Packages in non-primary environments can end up using incompatible versions of their dependencies even if their own environments are entirely compatible. This can happen when one of their dependencies is shadowed by a version in an earlier environment in the stack. +2. Packages in non-primary environments can end up using incompatible versions of their dependencies even if their own environments are entirely compatible. This can happen when one of their dependencies is shadowed by a version in an earlier environment in the stack (either by graph or path, or both). -Since the primary environment is typically the environment of a project you're working on, while environments later in the stack contain additional tools, this is the right tradeoff: it's better to break your dev tools but keep the project working. When such incompatibilities occur, you'll typically want to upgrade your dev tools to versions that are compatible with the main project. +Since the primary environment is typically the environment of a project you're working on, while environments later in the stack contain additional tools, this is the right trade-off: it's better to break your development tools but keep the project working. When such incompatibilities occur, you'll typically want to upgrade your dev tools to versions that are compatible with the main project. ## Conclusion -Federated package management and precise software reproducibility are difficult but worthy goals in a package system. In combination, these goals lead to a more complex package loading mechanism than most dynamic languages have, but it also yields scalability and reproducibility that is more commonly associated with static languages. Fortunately, most Julia users can remain oblivious to the technical details of code loading and simply use the built-in package manager to add a package `X` to the appropriate project and manifest files and then write `import X` to load `X` without a further thought. +Federated package management and precise software reproducibility are difficult but worthy goals in a package system. In combination, these goals lead to a more complex package loading mechanism than most dynamic languages have, but it also yields scalability and reproducibility that is more commonly associated with static languages. Typically, Julia users should be able to use the built-in package manager to manage their projects without needing a precise understanding of these interactions. A call to `Pkg.add("X")` will add to the appropriate project and manifest files, selected via `Pkg.activate("Y")`, so that a future call to `import X` will load `X` without further thought. diff --git a/src/manual/faq.md b/src/manual/faq.md index e6ae749..4db755c 100644 --- a/src/manual/faq.md +++ b/src/manual/faq.md @@ -774,8 +774,7 @@ julia> @sync for i in 1:3 You can lock your writes with a `ReentrantLock` like this: ```jldoctest -julia> l = ReentrantLock() -ReentrantLock(nothing, Condition(Any[]), 0) +julia> l = ReentrantLock(); julia> @sync for i in 1:3 @async begin diff --git a/src/stdlib/Distributed.md b/src/stdlib/Distributed.md index da0b822..4653a26 100644 --- a/src/stdlib/Distributed.md +++ b/src/stdlib/Distributed.md @@ -18,7 +18,6 @@ Distributed.pmap Distributed.RemoteException Distributed.Future Distributed.RemoteChannel -Distributed.wait Distributed.fetch(::Any) Distributed.remotecall(::Any, ::Integer, ::Any...) Distributed.remotecall_wait(::Any, ::Integer, ::Any...) @@ -38,13 +37,10 @@ Distributed.remotecall(::Any, ::AbstractWorkerPool, ::Any...) Distributed.remotecall_wait(::Any, ::AbstractWorkerPool, ::Any...) Distributed.remotecall_fetch(::Any, ::AbstractWorkerPool, ::Any...) Distributed.remote_do(::Any, ::AbstractWorkerPool, ::Any...) -Distributed.timedwait Distributed.@spawn Distributed.@spawnat Distributed.@fetch Distributed.@fetchfrom -Distributed.@async -Distributed.@sync Distributed.@distributed Distributed.@everywhere Distributed.clear!(::Any, ::Any; ::Any) From fcf0f2ee027136d4ee571e8d591b288428484eb0 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Fri, 28 Dec 2018 01:19:09 +0900 Subject: [PATCH 087/153] update Julia Commit 2ab1405c9c --- codex/NEWS.md | 9 +++++ codex/index.md | 12 +++++++ codex/manual/environment-variables.md | 2 +- codex/stdlib/Dates.md | 47 +++++++++++++------------- codex/stdlib/Sockets.md | 1 + contrib/.html_writer.jl.swp | Bin 0 -> 20480 bytes contrib/html_writer.jl | 39 +++++++++++++++------ make.jl | 11 +++--- src/NEWS.md | 9 +++++ src/index.md | 17 ++++++++++ src/manual/environment-variables.md | 2 +- src/stdlib/Dates.md | 47 +++++++++++++------------- src/stdlib/Sockets.md | 1 + 13 files changed, 134 insertions(+), 63 deletions(-) create mode 100644 contrib/.html_writer.jl.swp diff --git a/codex/NEWS.md b/codex/NEWS.md index 150601f..cbd598e 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -24,6 +24,7 @@ Command-line option changes New library functions --------------------- +* `getipaddrs()` function returns all the IP addresses of the local machine ([#30349](https://github.com/JuliaLang/julia/issues/30349)) Standard library changes ------------------------ @@ -33,6 +34,14 @@ Standard library changes * Added keyword arguments `rtol`, `atol` to `pinv` and `nullspace` ([#29998](https://github.com/JuliaLang/julia/issues/29998)). +#### SparseArrays + +* performance improvements for sparse matrix-matrix multiplication ([#30372](https://github.com/JuliaLang/julia/issues/30372)). + +#### Dates + +* Fixed `repr` such that it displays `DateTime` as it would be entered in Julia ([#30200](https://github.com/JuliaLang/julia/issues/30200)). + External dependencies --------------------- diff --git a/codex/index.md b/codex/index.md index b8fe2dc..ba11d6a 100644 --- a/codex/index.md +++ b/codex/index.md @@ -20,6 +20,18 @@ Markdown.parse(String(take!(io))) ``` Please read the [release notes](NEWS.md) to see what has changed since the last release. +```@eval +release = isempty(VERSION.prerelease) +file = release ? "julia-$(VERSION).pdf" : + "julia-$(VERSION.major).$(VERSION.minor).$(VERSION.patch)-$(first(VERSION.prerelease)).pdf" +url = "https://raw.githubusercontent.com/JuliaLang/docs.julialang.org/assets/$(file)" +import Markdown +Markdown.parse(""" +!!! note + The documentation is also available in PDF format: [$file]($url). +""") +``` + ### [Introduction](@id man-introduction) Scientific computing has traditionally required the highest performance, yet domain experts have diff --git a/codex/manual/environment-variables.md b/codex/manual/environment-variables.md index 7bc47ba..c410adc 100644 --- a/codex/manual/environment-variables.md +++ b/codex/manual/environment-variables.md @@ -151,7 +151,7 @@ logical CPU cores available. ### `JULIA_WORKER_TIMEOUT` -A [`Float64`](@ref) that sets the value of `Base.worker_timeout()` (default: `60.0`). +A [`Float64`](@ref) that sets the value of `Distributed.worker_timeout()` (default: `60.0`). This function gives the number of seconds a worker process will wait for a master process to establish a connection before dying. diff --git a/codex/stdlib/Dates.md b/codex/stdlib/Dates.md index bb0a9f2..6d5932c 100644 --- a/codex/stdlib/Dates.md +++ b/codex/stdlib/Dates.md @@ -400,29 +400,29 @@ As a bonus, all period arithmetic objects work directly with ranges: ```jldoctest julia> dr = Date(2014,1,29):Day(1):Date(2014,2,3) -2014-01-29:1 day:2014-02-03 +Date(2014, 1, 29):1 day:Date(2014, 2, 3) julia> collect(dr) 6-element Array{Date,1}: - 2014-01-29 - 2014-01-30 - 2014-01-31 - 2014-02-01 - 2014-02-02 - 2014-02-03 + Date(2014, 1, 29) + Date(2014, 1, 30) + Date(2014, 1, 31) + Date(2014, 2, 1) + Date(2014, 2, 2) + Date(2014, 2, 3) julia> dr = Date(2014,1,29):Dates.Month(1):Date(2014,07,29) -2014-01-29:1 month:2014-07-29 +Date(2014, 1, 29):1 month:Date(2014, 7, 29) julia> collect(dr) 7-element Array{Date,1}: - 2014-01-29 - 2014-02-28 - 2014-03-29 - 2014-04-29 - 2014-05-29 - 2014-06-29 - 2014-07-29 + Date(2014, 1, 29) + Date(2014, 2, 28) + Date(2014, 3, 29) + Date(2014, 4, 29) + Date(2014, 5, 29) + Date(2014, 6, 29) + Date(2014, 7, 29) ``` ## Adjuster Functions @@ -492,14 +492,15 @@ julia> filter(dr) do x Dates.dayofweekofmonth(x) == 2 end 8-element Array{Date,1}: - 2014-04-08 - 2014-05-13 - 2014-06-10 - 2014-07-08 - 2014-08-12 - 2014-09-09 - 2014-10-14 - 2014-11-11 + Date(2014, 4, 8) + Date(2014, 5, 13) + Date(2014, 6, 10) + Date(2014, 7, 8) + Date(2014, 8, 12) + Date(2014, 9, 9) + Date(2014, 10, 14) + Date(2014, 11, 11) + ``` Additional examples and tests are available in [`stdlib/Dates/test/adjusters.jl`](https://github.com/JuliaLang/julia/blob/master/stdlib/Dates/test/adjusters.jl). diff --git a/codex/stdlib/Sockets.md b/codex/stdlib/Sockets.md index 7f4d72b..710a95f 100644 --- a/codex/stdlib/Sockets.md +++ b/codex/stdlib/Sockets.md @@ -11,6 +11,7 @@ Sockets.listen(::Any) Sockets.listen(::AbstractString) Sockets.getaddrinfo Sockets.getipaddr +Sockets.getipaddrs Sockets.getalladdrinfo Sockets.getnameinfo Sockets.getsockname diff --git a/contrib/.html_writer.jl.swp b/contrib/.html_writer.jl.swp new file mode 100644 index 0000000000000000000000000000000000000000..341ee3363538115aa02800dac2738e8e7f056206 GIT binary patch literal 20480 zcmeI4d#oH)9mfZu3bw`i0wIQ+&TZ1!xI4EkBIS}>Y=IVS%d0KKv^SgC*|WQI@9doI z%$a+8eIPN2io`#Fs8KMO5={YPd;mV8CJH7JDN%z6LHSF38V=fN(Ae$y+mNMkc`V#e_+B`Y=bA#`WRH98Nf~=l5_*z1+QOgoMI_^( zHQAH>u(=QilE?1ssE84X=BKfMvB0t{kjhSD^J?qtO&is#K4GtAZ+_FhWo0#qj0KDZ zj0KDZj0KDZj0KDZj0KDZ{y!`r2Paw|Mpa&uRcBT9dBVu&N!f2d`&>Qp{KV|{`s}km z@;v)#K8yv71&jrZ1&jrZ1&jrZ1&jrZ1&jrZ1&jrZ1^x#X@Y;T)r$>1NSSk@!pCh#$EJ-7m#0p13lJ{h`# z`@tRH0R#F!Cw$X+?;0z7mzN2DQNf|71y`z9sa=fPHPxd|Ec(qf4jo?} za&frDO%t4Eq31QF*aX|dC6hhQlzBb0Rpj+K>xfw0wJ&Z5l8MN5ZPrSq#5divQVb$* z9!-V6P8vFNj)uq0Fo@=oT1}^^Hh2`d1FuW1fGk4xf~d7z1SO$K`nU({i37i!oO<5YE zKCBnBWZ*^2vpQ+y%RoddmycGsS{*G)+)MWE-le~zVIs0(CO6YQtGH#!CbdRWL=LrW zjnRw3vIb)7=$>uC1bBmF^HP3Dl5r@_pFVlVvD(Z zoqBBLO_qO>gh3oc(g{SJ(TONHkv5(f@Te(LIY{NOqGYE)XgigyRDL6wEzw>i%fi%Y zJ-6d<5;AJtqQrDj(fg-DFX~QjvFC(6<5>A^XoPB9blGlY$=tw>Rv>SpX?9%OlB`S} z$jXvtH->Aci-m4wI?{9`kxHcg21oPI0J&E>HTD69=j#XSYwm)G+uQJbZYSr1tzqck<@r$Ue0x;l{;4E};kPh* zayFTqJ(%)%QDttlD0gEH*&ALMy8R$>XA^s-Y)q}vI021~?q>JwFNvVY@Nq2^hDx11rbrP|um8g}*m|zzwg&1|sjX^Bt zgEnt7oi6Kbsb(Wa8?Kt`PNL^a(8DBT>sm$GzsUXQ*J?wQIElHd?c60lWv5UnFqYGq~sXUP|LzB!Vs)B+%B`NJo7g ziL%r){K0@)_)$`6J>QE&6yPYT%Gl%~r%{Ib1Q$*zF&rjtk*3bzG}YR8krysvtVx=g zSu$Je;kLQwYh%HUs=Mp2W8t3Wtoe%iJK*Y-J>Fg`?QZK|p(3ZXFHU)~m8;jL! zARm}9`D}SHRX|Obih0EF5WmaDcCZ3rmEi)_hrBR9WSHsgXvylU< zSGkT}ryq0{>#Q;d8zZD#?qG5>MKh#2+v|1fOgZJ!3{z}t+TWBVZkP9_#sMz~8|m;7j0A@Hgml6#N)G0B#38KzjPXT*d;%0>%Qy0>%Qy z0>%QbW((xOp)4r2-=4s_29XU1H<~oVruiIAGbz%FX&&9yK~24sFCJk9rKh0df?9bg z4A&q{dTW($@>ee{Zt7{gT|%YqQp{maSQTw{8cAMEFYDidMl}HZ5aXA zOURdHuR#{beNmfH!dKR2RKm-$Sss*LVmFdJWH)lH(mBxv+Pj=y>|pbOo=#x90!tXR ziIK(S7qB0rg7f5VS+K5jdUYvYyT2BgyFPh2 zM;yOFZ&S6|uuU`LWRBYL;6=100}X7%ASgo@+ivA0-5lzW93TGCycgMbty`_>G7feT#X{< z&^9ND(RIsoERsQZvDS8j#A_u;mzP%7q%;nU@B)VDhN9(#iAy0Vbha16yAWAbArQ(w z?B+xIQVoY1u1%UCB-ah3?#^f*O8Y0AB1m|DAQ!U@D|j2zZJ-c|46q8U1P>u5K=FdlfvdqTK=Fdpz>|m({2JT~ZUCPE0XPYq2%bQ!;0Wk} z)4&?A3akVVB2I8GxCh(R7BE=kHQRjAW=EWRhd4a`?ImCivH|7wFImDv> zOQmeHZs~jzbF*yDUruWC(*WiWi#fzHdhWzFhgg<*f~i each, :rel => "stylesheet", :type => "text/css"] + end, script("documenterBaseURL=\"$(relhref(src, "."))\""), @@ -45,6 +49,7 @@ function Documenter.Writers.HTMLWriter.render_head(ctx, navnode) # Custom user-provided assets. asset_links(src, ctx.local_assets), + # juliakorea custom css link[:href => relhref(src, "assets/custom.css"), :rel => "stylesheet", :type => "text/css"], # juliakorea Korean word break @@ -89,23 +94,37 @@ function Documenter.Writers.HTMLWriter.render_article(ctx, navnode) topnav = nav(ul(header_links)) - # Set the logo and name for the "Edit on.." button. We assume GitHub as a host. - host = "GitHub" - logo = "\uf09b" - + # Set the logo and name for the "Edit on.." button. host_type = Utilities.repo_host_from_url(ctx.doc.user.repo) if host_type == Utilities.RepoGitlab host = "GitLab" logo = "\uf296" + elseif host_type == Utilities.RepoGithub + host = "GitHub" + logo = "\uf09b" elseif host_type == Utilities.RepoBitbucket host = "BitBucket" logo = "\uf171" + else + host = "" + logo = "\uf15c" end - - if !ctx.doc.user.html_disable_git - url = Utilities.url(ctx.doc.user.repo, getpage(ctx, navnode).source, commit=ctx.doc.user.html_edit_branch) + hoststring = isempty(host) ? " source" : " on $(host)" + + if !ctx.settings.disable_git + pageurl = get(getpage(ctx, navnode).globals.meta, :EditURL, getpage(ctx, navnode).source) + if Utilities.isabsurl(pageurl) + url = pageurl + else + if !(pageurl == getpage(ctx, navnode).source) + # need to set users path relative the page itself + pageurl = joinpath(first(splitdir(getpage(ctx, navnode).source)), pageurl) + end + url = Utilities.url(ctx.doc.user.repo, pageurl, commit=ctx.settings.edit_branch) + end if url !== nothing - push!(topnav.nodes, a[".edit-page", :href => url](span[".fa"](logo), t_Edit_on(host))) + edit_verb = (ctx.settings.edit_branch === nothing) ? "View" : "Edit" + push!(topnav.nodes, a[".edit-page", :href => url](span[".fa"](logo), " $(edit_verb)$hoststring")) end end art_header = header(topnav, hr(), render_topbar(ctx, navnode)) diff --git a/make.jl b/make.jl index f7e9b69..bdfac97 100644 --- a/make.jl +++ b/make.jl @@ -1,9 +1,9 @@ # code from https://github.com/JuliaLang/julia/blob/master/doc/make.jl # Install dependencies needed to build the documentation. -empty!(LOAD_PATH) +#empty!(LOAD_PATH) push!(LOAD_PATH, @__DIR__, "@stdlib") -empty!(DEPOT_PATH) +#empty!(DEPOT_PATH) pushfirst!(DEPOT_PATH, joinpath(@__DIR__, "deps")) if !isdir(joinpath(@__DIR__, "deps", "packages", "Documenter")) || "deps" in ARGS @@ -147,12 +147,13 @@ makedocs( linkcheck_ignore = ["https://bugs.kde.org/show_bug.cgi?id=136779"], # fails to load from nanosoldier? strict = true, checkdocs = :none, - format = "pdf" in ARGS ? :latex : :html, + format = Documenter.HTML( + prettyurls = !("local" in ARGS), + canonical = t_html_canonical, + ), sitename = t_sitename, authors = "The Julia Project", analytics = t_analytics, pages = PAGES, - html_prettyurls = !("local" in ARGS), - html_canonical = t_html_canonical, assets = ["assets/julia-manual.css", ] ) diff --git a/src/NEWS.md b/src/NEWS.md index 150601f..cbd598e 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -24,6 +24,7 @@ Command-line option changes New library functions --------------------- +* `getipaddrs()` function returns all the IP addresses of the local machine ([#30349](https://github.com/JuliaLang/julia/issues/30349)) Standard library changes ------------------------ @@ -33,6 +34,14 @@ Standard library changes * Added keyword arguments `rtol`, `atol` to `pinv` and `nullspace` ([#29998](https://github.com/JuliaLang/julia/issues/29998)). +#### SparseArrays + +* performance improvements for sparse matrix-matrix multiplication ([#30372](https://github.com/JuliaLang/julia/issues/30372)). + +#### Dates + +* Fixed `repr` such that it displays `DateTime` as it would be entered in Julia ([#30200](https://github.com/JuliaLang/julia/issues/30200)). + External dependencies --------------------- diff --git a/src/index.md b/src/index.md index 0b0f10c..feeb442 100644 --- a/src/index.md +++ b/src/index.md @@ -27,6 +27,23 @@ Markdown.parse(String(take!(io))) 한글 문서 번역은 깃헙 [https://github.com/juliakorea/translate-doc](https://github.com/juliakorea/translate-doc) 에서 누구나 참여하실 수 있습니다. 많은 참여 부탁드립니다. +!!! note "구글 자동 번역" + 중국어 번역 자료를 한국어로 자동 번역해서 유용하게 볼 수 있습니다. + - Julia 대만(juliatw) 문서 [https://docs.juliatw.org/latest/](https://translate.google.com/translate?sl=zh-CN&tl=ko&u=https%3A%2F%2Fdocs.juliatw.org%2Flatest%2F) + - Julia 중국(juliacn) 문서 [http://docs.juliacn.com/latest/](https://translate.google.com/translate?sl=zh-CN&tl=ko&u=http%3A%2F%2Fdocs.juliacn.com%2Flatest%2F) + +```@eval +release = isempty(VERSION.prerelease) +file = release ? "julia-$(VERSION).pdf" : + "julia-$(VERSION.major).$(VERSION.minor).$(VERSION.patch)-$(first(VERSION.prerelease)).pdf" +url = "https://raw.githubusercontent.com/JuliaLang/docs.julialang.org/assets/$(file)" +import Markdown +Markdown.parse(""" +!!! note + The documentation is also available in PDF format: [$file]($url). +""") +``` + ### [소개글](@id man-introduction) 과학 분야 컴퓨팅은 전통적으로 최고의 성능을 요구하지만, 당사자인 전문 연구자들은 속도가 느리더라도 동적인 언어로서 그들의 업무를 처리한다. diff --git a/src/manual/environment-variables.md b/src/manual/environment-variables.md index 7bc47ba..c410adc 100644 --- a/src/manual/environment-variables.md +++ b/src/manual/environment-variables.md @@ -151,7 +151,7 @@ logical CPU cores available. ### `JULIA_WORKER_TIMEOUT` -A [`Float64`](@ref) that sets the value of `Base.worker_timeout()` (default: `60.0`). +A [`Float64`](@ref) that sets the value of `Distributed.worker_timeout()` (default: `60.0`). This function gives the number of seconds a worker process will wait for a master process to establish a connection before dying. diff --git a/src/stdlib/Dates.md b/src/stdlib/Dates.md index bb0a9f2..6d5932c 100644 --- a/src/stdlib/Dates.md +++ b/src/stdlib/Dates.md @@ -400,29 +400,29 @@ As a bonus, all period arithmetic objects work directly with ranges: ```jldoctest julia> dr = Date(2014,1,29):Day(1):Date(2014,2,3) -2014-01-29:1 day:2014-02-03 +Date(2014, 1, 29):1 day:Date(2014, 2, 3) julia> collect(dr) 6-element Array{Date,1}: - 2014-01-29 - 2014-01-30 - 2014-01-31 - 2014-02-01 - 2014-02-02 - 2014-02-03 + Date(2014, 1, 29) + Date(2014, 1, 30) + Date(2014, 1, 31) + Date(2014, 2, 1) + Date(2014, 2, 2) + Date(2014, 2, 3) julia> dr = Date(2014,1,29):Dates.Month(1):Date(2014,07,29) -2014-01-29:1 month:2014-07-29 +Date(2014, 1, 29):1 month:Date(2014, 7, 29) julia> collect(dr) 7-element Array{Date,1}: - 2014-01-29 - 2014-02-28 - 2014-03-29 - 2014-04-29 - 2014-05-29 - 2014-06-29 - 2014-07-29 + Date(2014, 1, 29) + Date(2014, 2, 28) + Date(2014, 3, 29) + Date(2014, 4, 29) + Date(2014, 5, 29) + Date(2014, 6, 29) + Date(2014, 7, 29) ``` ## Adjuster Functions @@ -492,14 +492,15 @@ julia> filter(dr) do x Dates.dayofweekofmonth(x) == 2 end 8-element Array{Date,1}: - 2014-04-08 - 2014-05-13 - 2014-06-10 - 2014-07-08 - 2014-08-12 - 2014-09-09 - 2014-10-14 - 2014-11-11 + Date(2014, 4, 8) + Date(2014, 5, 13) + Date(2014, 6, 10) + Date(2014, 7, 8) + Date(2014, 8, 12) + Date(2014, 9, 9) + Date(2014, 10, 14) + Date(2014, 11, 11) + ``` Additional examples and tests are available in [`stdlib/Dates/test/adjusters.jl`](https://github.com/JuliaLang/julia/blob/master/stdlib/Dates/test/adjusters.jl). diff --git a/src/stdlib/Sockets.md b/src/stdlib/Sockets.md index 7f4d72b..710a95f 100644 --- a/src/stdlib/Sockets.md +++ b/src/stdlib/Sockets.md @@ -11,6 +11,7 @@ Sockets.listen(::Any) Sockets.listen(::AbstractString) Sockets.getaddrinfo Sockets.getipaddr +Sockets.getipaddrs Sockets.getalladdrinfo Sockets.getnameinfo Sockets.getsockname From 128f86ff7224fee69aa376338322cc93b0092bc5 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Fri, 28 Dec 2018 01:38:06 +0900 Subject: [PATCH 088/153] =?UTF-8?q?=EC=A4=91=EA=B5=AD=EC=96=B4=20=EB=B2=88?= =?UTF-8?q?=EC=97=AD=20=EC=9E=90=EB=A3=8C=20=ED=95=9C=EA=B5=AD=EC=96=B4=20?= =?UTF-8?q?=EC=9E=90=EB=8F=99=20=EB=B2=88=EC=97=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 5 +++-- contrib/.html_writer.jl.swp | Bin 20480 -> 0 bytes 2 files changed, 3 insertions(+), 2 deletions(-) delete mode 100644 contrib/.html_writer.jl.swp diff --git a/README.md b/README.md index 914e50b..d170149 100644 --- a/README.md +++ b/README.md @@ -6,5 +6,6 @@ - https://juliakorea.github.io/ko/latest/ -### Julia Documentation 구글 번역 보기 - - [중국어 -> 한국어](https://translate.google.com/translate?sl=zh-CN&tl=ko&js=y&hl=en&ie=UTF-8&u=http%3A%2F%2Fdocs.juliacn.com%2Flatest%2F) +### 중국어 번역 자료 한국어 자동 번역 + - Julia 대만(juliatw) 문서 [https://docs.juliatw.org/latest/](https://translate.google.com/translate?sl=zh-CN&tl=ko&u=https%3A%2F%2Fdocs.juliatw.org%2Flatest%2F) + - Julia 중국(juliacn) 문서 [http://docs.juliacn.com/latest/](https://translate.google.com/translate?sl=zh-CN&tl=ko&u=http%3A%2F%2Fdocs.juliacn.com%2Flatest%2F) diff --git a/contrib/.html_writer.jl.swp b/contrib/.html_writer.jl.swp deleted file mode 100644 index 341ee3363538115aa02800dac2738e8e7f056206..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20480 zcmeI4d#oH)9mfZu3bw`i0wIQ+&TZ1!xI4EkBIS}>Y=IVS%d0KKv^SgC*|WQI@9doI z%$a+8eIPN2io`#Fs8KMO5={YPd;mV8CJH7JDN%z6LHSF38V=fN(Ae$y+mNMkc`V#e_+B`Y=bA#`WRH98Nf~=l5_*z1+QOgoMI_^( zHQAH>u(=QilE?1ssE84X=BKfMvB0t{kjhSD^J?qtO&is#K4GtAZ+_FhWo0#qj0KDZ zj0KDZj0KDZj0KDZj0KDZ{y!`r2Paw|Mpa&uRcBT9dBVu&N!f2d`&>Qp{KV|{`s}km z@;v)#K8yv71&jrZ1&jrZ1&jrZ1&jrZ1&jrZ1&jrZ1^x#X@Y;T)r$>1NSSk@!pCh#$EJ-7m#0p13lJ{h`# z`@tRH0R#F!Cw$X+?;0z7mzN2DQNf|71y`z9sa=fPHPxd|Ec(qf4jo?} za&frDO%t4Eq31QF*aX|dC6hhQlzBb0Rpj+K>xfw0wJ&Z5l8MN5ZPrSq#5divQVb$* z9!-V6P8vFNj)uq0Fo@=oT1}^^Hh2`d1FuW1fGk4xf~d7z1SO$K`nU({i37i!oO<5YE zKCBnBWZ*^2vpQ+y%RoddmycGsS{*G)+)MWE-le~zVIs0(CO6YQtGH#!CbdRWL=LrW zjnRw3vIb)7=$>uC1bBmF^HP3Dl5r@_pFVlVvD(Z zoqBBLO_qO>gh3oc(g{SJ(TONHkv5(f@Te(LIY{NOqGYE)XgigyRDL6wEzw>i%fi%Y zJ-6d<5;AJtqQrDj(fg-DFX~QjvFC(6<5>A^XoPB9blGlY$=tw>Rv>SpX?9%OlB`S} z$jXvtH->Aci-m4wI?{9`kxHcg21oPI0J&E>HTD69=j#XSYwm)G+uQJbZYSr1tzqck<@r$Ue0x;l{;4E};kPh* zayFTqJ(%)%QDttlD0gEH*&ALMy8R$>XA^s-Y)q}vI021~?q>JwFNvVY@Nq2^hDx11rbrP|um8g}*m|zzwg&1|sjX^Bt zgEnt7oi6Kbsb(Wa8?Kt`PNL^a(8DBT>sm$GzsUXQ*J?wQIElHd?c60lWv5UnFqYGq~sXUP|LzB!Vs)B+%B`NJo7g ziL%r){K0@)_)$`6J>QE&6yPYT%Gl%~r%{Ib1Q$*zF&rjtk*3bzG}YR8krysvtVx=g zSu$Je;kLQwYh%HUs=Mp2W8t3Wtoe%iJK*Y-J>Fg`?QZK|p(3ZXFHU)~m8;jL! zARm}9`D}SHRX|Obih0EF5WmaDcCZ3rmEi)_hrBR9WSHsgXvylU< zSGkT}ryq0{>#Q;d8zZD#?qG5>MKh#2+v|1fOgZJ!3{z}t+TWBVZkP9_#sMz~8|m;7j0A@Hgml6#N)G0B#38KzjPXT*d;%0>%Qy0>%Qy z0>%QbW((xOp)4r2-=4s_29XU1H<~oVruiIAGbz%FX&&9yK~24sFCJk9rKh0df?9bg z4A&q{dTW($@>ee{Zt7{gT|%YqQp{maSQTw{8cAMEFYDidMl}HZ5aXA zOURdHuR#{beNmfH!dKR2RKm-$Sss*LVmFdJWH)lH(mBxv+Pj=y>|pbOo=#x90!tXR ziIK(S7qB0rg7f5VS+K5jdUYvYyT2BgyFPh2 zM;yOFZ&S6|uuU`LWRBYL;6=100}X7%ASgo@+ivA0-5lzW93TGCycgMbty`_>G7feT#X{< z&^9ND(RIsoERsQZvDS8j#A_u;mzP%7q%;nU@B)VDhN9(#iAy0Vbha16yAWAbArQ(w z?B+xIQVoY1u1%UCB-ah3?#^f*O8Y0AB1m|DAQ!U@D|j2zZJ-c|46q8U1P>u5K=FdlfvdqTK=Fdpz>|m({2JT~ZUCPE0XPYq2%bQ!;0Wk} z)4&?A3akVVB2I8GxCh(R7BE=kHQRjAW=EWRhd4a`?ImCivH|7wFImDv> zOQmeHZs~jzbF*yDUruWC(*WiWi#fzHdhWzFhgg<*f~i Date: Sun, 30 Dec 2018 20:06:45 +0900 Subject: [PATCH 089/153] update Julia Commit 2e91c5e73a --- codex/base/numbers.md | 2 +- codex/devdocs/inference.md | 2 +- codex/manual/code-loading.md | 2 +- codex/manual/environment-variables.md | 2 +- codex/manual/faq.md | 2 +- codex/manual/integers-and-floating-point-numbers.md | 4 ++-- codex/manual/networking-and-streams.md | 2 +- codex/manual/noteworthy-differences.md | 2 +- codex/manual/parallel-computing.md | 9 +++++---- codex/manual/performance-tips.md | 2 +- codex/manual/strings.md | 4 ++-- codex/stdlib/Dates.md | 2 +- codex/stdlib/LibGit2.md | 4 ++-- src/base/numbers.md | 2 +- src/devdocs/inference.md | 2 +- src/manual/code-loading.md | 2 +- src/manual/environment-variables.md | 2 +- src/manual/faq.md | 2 +- src/manual/integers-and-floating-point-numbers.md | 4 ++-- src/manual/networking-and-streams.md | 2 +- src/manual/noteworthy-differences.md | 2 +- src/manual/parallel-computing.md | 9 +++++---- src/manual/performance-tips.md | 2 +- src/manual/strings.md | 4 ++-- src/stdlib/Dates.md | 2 +- src/stdlib/LibGit2.md | 4 ++-- 26 files changed, 40 insertions(+), 38 deletions(-) diff --git a/codex/base/numbers.md b/codex/base/numbers.md index f07f7f5..47a33b4 100644 --- a/codex/base/numbers.md +++ b/codex/base/numbers.md @@ -115,7 +115,7 @@ Base.@uint128_str The [`BigFloat`](@ref) and [`BigInt`](@ref) types implements arbitrary-precision floating point and integer arithmetic, respectively. For -[`BigFloat`](@ref) the [GNU MPFR library](http://www.mpfr.org/) is used, +[`BigFloat`](@ref) the [GNU MPFR library](https://www.mpfr.org/) is used, and for [`BigInt`](@ref) the [GNU Multiple Precision Arithmetic Library (GMP)] (https://gmplib.org) is used. diff --git a/codex/devdocs/inference.md b/codex/devdocs/inference.md index df1f908..97f2122 100644 --- a/codex/devdocs/inference.md +++ b/codex/devdocs/inference.md @@ -75,7 +75,7 @@ in CPU cycles) to each of Julia's intrinsic functions. These costs are based on [standard ranges for common architectures](http://ithare.com/wp-content/uploads/part101_infographics_v08.png) (see -[Agner Fog's analysis](http://www.agner.org/optimize/instruction_tables.pdf) +[Agner Fog's analysis](https://www.agner.org/optimize/instruction_tables.pdf) for more detail). We supplement this low-level lookup table with a number of special diff --git a/codex/manual/code-loading.md b/codex/manual/code-loading.md index 7e2652a..8cf646f 100644 --- a/codex/manual/code-loading.md +++ b/codex/manual/code-loading.md @@ -204,7 +204,7 @@ paths = Dict( This example map includes three different kinds of package locations (the first and third are part of the default load path): -1. The private `Priv` package is "[vendored](https://stackoverflow.com/a/35109534/659248)" inside the `App` repository. +1. The private `Priv` package is "[vendored](https://stackoverflow.com/a/35109534)" inside the `App` repository. 2. The public `Priv` and `Zebra` packages are in the system depot, where packages installed and managed by the system administrator live. These are available to all users on the system. 3. The `Pub` package is in the user depot, where packages installed by the user live. These are only available to the user who installed them. diff --git a/codex/manual/environment-variables.md b/codex/manual/environment-variables.md index c410adc..a5c1e77 100644 --- a/codex/manual/environment-variables.md +++ b/codex/manual/environment-variables.md @@ -284,7 +284,7 @@ event listener for just-in-time (JIT) profiling. This environment variable only has an effect if Julia was compiled with JIT profiling support, using either - * Intel's [VTune™ Amplifier](https://software.intel.com/en-us/intel-vtune-amplifier-xe) + * Intel's [VTune™ Amplifier](https://software.intel.com/en-us/vtune) (`USE_INTEL_JITEVENTS` set to `1` in the build configuration), or * [OProfile](http://oprofile.sourceforge.net/news/) (`USE_OPROFILE_JITEVENTS` set to `1` in the build configuration). diff --git a/codex/manual/faq.md b/codex/manual/faq.md index 4db755c..46be5bf 100644 --- a/codex/manual/faq.md +++ b/codex/manual/faq.md @@ -741,7 +741,7 @@ Because supporting generic programming is deemed more important than potential p that can be achieved by other means (e.g., using explicit loops), operators like `+=` and `*=` work by rebinding new values. -## Asynchronous IO and concurrent synchronous writes +## [Asynchronous IO and concurrent synchronous writes](@id faq-async-io) ### Why do concurrent writes to the same stream result in inter-mixed output? diff --git a/codex/manual/integers-and-floating-point-numbers.md b/codex/manual/integers-and-floating-point-numbers.md index b4d82c3..919714e 100644 --- a/codex/manual/integers-and-floating-point-numbers.md +++ b/codex/manual/integers-and-floating-point-numbers.md @@ -505,7 +505,7 @@ Floating-point arithmetic entails many subtleties which can be surprising to use with the low-level implementation details. However, these subtleties are described in detail in most books on scientific computation, and also in the following references: - * The definitive guide to floating point arithmetic is the [IEEE 754-2008 Standard](http://standards.ieee.org/findstds/standard/754-2008.html); + * The definitive guide to floating point arithmetic is the [IEEE 754-2008 Standard](https://standards.ieee.org/standard/754-2008.html); however, it is not available for free online. * For a brief but lucid presentation of how floating-point numbers are represented, see John D. Cook's [article](https://www.johndcook.com/blog/2009/04/06/anatomy-of-a-floating-point-number/) @@ -523,7 +523,7 @@ most books on scientific computation, and also in the following references: ## Arbitrary Precision Arithmetic To allow computations with arbitrary-precision integers and floating point numbers, Julia wraps -the [GNU Multiple Precision Arithmetic Library (GMP)](https://gmplib.org) and the [GNU MPFR Library](http://www.mpfr.org), +the [GNU Multiple Precision Arithmetic Library (GMP)](https://gmplib.org) and the [GNU MPFR Library](https://www.mpfr.org), respectively. The [`BigInt`](@ref) and [`BigFloat`](@ref) types are available in Julia for arbitrary precision integer and floating point numbers respectively. diff --git a/codex/manual/networking-and-streams.md b/codex/manual/networking-and-streams.md index dada5e5..272460a 100644 --- a/codex/manual/networking-and-streams.md +++ b/codex/manual/networking-and-streams.md @@ -234,7 +234,7 @@ Sockets.PipeServer(active) Note that the return type of the last invocation is different. This is because this server does not listen on TCP, but rather on a named pipe (Windows) or UNIX domain socket. Also note that Windows named pipe format has to be a specific pattern such that the name prefix (`\\.\pipe\`) uniquely -identifies the [file type](https://msdn.microsoft.com/en-us/library/windows/desktop/aa365783(v=vs.85).aspx). +identifies the [file type](https://docs.microsoft.com/windows/desktop/ipc/pipe-names). The difference between TCP and named pipes or UNIX domain sockets is subtle and has to do with the [`accept`](@ref) and [`connect`](@ref) methods. The [`accept`](@ref) method retrieves a connection to the client that is connecting on diff --git a/codex/manual/noteworthy-differences.md b/codex/manual/noteworthy-differences.md index fb3d166..bd24907 100644 --- a/codex/manual/noteworthy-differences.md +++ b/codex/manual/noteworthy-differences.md @@ -144,7 +144,7 @@ For users coming to Julia from R, these are some noteworthy differences: For example: * Functions pertaining to probability distributions are provided by the [Distributions package](https://github.com/JuliaStats/Distributions.jl). - * The [DataFrames package](https://github.com/JuliaStats/DataFrames.jl) provides data frames. + * The [DataFrames package](https://github.com/JuliaData/DataFrames.jl) provides data frames. * Generalized linear models are provided by the [GLM package](https://github.com/JuliaStats/GLM.jl). * Julia provides tuples and real hash tables, but not R-style lists. When returning multiple items, you should typically use a tuple or a named tuple: instead of `list(a = 1, b = 2)`, use `(1, 2)` diff --git a/codex/manual/parallel-computing.md b/codex/manual/parallel-computing.md index 80e513b..32cd341 100644 --- a/codex/manual/parallel-computing.md +++ b/codex/manual/parallel-computing.md @@ -627,7 +627,8 @@ block, at which point it surrenders control and waits for all the local tasks to returning from the function. As for v0.7 and beyond, the feeder tasks are able to share state via `nextidx` because they all run on the same process. -Even if `Tasks` are scheduled cooperatively, locking may still be required in some contexts, as in [asynchronous I\O](https://docs.julialang.org/en/stable/manual/faq/#Asynchronous-IO-and-concurrent-synchronous-writes-1). +Even if `Tasks` are scheduled cooperatively, locking may still be required in some contexts, as in +[asynchronous I/O](@ref faq-async-io). This means context switches only occur at well-defined points: in this case, when [`remotecall_fetch`](@ref) is called. This is the current state of implementation and it may change for future Julia versions, as it is intended to make it possible to run up to N `Tasks` on M `Process`, aka @@ -1025,7 +1026,7 @@ on a [`RemoteChannel`](@ref) are proxied onto the backing store on the remote pr [`RemoteChannel`](@ref) can thus be used to refer to user implemented `AbstractChannel` objects. A simple example of this is provided in `dictchannel.jl` in the -[Examples repository](https://github.com/JuliaArchive/Examples), which uses a dictionary as its +[Examples repository](https://github.com/JuliaAttic/Examples), which uses a dictionary as its remote store. @@ -1635,7 +1636,7 @@ transport and Julia's in-built parallel infrastructure. A `BufferStream` is an in-memory [`IOBuffer`](@ref) which behaves like an `IO`--it is a stream which can be handled asynchronously. -The folder `clustermanager/0mq` in the [Examples repository](https://github.com/JuliaArchive/Examples) +The folder `clustermanager/0mq` in the [Examples repository](https://github.com/JuliaAttic/Examples) contains an example of using ZeroMQ to connect Julia workers in a star topology with a 0MQ broker in the middle. Note: The Julia processes are still all *logically* connected to each other--any worker can message any other worker directly without any awareness @@ -1885,7 +1886,7 @@ mpirun -np 4 ./julia example.jl In this context, MPI refers to the MPI-1 standard. Beginning with MPI-2, the MPI standards committee introduced a new set of communication mechanisms, collectively referred to as Remote Memory Access (RMA). The motivation for adding rma to the MPI standard was to facilitate one-sided communication - patterns. For additional information on the latest MPI standard, see [http://mpi-forum.org/docs](http://mpi-forum.org/docs/). + patterns. For additional information on the latest MPI standard, see . [^2]: [Julia GPU man pages](http://juliagpu.github.io/CUDAnative.jl/stable/man/usage.html#Julia-support-1) diff --git a/codex/manual/performance-tips.md b/codex/manual/performance-tips.md index f962cdd..2dbd75a 100644 --- a/codex/manual/performance-tips.md +++ b/codex/manual/performance-tips.md @@ -1129,7 +1129,7 @@ Sometimes you can enable better optimization by promising certain program proper The common idiom of using 1:n to index into an AbstractArray is not safe if the Array uses unconventional indexing, and may cause a segmentation fault if bounds checking is turned off. Use `LinearIndices(x)` or `eachindex(x)` -instead (see also [offset-arrays](https://docs.julialang.org/en/latest/devdocs/offset-arrays)). +instead (see also [offset-arrays](https://docs.julialang.org/en/latest/devdocs/offset-arrays/)). !!! note While `@simd` needs to be placed directly in front of an innermost `for` loop, both `@inbounds` and `@fastmath` diff --git a/codex/manual/strings.md b/codex/manual/strings.md index 1fd2a5b..fac4988 100644 --- a/codex/manual/strings.md +++ b/codex/manual/strings.md @@ -397,7 +397,7 @@ character because `|` is not a valid continuation to it. Finally the string `s2` one too high code point. Julia uses the UTF-8 encoding by default, and support for new encodings can be added by packages. -For example, the [LegacyStrings.jl](https://github.com/JuliaArchive/LegacyStrings.jl) package +For example, the [LegacyStrings.jl](https://github.com/JuliaStrings/LegacyStrings.jl) package implements `UTF16String` and `UTF32String` types. Additional discussion of other encodings and how to implement support for them is beyond the scope of this document for the time being. For further discussion of UTF-8 encoding issues, see the section below on [byte array literals](@ref man-byte-array-literals). @@ -1059,7 +1059,7 @@ some confusion regarding the matter. Version numbers can easily be expressed with non-standard string literals of the form [`v"..."`](@ref @v_str). Version number literals create [`VersionNumber`](@ref) objects which follow the -specifications of [semantic versioning](http://semver.org), +specifications of [semantic versioning](https://semver.org/), and therefore are composed of major, minor and patch numeric values, followed by pre-release and build alpha-numeric annotations. For example, `v"0.2.1-rc1+win64"` is broken into major version `0`, minor version `2`, patch version `1`, pre-release `rc1` and build `win64`. When entering diff --git a/codex/stdlib/Dates.md b/codex/stdlib/Dates.md index 6d5932c..5218861 100644 --- a/codex/stdlib/Dates.md +++ b/codex/stdlib/Dates.md @@ -347,7 +347,7 @@ The `Dates` module approach tries to follow the simple principle of trying to ch little as possible when doing [`Period`](@ref) arithmetic. This approach is also often known as *calendrical* arithmetic or what you would probably guess if someone were to ask you the same calculation in a conversation. Why all the fuss about this? Let's take a classic example: add -1 month to January 31st, 2014. What's the answer? Javascript will say [March 3](http://www.markhneedham.com/blog/2009/01/07/javascript-add-a-month-to-a-date/) +1 month to January 31st, 2014. What's the answer? Javascript will say [March 3](https://markhneedham.com/blog/2009/01/07/javascript-add-a-month-to-a-date/) (assumes 31 days). PHP says [March 2](https://stackoverflow.com/questions/5760262/php-adding-months-to-a-date-while-not-exceeding-the-last-day-of-the-month) (assumes 30 days). The fact is, there is no right answer. In the `Dates` module, it gives the result of February 28th. How does it figure that out? I like to think of the classic 7-7-7 diff --git a/codex/stdlib/LibGit2.md b/codex/stdlib/LibGit2.md index 421540d..2eafb77 100644 --- a/codex/stdlib/LibGit2.md +++ b/codex/stdlib/LibGit2.md @@ -4,7 +4,7 @@ DocTestSetup = :(using LibGit2) ``` -The LibGit2 module provides bindings to [libgit2](https://libgit2.github.com/), a portable C library that +The LibGit2 module provides bindings to [libgit2](https://libgit2.org/), a portable C library that implements core functionality for the [Git](https://git-scm.com/) version control system. These bindings are currently used to power Julia's package manager. It is expected that this module will eventually be moved into a separate package. @@ -13,7 +13,7 @@ It is expected that this module will eventually be moved into a separate package Some of this documentation assumes some prior knowledge of the libgit2 API. For more information on some of the objects and methods referenced here, consult the upstream -[libgit2 API reference](https://libgit2.github.com/libgit2/#v0.25.1). +[libgit2 API reference](https://libgit2.org/libgit2/#v0.25.1). ```@docs LibGit2.Buffer diff --git a/src/base/numbers.md b/src/base/numbers.md index f07f7f5..47a33b4 100644 --- a/src/base/numbers.md +++ b/src/base/numbers.md @@ -115,7 +115,7 @@ Base.@uint128_str The [`BigFloat`](@ref) and [`BigInt`](@ref) types implements arbitrary-precision floating point and integer arithmetic, respectively. For -[`BigFloat`](@ref) the [GNU MPFR library](http://www.mpfr.org/) is used, +[`BigFloat`](@ref) the [GNU MPFR library](https://www.mpfr.org/) is used, and for [`BigInt`](@ref) the [GNU Multiple Precision Arithmetic Library (GMP)] (https://gmplib.org) is used. diff --git a/src/devdocs/inference.md b/src/devdocs/inference.md index df1f908..97f2122 100644 --- a/src/devdocs/inference.md +++ b/src/devdocs/inference.md @@ -75,7 +75,7 @@ in CPU cycles) to each of Julia's intrinsic functions. These costs are based on [standard ranges for common architectures](http://ithare.com/wp-content/uploads/part101_infographics_v08.png) (see -[Agner Fog's analysis](http://www.agner.org/optimize/instruction_tables.pdf) +[Agner Fog's analysis](https://www.agner.org/optimize/instruction_tables.pdf) for more detail). We supplement this low-level lookup table with a number of special diff --git a/src/manual/code-loading.md b/src/manual/code-loading.md index 7e2652a..8cf646f 100644 --- a/src/manual/code-loading.md +++ b/src/manual/code-loading.md @@ -204,7 +204,7 @@ paths = Dict( This example map includes three different kinds of package locations (the first and third are part of the default load path): -1. The private `Priv` package is "[vendored](https://stackoverflow.com/a/35109534/659248)" inside the `App` repository. +1. The private `Priv` package is "[vendored](https://stackoverflow.com/a/35109534)" inside the `App` repository. 2. The public `Priv` and `Zebra` packages are in the system depot, where packages installed and managed by the system administrator live. These are available to all users on the system. 3. The `Pub` package is in the user depot, where packages installed by the user live. These are only available to the user who installed them. diff --git a/src/manual/environment-variables.md b/src/manual/environment-variables.md index c410adc..a5c1e77 100644 --- a/src/manual/environment-variables.md +++ b/src/manual/environment-variables.md @@ -284,7 +284,7 @@ event listener for just-in-time (JIT) profiling. This environment variable only has an effect if Julia was compiled with JIT profiling support, using either - * Intel's [VTune™ Amplifier](https://software.intel.com/en-us/intel-vtune-amplifier-xe) + * Intel's [VTune™ Amplifier](https://software.intel.com/en-us/vtune) (`USE_INTEL_JITEVENTS` set to `1` in the build configuration), or * [OProfile](http://oprofile.sourceforge.net/news/) (`USE_OPROFILE_JITEVENTS` set to `1` in the build configuration). diff --git a/src/manual/faq.md b/src/manual/faq.md index 4db755c..46be5bf 100644 --- a/src/manual/faq.md +++ b/src/manual/faq.md @@ -741,7 +741,7 @@ Because supporting generic programming is deemed more important than potential p that can be achieved by other means (e.g., using explicit loops), operators like `+=` and `*=` work by rebinding new values. -## Asynchronous IO and concurrent synchronous writes +## [Asynchronous IO and concurrent synchronous writes](@id faq-async-io) ### Why do concurrent writes to the same stream result in inter-mixed output? diff --git a/src/manual/integers-and-floating-point-numbers.md b/src/manual/integers-and-floating-point-numbers.md index ce15204..f4a681a 100644 --- a/src/manual/integers-and-floating-point-numbers.md +++ b/src/manual/integers-and-floating-point-numbers.md @@ -458,7 +458,7 @@ julia> bitstring(nextfloat(x)) 부동 소수점 연산은 많은 미묘한 것들을 수반하고 있기 때문에 저수준(low-level) 구현에 익숙하지 않은 유저들은 당활할 수도 있다. 그러나 그 미묘한 점들은 과학적 연산과 관련된 많은 책들에서 잘 설명되고 있고, 아래에 나열하는 참고문헌도 참고하면 좋을 것이다: - * 부동 소수점과 관련해서 가장 확실한 가이드는 [IEEE 754-2008 Standard](http://standards.ieee.org/findstds/standard/754-2008.html)이지만, 유료이다. + * 부동 소수점과 관련해서 가장 확실한 가이드는 [IEEE 754-2008 Standard](https://standards.ieee.org/standard/754-2008.html)이지만, 유료이다. * 부동 소수점이 어떻게 표현되는지에 대한 간략하면서도 명쾌한 설명은 John D. Cook's [블로그 글](https://www.johndcook.com/blog/2009/04/06/anatomy-of-a-floating-point-number/)를 참고하면 된다. 같은 주제에 관하여 이와 더불어서 그의 [소개글](https://www.johndcook.com/blog/2009/04/06/numbers-are-a-leaky-abstraction/)은 부동 소수점이 실수의 이상적인 추상화와 다름으로써 생기는 몇가지 문제에 대해서도 다루고 있다. * Bruce Dawson의 [series of blog posts on floating-point numbers](https://randomascii.wordpress.com/2012/05/20/thats-not-normalthe-performance-of-odd-floats/)도 추천하는 바이다. * 상급자들은 부동 소수점의 내부 구현에 관한 이야기들과 부동 소수점 연산을 할 때 맞닥뜨릴 수 있는 수치적인 정확도에 관한 문제들에 대해서는 David Goldberg의 논문 [What Every Computer Scientist Should Know About Floating-Point Arithmetic](http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.22.6768&rep=rep1&type=pdf)를 참고하는 것이 좋다. @@ -466,7 +466,7 @@ julia> bitstring(nextfloat(x)) ## [임의 정밀도 연산](@id Arbitrary-Precision-Arithmetic) -임의 정밀도의 정수와 부동 소수점들의 연산을 위해, 줄리아는 [GNU Multiple Precision Arithmetic Library (GMP)](https://gmplib.org)와 [GNU MPFR Library](http://www.mpfr.org)을 각각 래빙(wrapping)하였다. [`BigInt`](@ref)와 [`BigFloat`](@ref)타입은 줄리아에서 각각 임의 정밀도의 정수와 부동 소수점을 다루기 위해 사용되고 있다. +임의 정밀도의 정수와 부동 소수점들의 연산을 위해, 줄리아는 [GNU Multiple Precision Arithmetic Library (GMP)](https://gmplib.org)와 [GNU MPFR Library](https://www.mpfr.org)을 각각 래빙(wrapping)하였다. [`BigInt`](@ref)와 [`BigFloat`](@ref)타입은 줄리아에서 각각 임의 정밀도의 정수와 부동 소수점을 다루기 위해 사용되고 있다. 기본 수치 타입으로부터 임의 정밀도 정수와 부동 소수점 타입을 만들기 위해 생성자가 존재하며, [`parse`](@ref)는 `AbstractString`들로 부터 임의 정밀도 타입을 만들 수 있게 해준다. 한번 임의 정밀도 타입이 만들어지면, [type promotion and conversion mechanism](@ref conversion-and-promotion)덕분에 자유롭게 다른 수치타입과 연산을 수행할 수 있다: diff --git a/src/manual/networking-and-streams.md b/src/manual/networking-and-streams.md index dada5e5..272460a 100644 --- a/src/manual/networking-and-streams.md +++ b/src/manual/networking-and-streams.md @@ -234,7 +234,7 @@ Sockets.PipeServer(active) Note that the return type of the last invocation is different. This is because this server does not listen on TCP, but rather on a named pipe (Windows) or UNIX domain socket. Also note that Windows named pipe format has to be a specific pattern such that the name prefix (`\\.\pipe\`) uniquely -identifies the [file type](https://msdn.microsoft.com/en-us/library/windows/desktop/aa365783(v=vs.85).aspx). +identifies the [file type](https://docs.microsoft.com/windows/desktop/ipc/pipe-names). The difference between TCP and named pipes or UNIX domain sockets is subtle and has to do with the [`accept`](@ref) and [`connect`](@ref) methods. The [`accept`](@ref) method retrieves a connection to the client that is connecting on diff --git a/src/manual/noteworthy-differences.md b/src/manual/noteworthy-differences.md index fb3d166..bd24907 100644 --- a/src/manual/noteworthy-differences.md +++ b/src/manual/noteworthy-differences.md @@ -144,7 +144,7 @@ For users coming to Julia from R, these are some noteworthy differences: For example: * Functions pertaining to probability distributions are provided by the [Distributions package](https://github.com/JuliaStats/Distributions.jl). - * The [DataFrames package](https://github.com/JuliaStats/DataFrames.jl) provides data frames. + * The [DataFrames package](https://github.com/JuliaData/DataFrames.jl) provides data frames. * Generalized linear models are provided by the [GLM package](https://github.com/JuliaStats/GLM.jl). * Julia provides tuples and real hash tables, but not R-style lists. When returning multiple items, you should typically use a tuple or a named tuple: instead of `list(a = 1, b = 2)`, use `(1, 2)` diff --git a/src/manual/parallel-computing.md b/src/manual/parallel-computing.md index 80e513b..32cd341 100644 --- a/src/manual/parallel-computing.md +++ b/src/manual/parallel-computing.md @@ -627,7 +627,8 @@ block, at which point it surrenders control and waits for all the local tasks to returning from the function. As for v0.7 and beyond, the feeder tasks are able to share state via `nextidx` because they all run on the same process. -Even if `Tasks` are scheduled cooperatively, locking may still be required in some contexts, as in [asynchronous I\O](https://docs.julialang.org/en/stable/manual/faq/#Asynchronous-IO-and-concurrent-synchronous-writes-1). +Even if `Tasks` are scheduled cooperatively, locking may still be required in some contexts, as in +[asynchronous I/O](@ref faq-async-io). This means context switches only occur at well-defined points: in this case, when [`remotecall_fetch`](@ref) is called. This is the current state of implementation and it may change for future Julia versions, as it is intended to make it possible to run up to N `Tasks` on M `Process`, aka @@ -1025,7 +1026,7 @@ on a [`RemoteChannel`](@ref) are proxied onto the backing store on the remote pr [`RemoteChannel`](@ref) can thus be used to refer to user implemented `AbstractChannel` objects. A simple example of this is provided in `dictchannel.jl` in the -[Examples repository](https://github.com/JuliaArchive/Examples), which uses a dictionary as its +[Examples repository](https://github.com/JuliaAttic/Examples), which uses a dictionary as its remote store. @@ -1635,7 +1636,7 @@ transport and Julia's in-built parallel infrastructure. A `BufferStream` is an in-memory [`IOBuffer`](@ref) which behaves like an `IO`--it is a stream which can be handled asynchronously. -The folder `clustermanager/0mq` in the [Examples repository](https://github.com/JuliaArchive/Examples) +The folder `clustermanager/0mq` in the [Examples repository](https://github.com/JuliaAttic/Examples) contains an example of using ZeroMQ to connect Julia workers in a star topology with a 0MQ broker in the middle. Note: The Julia processes are still all *logically* connected to each other--any worker can message any other worker directly without any awareness @@ -1885,7 +1886,7 @@ mpirun -np 4 ./julia example.jl In this context, MPI refers to the MPI-1 standard. Beginning with MPI-2, the MPI standards committee introduced a new set of communication mechanisms, collectively referred to as Remote Memory Access (RMA). The motivation for adding rma to the MPI standard was to facilitate one-sided communication - patterns. For additional information on the latest MPI standard, see [http://mpi-forum.org/docs](http://mpi-forum.org/docs/). + patterns. For additional information on the latest MPI standard, see . [^2]: [Julia GPU man pages](http://juliagpu.github.io/CUDAnative.jl/stable/man/usage.html#Julia-support-1) diff --git a/src/manual/performance-tips.md b/src/manual/performance-tips.md index f962cdd..2dbd75a 100644 --- a/src/manual/performance-tips.md +++ b/src/manual/performance-tips.md @@ -1129,7 +1129,7 @@ Sometimes you can enable better optimization by promising certain program proper The common idiom of using 1:n to index into an AbstractArray is not safe if the Array uses unconventional indexing, and may cause a segmentation fault if bounds checking is turned off. Use `LinearIndices(x)` or `eachindex(x)` -instead (see also [offset-arrays](https://docs.julialang.org/en/latest/devdocs/offset-arrays)). +instead (see also [offset-arrays](https://docs.julialang.org/en/latest/devdocs/offset-arrays/)). !!! note While `@simd` needs to be placed directly in front of an innermost `for` loop, both `@inbounds` and `@fastmath` diff --git a/src/manual/strings.md b/src/manual/strings.md index 1fd2a5b..fac4988 100644 --- a/src/manual/strings.md +++ b/src/manual/strings.md @@ -397,7 +397,7 @@ character because `|` is not a valid continuation to it. Finally the string `s2` one too high code point. Julia uses the UTF-8 encoding by default, and support for new encodings can be added by packages. -For example, the [LegacyStrings.jl](https://github.com/JuliaArchive/LegacyStrings.jl) package +For example, the [LegacyStrings.jl](https://github.com/JuliaStrings/LegacyStrings.jl) package implements `UTF16String` and `UTF32String` types. Additional discussion of other encodings and how to implement support for them is beyond the scope of this document for the time being. For further discussion of UTF-8 encoding issues, see the section below on [byte array literals](@ref man-byte-array-literals). @@ -1059,7 +1059,7 @@ some confusion regarding the matter. Version numbers can easily be expressed with non-standard string literals of the form [`v"..."`](@ref @v_str). Version number literals create [`VersionNumber`](@ref) objects which follow the -specifications of [semantic versioning](http://semver.org), +specifications of [semantic versioning](https://semver.org/), and therefore are composed of major, minor and patch numeric values, followed by pre-release and build alpha-numeric annotations. For example, `v"0.2.1-rc1+win64"` is broken into major version `0`, minor version `2`, patch version `1`, pre-release `rc1` and build `win64`. When entering diff --git a/src/stdlib/Dates.md b/src/stdlib/Dates.md index 6d5932c..5218861 100644 --- a/src/stdlib/Dates.md +++ b/src/stdlib/Dates.md @@ -347,7 +347,7 @@ The `Dates` module approach tries to follow the simple principle of trying to ch little as possible when doing [`Period`](@ref) arithmetic. This approach is also often known as *calendrical* arithmetic or what you would probably guess if someone were to ask you the same calculation in a conversation. Why all the fuss about this? Let's take a classic example: add -1 month to January 31st, 2014. What's the answer? Javascript will say [March 3](http://www.markhneedham.com/blog/2009/01/07/javascript-add-a-month-to-a-date/) +1 month to January 31st, 2014. What's the answer? Javascript will say [March 3](https://markhneedham.com/blog/2009/01/07/javascript-add-a-month-to-a-date/) (assumes 31 days). PHP says [March 2](https://stackoverflow.com/questions/5760262/php-adding-months-to-a-date-while-not-exceeding-the-last-day-of-the-month) (assumes 30 days). The fact is, there is no right answer. In the `Dates` module, it gives the result of February 28th. How does it figure that out? I like to think of the classic 7-7-7 diff --git a/src/stdlib/LibGit2.md b/src/stdlib/LibGit2.md index 421540d..2eafb77 100644 --- a/src/stdlib/LibGit2.md +++ b/src/stdlib/LibGit2.md @@ -4,7 +4,7 @@ DocTestSetup = :(using LibGit2) ``` -The LibGit2 module provides bindings to [libgit2](https://libgit2.github.com/), a portable C library that +The LibGit2 module provides bindings to [libgit2](https://libgit2.org/), a portable C library that implements core functionality for the [Git](https://git-scm.com/) version control system. These bindings are currently used to power Julia's package manager. It is expected that this module will eventually be moved into a separate package. @@ -13,7 +13,7 @@ It is expected that this module will eventually be moved into a separate package Some of this documentation assumes some prior knowledge of the libgit2 API. For more information on some of the objects and methods referenced here, consult the upstream -[libgit2 API reference](https://libgit2.github.com/libgit2/#v0.25.1). +[libgit2 API reference](https://libgit2.org/libgit2/#v0.25.1). ```@docs LibGit2.Buffer From 5de6c2e8b4425b16af6104845fd6dfe41d1c137c Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Thu, 10 Jan 2019 07:09:37 +0900 Subject: [PATCH 090/153] update Julia Commit 428eb0a071 --- codex/NEWS.md | 8 +++++++- codex/devdocs/isbitsunionarrays.md | 2 +- codex/devdocs/offset-arrays.md | 4 ++-- codex/devdocs/types.md | 2 +- codex/manual/arrays.md | 8 ++++---- codex/manual/strings.md | 8 ++++---- src/NEWS.md | 8 +++++++- src/devdocs/isbitsunionarrays.md | 2 +- src/devdocs/offset-arrays.md | 4 ++-- src/devdocs/types.md | 2 +- src/manual/arrays.md | 8 ++++---- src/manual/strings.md | 8 ++++---- 12 files changed, 38 insertions(+), 26 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index cbd598e..798c5c7 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -29,7 +29,6 @@ New library functions Standard library changes ------------------------ - #### LinearAlgebra * Added keyword arguments `rtol`, `atol` to `pinv` and `nullspace` ([#29998](https://github.com/JuliaLang/julia/issues/29998)). @@ -42,10 +41,17 @@ Standard library changes * Fixed `repr` such that it displays `DateTime` as it would be entered in Julia ([#30200](https://github.com/JuliaLang/julia/issues/30200)). +#### Miscellaneous + +* Since environment variables on Windows are case-insensitive, `ENV` now converts its keys + to uppercase for display, iteration, and copying ([#30593](https://github.com/JuliaLang/julia/issues/30593)). External dependencies --------------------- +* libgit2 has been updated to v0.27.7 ([#30584](https://github.com/JuliaLang/julia/issues/30584)). +* OpenBLAS has been updated to v0.3.5 ([#30583](https://github.com/JuliaLang/julia/issues/30583)). +* MbedTLS has been updated to v2.16.0 ([#30618](https://github.com/JuliaLang/julia/issues/30618)). Deprecated or removed --------------------- diff --git a/codex/devdocs/isbitsunionarrays.md b/codex/devdocs/isbitsunionarrays.md index ad5e16c..824b621 100644 --- a/codex/devdocs/isbitsunionarrays.md +++ b/codex/devdocs/isbitsunionarrays.md @@ -6,7 +6,7 @@ Julia also supports Union types, quite literally the union of a set of types. Cu ## isbits Union Structs -Julia now includes an optimization wherein "isbits Union" fields in types (`mutable struct`, `struct`, etc.) will be stored inline. This is accomplished by determining the "inline size" of the Union type (e.g. `Union{UInt8, Int16}` will have a size of two bytes, which represents the size needed of the largest Union type `Int16`), and in addition, allocating an extra "type tag byte" (`UInt8`), whose value signals the type of the actual value stored inline of the "Union bytes". The type tag byte value is the index of the actual value's type in the Union type's order of types. For example, a type tag value of `0x02` for a field with type `Union{Nothing, UInt8, Int16}` would indicate that an `Int16` value is stored in the 16 bytes of the field in the structure's memory; a `0x01` value would indicate that a `UInt8` value was stored in the first 8 bytes of the 16 bytes of the field's memory. Lastly, a value of `0x00` signals that the `nothing` value will be returned for this field, even though, as a singleton type with a single type instance, it technically has a size of 0. The type tag byte for a type's Union field is stored directly after the field's computed Union memory. +Julia now includes an optimization wherein "isbits Union" fields in types (`mutable struct`, `struct`, etc.) will be stored inline. This is accomplished by determining the "inline size" of the Union type (e.g. `Union{UInt8, Int16}` will have a size of two bytes, which represents the size needed of the largest Union type `Int16`), and in addition, allocating an extra "type tag byte" (`UInt8`), whose value signals the type of the actual value stored inline of the "Union bytes". The type tag byte value is the index of the actual value's type in the Union type's order of types. For example, a type tag value of `0x02` for a field with type `Union{Nothing, UInt8, Int16}` would indicate that an `Int16` value is stored in the 2 bytes of the field in the structure's memory; a `0x01` value would indicate that a `UInt8` value was stored in the first 1 byte of the 2 bytes of the field's memory. Lastly, a value of `0x00` signals that the `nothing` value will be returned for this field, even though, as a singleton type with a single type instance, it technically has a size of 0. The type tag byte for a type's Union field is stored directly after the field's computed Union memory. ## isbits Union Arrays diff --git a/codex/devdocs/offset-arrays.md b/codex/devdocs/offset-arrays.md index 3464b94..84b6037 100644 --- a/codex/devdocs/offset-arrays.md +++ b/codex/devdocs/offset-arrays.md @@ -27,7 +27,7 @@ As an overview, the steps are: * replace many uses of `size` with `axes` * replace `1:length(A)` with `eachindex(A)`, or in some cases `LinearIndices(A)` - * replace explicit allocations like `Array{Int}(size(B))` with `similar(Array{Int}, axes(B))` + * replace explicit allocations like `Array{Int}(undef, size(B))` with `similar(Array{Int}, axes(B))` These are described in more detail below. @@ -101,7 +101,7 @@ underlying "conventional" behavior you'd like, e.g., `Array{Int}` or `BitArray` a convenient way of producing an all-zeros array that matches the indices of A is simply `zeros(A)`. Let's walk through a couple of explicit examples. First, if `A` has conventional indices, then -`similar(Array{Int}, axes(A))` would end up calling `Array{Int}(size(A))`, and thus return +`similar(Array{Int}, axes(A))` would end up calling `Array{Int}(undef, size(A))`, and thus return an array. If `A` is an `AbstractArray` type with unconventional indexing, then `similar(Array{Int}, axes(A))` should return something that "behaves like" an `Array{Int}` but with a shape (including indices) that matches `A`. (The most obvious implementation is to allocate an `Array{Int}(undef, size(A))` and diff --git a/codex/devdocs/types.md b/codex/devdocs/types.md index 0505521..b795add 100644 --- a/codex/devdocs/types.md +++ b/codex/devdocs/types.md @@ -82,7 +82,7 @@ f3(A::Array{T}) where {T<:Any} = 3 f4(A::Array{Any}) = 4 ``` -The signature of `f3` is a `UnionAll` type wrapping a tuple type. +The signature - as decribed in [Function calls](@ref) - of `f3` is a `UnionAll` type wrapping a tuple type: `Tuple{typeof(f3), Array{T}} where T`. All but `f4` can be called with `a = [1,2]`; all but `f2` can be called with `b = Any[1,2]`. Let's look at these types a little more closely: diff --git a/codex/manual/arrays.md b/codex/manual/arrays.md index 4667fb4..c1c4682 100644 --- a/codex/manual/arrays.md +++ b/codex/manual/arrays.md @@ -634,10 +634,10 @@ julia> x[[false, true, true, false], :] julia> mask = map(ispow2, x) 4×4 Array{Bool,2}: - true false false false - true false false false - false false false false - true true false true + 1 0 0 0 + 1 0 0 0 + 0 0 0 0 + 1 1 0 1 julia> x[mask] 5-element Array{Int64,1}: diff --git a/codex/manual/strings.md b/codex/manual/strings.md index fac4988..7832bba 100644 --- a/codex/manual/strings.md +++ b/codex/manual/strings.md @@ -376,10 +376,10 @@ julia> foreach(display, s) julia> isvalid.(collect(s)) 4-element BitArray{1}: - false - false - false - true + 0 + 0 + 0 + 1 julia> s2 = "\xf7\xbf\xbf\xbf" "\U1fffff" diff --git a/src/NEWS.md b/src/NEWS.md index cbd598e..798c5c7 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -29,7 +29,6 @@ New library functions Standard library changes ------------------------ - #### LinearAlgebra * Added keyword arguments `rtol`, `atol` to `pinv` and `nullspace` ([#29998](https://github.com/JuliaLang/julia/issues/29998)). @@ -42,10 +41,17 @@ Standard library changes * Fixed `repr` such that it displays `DateTime` as it would be entered in Julia ([#30200](https://github.com/JuliaLang/julia/issues/30200)). +#### Miscellaneous + +* Since environment variables on Windows are case-insensitive, `ENV` now converts its keys + to uppercase for display, iteration, and copying ([#30593](https://github.com/JuliaLang/julia/issues/30593)). External dependencies --------------------- +* libgit2 has been updated to v0.27.7 ([#30584](https://github.com/JuliaLang/julia/issues/30584)). +* OpenBLAS has been updated to v0.3.5 ([#30583](https://github.com/JuliaLang/julia/issues/30583)). +* MbedTLS has been updated to v2.16.0 ([#30618](https://github.com/JuliaLang/julia/issues/30618)). Deprecated or removed --------------------- diff --git a/src/devdocs/isbitsunionarrays.md b/src/devdocs/isbitsunionarrays.md index ad5e16c..824b621 100644 --- a/src/devdocs/isbitsunionarrays.md +++ b/src/devdocs/isbitsunionarrays.md @@ -6,7 +6,7 @@ Julia also supports Union types, quite literally the union of a set of types. Cu ## isbits Union Structs -Julia now includes an optimization wherein "isbits Union" fields in types (`mutable struct`, `struct`, etc.) will be stored inline. This is accomplished by determining the "inline size" of the Union type (e.g. `Union{UInt8, Int16}` will have a size of two bytes, which represents the size needed of the largest Union type `Int16`), and in addition, allocating an extra "type tag byte" (`UInt8`), whose value signals the type of the actual value stored inline of the "Union bytes". The type tag byte value is the index of the actual value's type in the Union type's order of types. For example, a type tag value of `0x02` for a field with type `Union{Nothing, UInt8, Int16}` would indicate that an `Int16` value is stored in the 16 bytes of the field in the structure's memory; a `0x01` value would indicate that a `UInt8` value was stored in the first 8 bytes of the 16 bytes of the field's memory. Lastly, a value of `0x00` signals that the `nothing` value will be returned for this field, even though, as a singleton type with a single type instance, it technically has a size of 0. The type tag byte for a type's Union field is stored directly after the field's computed Union memory. +Julia now includes an optimization wherein "isbits Union" fields in types (`mutable struct`, `struct`, etc.) will be stored inline. This is accomplished by determining the "inline size" of the Union type (e.g. `Union{UInt8, Int16}` will have a size of two bytes, which represents the size needed of the largest Union type `Int16`), and in addition, allocating an extra "type tag byte" (`UInt8`), whose value signals the type of the actual value stored inline of the "Union bytes". The type tag byte value is the index of the actual value's type in the Union type's order of types. For example, a type tag value of `0x02` for a field with type `Union{Nothing, UInt8, Int16}` would indicate that an `Int16` value is stored in the 2 bytes of the field in the structure's memory; a `0x01` value would indicate that a `UInt8` value was stored in the first 1 byte of the 2 bytes of the field's memory. Lastly, a value of `0x00` signals that the `nothing` value will be returned for this field, even though, as a singleton type with a single type instance, it technically has a size of 0. The type tag byte for a type's Union field is stored directly after the field's computed Union memory. ## isbits Union Arrays diff --git a/src/devdocs/offset-arrays.md b/src/devdocs/offset-arrays.md index 3464b94..84b6037 100644 --- a/src/devdocs/offset-arrays.md +++ b/src/devdocs/offset-arrays.md @@ -27,7 +27,7 @@ As an overview, the steps are: * replace many uses of `size` with `axes` * replace `1:length(A)` with `eachindex(A)`, or in some cases `LinearIndices(A)` - * replace explicit allocations like `Array{Int}(size(B))` with `similar(Array{Int}, axes(B))` + * replace explicit allocations like `Array{Int}(undef, size(B))` with `similar(Array{Int}, axes(B))` These are described in more detail below. @@ -101,7 +101,7 @@ underlying "conventional" behavior you'd like, e.g., `Array{Int}` or `BitArray` a convenient way of producing an all-zeros array that matches the indices of A is simply `zeros(A)`. Let's walk through a couple of explicit examples. First, if `A` has conventional indices, then -`similar(Array{Int}, axes(A))` would end up calling `Array{Int}(size(A))`, and thus return +`similar(Array{Int}, axes(A))` would end up calling `Array{Int}(undef, size(A))`, and thus return an array. If `A` is an `AbstractArray` type with unconventional indexing, then `similar(Array{Int}, axes(A))` should return something that "behaves like" an `Array{Int}` but with a shape (including indices) that matches `A`. (The most obvious implementation is to allocate an `Array{Int}(undef, size(A))` and diff --git a/src/devdocs/types.md b/src/devdocs/types.md index 0505521..b795add 100644 --- a/src/devdocs/types.md +++ b/src/devdocs/types.md @@ -82,7 +82,7 @@ f3(A::Array{T}) where {T<:Any} = 3 f4(A::Array{Any}) = 4 ``` -The signature of `f3` is a `UnionAll` type wrapping a tuple type. +The signature - as decribed in [Function calls](@ref) - of `f3` is a `UnionAll` type wrapping a tuple type: `Tuple{typeof(f3), Array{T}} where T`. All but `f4` can be called with `a = [1,2]`; all but `f2` can be called with `b = Any[1,2]`. Let's look at these types a little more closely: diff --git a/src/manual/arrays.md b/src/manual/arrays.md index fc0acf4..b677b44 100644 --- a/src/manual/arrays.md +++ b/src/manual/arrays.md @@ -592,10 +592,10 @@ julia> x[[false, true, true, false], :] julia> mask = map(ispow2, x) 4×4 Array{Bool,2}: - true false false false - true false false false - false false false false - true true false true + 1 0 0 0 + 1 0 0 0 + 0 0 0 0 + 1 1 0 1 julia> x[mask] 5-element Array{Int64,1}: diff --git a/src/manual/strings.md b/src/manual/strings.md index fac4988..7832bba 100644 --- a/src/manual/strings.md +++ b/src/manual/strings.md @@ -376,10 +376,10 @@ julia> foreach(display, s) julia> isvalid.(collect(s)) 4-element BitArray{1}: - false - false - false - true + 0 + 0 + 0 + 1 julia> s2 = "\xf7\xbf\xbf\xbf" "\U1fffff" From b3f59dbd3926f56d873b942c51db2e6511444308 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Tue, 15 Jan 2019 12:13:32 +0900 Subject: [PATCH 091/153] update Julia Commit 7ed9e4fb35 --- codex/NEWS.md | 1 + codex/base/arrays.md | 3 ++ codex/devdocs/offset-arrays.md | 2 +- codex/devdocs/sysimg.md | 2 +- codex/manual/strings.md | 42 +++++++++++++++++++------ codex/manual/variables-and-scoping.md | 44 +++++++++++++++------------ codex/manual/variables.md | 4 +-- src/NEWS.md | 1 + src/base/arrays.md | 3 ++ src/devdocs/offset-arrays.md | 2 +- src/devdocs/sysimg.md | 2 +- src/manual/strings.md | 42 +++++++++++++++++++------ src/manual/variables-and-scoping.md | 44 +++++++++++++++------------ src/manual/variables.md | 4 +-- 14 files changed, 132 insertions(+), 64 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index 798c5c7..51ff283 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -16,6 +16,7 @@ Multi-threading changes Language changes ---------------- +* `Enum` now behaves like a scalar when used in broadcasting ([#30670](https://github.com/JuliaLang/julia/issues/30670)). Command-line option changes --------------------------- diff --git a/codex/base/arrays.md b/codex/base/arrays.md index 6cad1e6..5805223 100644 --- a/codex/base/arrays.md +++ b/codex/base/arrays.md @@ -80,6 +80,9 @@ Base.Broadcast.AbstractArrayStyle Base.Broadcast.ArrayStyle Base.Broadcast.DefaultArrayStyle Base.Broadcast.broadcastable +Base.Broadcast.combine_axes +Base.Broadcast.combine_styles +Base.Broadcast.result_style ``` ## Indexing and assignment diff --git a/codex/devdocs/offset-arrays.md b/codex/devdocs/offset-arrays.md index 84b6037..a172f6c 100644 --- a/codex/devdocs/offset-arrays.md +++ b/codex/devdocs/offset-arrays.md @@ -15,7 +15,7 @@ the exported interfaces of Julia. If you find it more convenient to just force your users to supply traditional arrays where indexing starts at one, you can add ```julia -@assert !Base.has_offset_axes(arrays...) +Base.require_one_based_indexing(arrays...) ``` where `arrays...` is a list of the array objects that you wish to check for anything that diff --git a/codex/devdocs/sysimg.md b/codex/devdocs/sysimg.md index a354a5f..8010df8 100644 --- a/codex/devdocs/sysimg.md +++ b/codex/devdocs/sysimg.md @@ -60,7 +60,7 @@ Additionally, a few special features are supported to control the function cloni 3. `opt_size` - This cause the function for the targe to be optimize for size when there isn't a significant + This causes the function for the target to be optimized for size when there isn't a significant runtime performance impact. This corresponds to `-Os` GCC and Clang option. 4. `min_size` diff --git a/codex/manual/strings.md b/codex/manual/strings.md index 7832bba..60eea9c 100644 --- a/codex/manual/strings.md +++ b/codex/manual/strings.md @@ -180,12 +180,12 @@ julia> str[end] ``` Many Julia objects, including strings, can be indexed with integers. The index of the first -element is returned by [`firstindex(str)`](@ref), and the index of the last element +element (the first character of a string) is returned by [`firstindex(str)`](@ref), and the index of the last element (character) with [`lastindex(str)`](@ref). The keyword `end` can be used inside an indexing operation as shorthand for the last index along the given dimension. -Most indexing in Julia is 1-based: the first element of many integer-indexed objects is found at -index 1. (As we will see below, this does not necessarily mean that the last element is found -at index `n`, where `n` is the length of the string.) +String indexing, like most indexing in Julia, is 1-based: `firstindex` always returns `1` for any `AbstractString`. +As we will see below, however, `lastindex(str)` is *not* in general the same as `length(str)` for a string, +because some Unicode characters can occupy multiple "code units". You can perform arithmetic and other operations with [`end`](@ref), just like a normal value: @@ -265,10 +265,13 @@ julia> s = "\u2200 x \u2203 y" Whether these Unicode characters are displayed as escapes or shown as special characters depends on your terminal's locale settings and its support for Unicode. String literals are encoded using the UTF-8 encoding. UTF-8 is a variable-width encoding, meaning that not all characters are encoded -in the same number of bytes. In UTF-8, ASCII characters -- i.e. those with code points less than +in the same number of bytes ("code units"). In UTF-8, ASCII characters — i.e. those with code points less than 0x80 (128) -- are encoded as they are in ASCII, using a single byte, while code points 0x80 and -above are encoded using multiple bytes -- up to four per character. This means that not every -byte index into a UTF-8 string is necessarily a valid index for a character. If you index into +above are encoded using multiple bytes — up to four per character. + +String indices in Julia refer to code units (= bytes for UTF-8), the fixed-width building blocks that +are used to encode arbitrary characters (code points). This means that not every +index into a `String` is necessarily a valid index for a character. If you index into a string at such an invalid byte index, an error is thrown: ```jldoctest unicodestring @@ -348,6 +351,26 @@ x y ``` +If you need to obtain valid indices for a string, you can use the [`nextind`](@ref) and +[`prevind`](@ref) functions to increment/decrement to the next/previous valid index, as mentioned above. +You can also use the [`eachindex`](@ref) function to iterate over the valid character indices: + +```jldoctest unicodestring +julia> collect(eachindex(s)) +7-element Array{Int64,1}: + 1 + 4 + 5 + 6 + 7 + 10 + 11 +``` + +To access the raw code units (bytes for UTF-8) of the encoding, you can use the [`codeunit(s,i)`](@ref) +function, where the index `i` runs consecutively from `1` to [`ncodeunits(s)`](@ref). The [`codeunits(s)`](@ref) +function returns an `AbstractVector{UInt8}` wrapper that lets you access these raw codeunits (bytes) as an array. + Strings in Julia can contain invalid UTF-8 code unit sequences. This convention allows to treat any byte sequence as a `String`. In such situations a rule is that when parsing a sequence of code units from left to right characters are formed by the longest sequence of @@ -361,8 +384,9 @@ a sequence of code units from left to right characters are formed by the longest * `10xxxxxx`; * `11111xxx`. -In particular this implies that overlong and too high code unit sequences are accepted. -This rule is best explained by an example: +In particular this means that overlong and too-high code unit sequences and prefixes thereof are treated +as a single invalid character rather than multiple invalid characters. +This rule may be best explained with an example: ```julia-repl julia> s = "\xc0\xa0\xe2\x88\xe2|" diff --git a/codex/manual/variables-and-scoping.md b/codex/manual/variables-and-scoping.md index eae8c87..d15f4a5 100644 --- a/codex/manual/variables-and-scoping.md +++ b/codex/manual/variables-and-scoping.md @@ -26,7 +26,7 @@ comprehensions, broadcast-fusing | local | global or local Notably missing from this table are [begin blocks](@ref man-compound-expressions) and [if blocks](@ref man-conditional-evaluation) -which do *not* introduce new scope blocks. +which do *not* introduce new scopes. Both types of scopes follow somewhat different rules which will be explained below. Julia uses [lexical scoping](https://en.wikipedia.org/wiki/Scope_%28computer_science%29#Lexical_scoping_vs._dynamic_scoping), @@ -97,15 +97,12 @@ A new local scope is introduced by most code blocks (see above [table](@ref man-scope-table) for a complete list). A local scope inherits all the variables from a parent local scope, both for reading and writing. -Additionally, the local scope inherits all global variables that are assigned -in its parent global scope block (if it is surrounded by a global `if` or `begin` scope). Unlike global scopes, local scopes are not namespaces, thus variables in an inner scope cannot be retrieved from the parent scope through some sort of qualified access. The following rules and examples pertain to local scopes. -A newly introduced variable in a local scope does not -back-propagate to its parent scope. +A newly introduced variable in a local scope cannot be referenced by a parent scope. For example, here the ``z`` is not introduced into the top-level scope: ```jldoctest @@ -121,18 +118,30 @@ ERROR: UndefVarError: z not defined In this and all following examples it is assumed that their top-level is a global scope with a clean workspace, for instance a newly started REPL. -Inside a local scope a variable can be forced to be a new local variable using the [`local`](@ref) keyword: +Inner local scopes can, however, update variables in their parent scopes: ```jldoctest -julia> x = 0; +julia> for i = 1:1 + z = i + for j = 1:1 + z = 0 + end + println(z) + end +0 +``` -julia> for i = 1:10 - local x # this is also the default +Inside a local scope a variable can be forced to be a new local variable using the [`local`](@ref) keyword: + +```jldoctest +julia> for i = 1:1 x = i + 1 + for j = 1:1 + local x = 0 + end + println(x) end - -julia> x -0 +2 ``` Inside a local scope a global variable can be assigned to by using the keyword [`global`](@ref): @@ -163,9 +172,6 @@ julia> z The `local` and `global` keywords can also be applied to destructuring assignments, e.g. `local x, y = 1, 2`. In this case the keyword affects all listed variables. -Local scopes are introduced by most block keywords, -with notable exceptions of `begin` and `if`. - In a local scope, all variables are inherited from its parent global scope block unless: @@ -194,8 +200,8 @@ An explicit `global` is needed to assign to a global variable: !!! sidebar "Avoiding globals" Avoiding changing the value of global variables is considered by many to be a programming best-practice. - One reason for this is that remotely changing the state of global variables in other - modules should be done with care as it makes the local behavior of the program hard to reason about. + Changing the value of a global variable can cause "action at a distance", + making the behavior of a program harder to reason about. This is why the scope blocks that introduce local scope require the `global` keyword to declare the intent to modify a global variable. @@ -233,9 +239,9 @@ julia> x, y # verify that global x and y are unchanged (1, 2) ``` -The reason to allow *modifying local* variables of parent scopes in +The reason to allow modifying local variables of parent scopes in nested functions is to allow constructing [`closures`](https://en.wikipedia.org/wiki/Closure_%28computer_programming%29) -which have a private state, for instance the `state` variable in the +which have private state, for instance the `state` variable in the following example: ```jldoctest diff --git a/codex/manual/variables.md b/codex/manual/variables.md index 317b162..0ede5e7 100644 --- a/codex/manual/variables.md +++ b/codex/manual/variables.md @@ -81,13 +81,13 @@ julia> pi π = 3.1415926535897... julia> pi = 3 -ERROR: cannot assign variable MathConstants.pi from module Main +ERROR: cannot assign a value to variable MathConstants.pi from module Main julia> sqrt(100) 10.0 julia> sqrt = 4 -ERROR: cannot assign variable Base.sqrt from module Main +ERROR: cannot assign a value to variable Base.sqrt from module Main ``` ## Allowed Variable Names diff --git a/src/NEWS.md b/src/NEWS.md index 798c5c7..51ff283 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -16,6 +16,7 @@ Multi-threading changes Language changes ---------------- +* `Enum` now behaves like a scalar when used in broadcasting ([#30670](https://github.com/JuliaLang/julia/issues/30670)). Command-line option changes --------------------------- diff --git a/src/base/arrays.md b/src/base/arrays.md index 6cad1e6..5805223 100644 --- a/src/base/arrays.md +++ b/src/base/arrays.md @@ -80,6 +80,9 @@ Base.Broadcast.AbstractArrayStyle Base.Broadcast.ArrayStyle Base.Broadcast.DefaultArrayStyle Base.Broadcast.broadcastable +Base.Broadcast.combine_axes +Base.Broadcast.combine_styles +Base.Broadcast.result_style ``` ## Indexing and assignment diff --git a/src/devdocs/offset-arrays.md b/src/devdocs/offset-arrays.md index 84b6037..a172f6c 100644 --- a/src/devdocs/offset-arrays.md +++ b/src/devdocs/offset-arrays.md @@ -15,7 +15,7 @@ the exported interfaces of Julia. If you find it more convenient to just force your users to supply traditional arrays where indexing starts at one, you can add ```julia -@assert !Base.has_offset_axes(arrays...) +Base.require_one_based_indexing(arrays...) ``` where `arrays...` is a list of the array objects that you wish to check for anything that diff --git a/src/devdocs/sysimg.md b/src/devdocs/sysimg.md index a354a5f..8010df8 100644 --- a/src/devdocs/sysimg.md +++ b/src/devdocs/sysimg.md @@ -60,7 +60,7 @@ Additionally, a few special features are supported to control the function cloni 3. `opt_size` - This cause the function for the targe to be optimize for size when there isn't a significant + This causes the function for the target to be optimized for size when there isn't a significant runtime performance impact. This corresponds to `-Os` GCC and Clang option. 4. `min_size` diff --git a/src/manual/strings.md b/src/manual/strings.md index 7832bba..60eea9c 100644 --- a/src/manual/strings.md +++ b/src/manual/strings.md @@ -180,12 +180,12 @@ julia> str[end] ``` Many Julia objects, including strings, can be indexed with integers. The index of the first -element is returned by [`firstindex(str)`](@ref), and the index of the last element +element (the first character of a string) is returned by [`firstindex(str)`](@ref), and the index of the last element (character) with [`lastindex(str)`](@ref). The keyword `end` can be used inside an indexing operation as shorthand for the last index along the given dimension. -Most indexing in Julia is 1-based: the first element of many integer-indexed objects is found at -index 1. (As we will see below, this does not necessarily mean that the last element is found -at index `n`, where `n` is the length of the string.) +String indexing, like most indexing in Julia, is 1-based: `firstindex` always returns `1` for any `AbstractString`. +As we will see below, however, `lastindex(str)` is *not* in general the same as `length(str)` for a string, +because some Unicode characters can occupy multiple "code units". You can perform arithmetic and other operations with [`end`](@ref), just like a normal value: @@ -265,10 +265,13 @@ julia> s = "\u2200 x \u2203 y" Whether these Unicode characters are displayed as escapes or shown as special characters depends on your terminal's locale settings and its support for Unicode. String literals are encoded using the UTF-8 encoding. UTF-8 is a variable-width encoding, meaning that not all characters are encoded -in the same number of bytes. In UTF-8, ASCII characters -- i.e. those with code points less than +in the same number of bytes ("code units"). In UTF-8, ASCII characters — i.e. those with code points less than 0x80 (128) -- are encoded as they are in ASCII, using a single byte, while code points 0x80 and -above are encoded using multiple bytes -- up to four per character. This means that not every -byte index into a UTF-8 string is necessarily a valid index for a character. If you index into +above are encoded using multiple bytes — up to four per character. + +String indices in Julia refer to code units (= bytes for UTF-8), the fixed-width building blocks that +are used to encode arbitrary characters (code points). This means that not every +index into a `String` is necessarily a valid index for a character. If you index into a string at such an invalid byte index, an error is thrown: ```jldoctest unicodestring @@ -348,6 +351,26 @@ x y ``` +If you need to obtain valid indices for a string, you can use the [`nextind`](@ref) and +[`prevind`](@ref) functions to increment/decrement to the next/previous valid index, as mentioned above. +You can also use the [`eachindex`](@ref) function to iterate over the valid character indices: + +```jldoctest unicodestring +julia> collect(eachindex(s)) +7-element Array{Int64,1}: + 1 + 4 + 5 + 6 + 7 + 10 + 11 +``` + +To access the raw code units (bytes for UTF-8) of the encoding, you can use the [`codeunit(s,i)`](@ref) +function, where the index `i` runs consecutively from `1` to [`ncodeunits(s)`](@ref). The [`codeunits(s)`](@ref) +function returns an `AbstractVector{UInt8}` wrapper that lets you access these raw codeunits (bytes) as an array. + Strings in Julia can contain invalid UTF-8 code unit sequences. This convention allows to treat any byte sequence as a `String`. In such situations a rule is that when parsing a sequence of code units from left to right characters are formed by the longest sequence of @@ -361,8 +384,9 @@ a sequence of code units from left to right characters are formed by the longest * `10xxxxxx`; * `11111xxx`. -In particular this implies that overlong and too high code unit sequences are accepted. -This rule is best explained by an example: +In particular this means that overlong and too-high code unit sequences and prefixes thereof are treated +as a single invalid character rather than multiple invalid characters. +This rule may be best explained with an example: ```julia-repl julia> s = "\xc0\xa0\xe2\x88\xe2|" diff --git a/src/manual/variables-and-scoping.md b/src/manual/variables-and-scoping.md index eae8c87..d15f4a5 100644 --- a/src/manual/variables-and-scoping.md +++ b/src/manual/variables-and-scoping.md @@ -26,7 +26,7 @@ comprehensions, broadcast-fusing | local | global or local Notably missing from this table are [begin blocks](@ref man-compound-expressions) and [if blocks](@ref man-conditional-evaluation) -which do *not* introduce new scope blocks. +which do *not* introduce new scopes. Both types of scopes follow somewhat different rules which will be explained below. Julia uses [lexical scoping](https://en.wikipedia.org/wiki/Scope_%28computer_science%29#Lexical_scoping_vs._dynamic_scoping), @@ -97,15 +97,12 @@ A new local scope is introduced by most code blocks (see above [table](@ref man-scope-table) for a complete list). A local scope inherits all the variables from a parent local scope, both for reading and writing. -Additionally, the local scope inherits all global variables that are assigned -in its parent global scope block (if it is surrounded by a global `if` or `begin` scope). Unlike global scopes, local scopes are not namespaces, thus variables in an inner scope cannot be retrieved from the parent scope through some sort of qualified access. The following rules and examples pertain to local scopes. -A newly introduced variable in a local scope does not -back-propagate to its parent scope. +A newly introduced variable in a local scope cannot be referenced by a parent scope. For example, here the ``z`` is not introduced into the top-level scope: ```jldoctest @@ -121,18 +118,30 @@ ERROR: UndefVarError: z not defined In this and all following examples it is assumed that their top-level is a global scope with a clean workspace, for instance a newly started REPL. -Inside a local scope a variable can be forced to be a new local variable using the [`local`](@ref) keyword: +Inner local scopes can, however, update variables in their parent scopes: ```jldoctest -julia> x = 0; +julia> for i = 1:1 + z = i + for j = 1:1 + z = 0 + end + println(z) + end +0 +``` -julia> for i = 1:10 - local x # this is also the default +Inside a local scope a variable can be forced to be a new local variable using the [`local`](@ref) keyword: + +```jldoctest +julia> for i = 1:1 x = i + 1 + for j = 1:1 + local x = 0 + end + println(x) end - -julia> x -0 +2 ``` Inside a local scope a global variable can be assigned to by using the keyword [`global`](@ref): @@ -163,9 +172,6 @@ julia> z The `local` and `global` keywords can also be applied to destructuring assignments, e.g. `local x, y = 1, 2`. In this case the keyword affects all listed variables. -Local scopes are introduced by most block keywords, -with notable exceptions of `begin` and `if`. - In a local scope, all variables are inherited from its parent global scope block unless: @@ -194,8 +200,8 @@ An explicit `global` is needed to assign to a global variable: !!! sidebar "Avoiding globals" Avoiding changing the value of global variables is considered by many to be a programming best-practice. - One reason for this is that remotely changing the state of global variables in other - modules should be done with care as it makes the local behavior of the program hard to reason about. + Changing the value of a global variable can cause "action at a distance", + making the behavior of a program harder to reason about. This is why the scope blocks that introduce local scope require the `global` keyword to declare the intent to modify a global variable. @@ -233,9 +239,9 @@ julia> x, y # verify that global x and y are unchanged (1, 2) ``` -The reason to allow *modifying local* variables of parent scopes in +The reason to allow modifying local variables of parent scopes in nested functions is to allow constructing [`closures`](https://en.wikipedia.org/wiki/Closure_%28computer_programming%29) -which have a private state, for instance the `state` variable in the +which have private state, for instance the `state` variable in the following example: ```jldoctest diff --git a/src/manual/variables.md b/src/manual/variables.md index d71d335..1864268 100644 --- a/src/manual/variables.md +++ b/src/manual/variables.md @@ -77,13 +77,13 @@ julia> pi π = 3.1415926535897... julia> pi = 3 -ERROR: cannot assign variable MathConstants.pi from module Main +ERROR: cannot assign a value to variable MathConstants.pi from module Main julia> sqrt(100) 10.0 julia> sqrt = 4 -ERROR: cannot assign variable Base.sqrt from module Main +ERROR: cannot assign a value to variable Base.sqrt from module Main ``` ##허용된 변수 이름 From 5419e4ea0ccc9541a7251274d8b464de99bf3897 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Fri, 25 Jan 2019 10:13:50 +0900 Subject: [PATCH 092/153] update Julia 1.2.0-DEV.213 (2019-01-24) Commit caf65e011b --- codex/NEWS.md | 5 + codex/devdocs/ast.md | 453 +++++++++++++++-------------- codex/manual/embedding.md | 105 ++++++- codex/manual/parallel-computing.md | 2 +- codex/manual/types.md | 2 +- src/NEWS.md | 5 + src/devdocs/ast.md | 453 +++++++++++++++-------------- src/manual/embedding.md | 105 ++++++- src/manual/parallel-computing.md | 2 +- src/manual/types.md | 2 +- 10 files changed, 668 insertions(+), 466 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index 51ff283..af70bb6 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -33,10 +33,14 @@ Standard library changes #### LinearAlgebra * Added keyword arguments `rtol`, `atol` to `pinv` and `nullspace` ([#29998](https://github.com/JuliaLang/julia/issues/29998)). +* `UniformScaling` instances are now callable such that e.g. `I(3)` will produce a `Diagonal` matrix ([#30298](https://github.com/JuliaLang/julia/issues/30298)). #### SparseArrays * performance improvements for sparse matrix-matrix multiplication ([#30372](https://github.com/JuliaLang/julia/issues/30372)). +* Sparse vector outer products are more performant and maintain sparsity in products of the + form `kron(u, v')`, `u * v'`, and `u .* v'` where `u` and `v` are sparse vectors or column + views. ([#24980](https://github.com/JuliaLang/julia/issues/24980)) #### Dates @@ -53,6 +57,7 @@ External dependencies * libgit2 has been updated to v0.27.7 ([#30584](https://github.com/JuliaLang/julia/issues/30584)). * OpenBLAS has been updated to v0.3.5 ([#30583](https://github.com/JuliaLang/julia/issues/30583)). * MbedTLS has been updated to v2.16.0 ([#30618](https://github.com/JuliaLang/julia/issues/30618)). +* libunwind has been updated to v1.3.1 ([#30724](https://github.com/JuliaLang/julia/issues/30724)). Deprecated or removed --------------------- diff --git a/codex/devdocs/ast.md b/codex/devdocs/ast.md index a30bdd1..f81ccad 100644 --- a/codex/devdocs/ast.md +++ b/codex/devdocs/ast.md @@ -8,11 +8,237 @@ generation. In the lowered form there are fewer types of nodes, all macros are e control flow is converted to explicit branches and sequences of statements. The lowered form is constructed by `julia-syntax.scm`. -First we will focus on the lowered form, since it is more important to the compiler. It is also -less obvious to the human, since it results from a significant rearrangement of the input syntax. +First we will focus on the AST, since it is needed to write macros. + +## Surface syntax AST + +Front end ASTs consist almost entirely of `Expr`s and atoms (e.g. symbols, numbers). +There is generally a different expression head for each visually distinct syntactic form. +Examples will be given in s-expression syntax. +Each parenthesized list corresponds to an Expr, where the first element is the head. +For example `(call f x)` corresponds to `Expr(:call, :f, :x)` in Julia. + +### Calls + +| Input | AST | +|:---------------- |:---------------------------------- | +| `f(x)` | `(call f x)` | +| `f(x, y=1, z=2)` | `(call f x (kw y 1) (kw z 2))` | +| `f(x; y=1)` | `(call f (parameters (kw y 1)) x)` | +| `f(x...)` | `(call f (... x))` | + +`do` syntax: + +```julia +f(x) do a,b + body +end +``` + +parses as `(do (call f x) (-> (tuple a b) (block body)))`. + +### Operators + +Most uses of operators are just function calls, so they are parsed with the head `call`. However +some operators are special forms (not necessarily function calls), and in those cases the operator +itself is the expression head. In julia-parser.scm these are referred to as "syntactic operators". +Some operators (`+` and `*`) use N-ary parsing; chained calls are parsed as a single N-argument +call. Finally, chains of comparisons have their own special expression structure. + +| Input | AST | +|:----------- |:------------------------- | +| `x+y` | `(call + x y)` | +| `a+b+c+d` | `(call + a b c d)` | +| `2x` | `(call * 2 x)` | +| `a&&b` | `(&& a b)` | +| `x += 1` | `(+= x 1)` | +| `a ? 1 : 2` | `(if a 1 2)` | +| `a:b` | `(: a b)` | +| `a:b:c` | `(: a b c)` | +| `a,b` | `(tuple a b)` | +| `a==b` | `(call == a b)` | +| `1 (tuple a b) (block body)))`. - -### Operators - -Most uses of operators are just function calls, so they are parsed with the head `call`. However -some operators are special forms (not necessarily function calls), and in those cases the operator -itself is the expression head. In julia-parser.scm these are referred to as "syntactic operators". -Some operators (`+` and `*`) use N-ary parsing; chained calls are parsed as a single N-argument -call. Finally, chains of comparisons have their own special expression structure. - -| Input | AST | -|:----------- |:------------------------- | -| `x+y` | `(call + x y)` | -| `a+b+c+d` | `(call + a b c d)` | -| `2x` | `(call * 2 x)` | -| `a&&b` | `(&& a b)` | -| `x += 1` | `(+= x 1)` | -| `a ? 1 : 2` | `(if a 1 2)` | -| `a:b` | `(: a b)` | -| `a:b:c` | `(: a b c)` | -| `a,b` | `(tuple a b)` | -| `a==b` | `(call == a b)` | -| `1 for p in workers() # start tasks on the workers to process requests in pa julia> @elapsed while n > 0 # print out results job_id, exec_time, where = take!(results) println("$job_id finished in $(round(exec_time; digits=2)) seconds on worker $where") - n = n - 1 + global n = n - 1 end 1 finished in 0.18 seconds on worker 4 2 finished in 0.26 seconds on worker 5 diff --git a/codex/manual/types.md b/codex/manual/types.md index c219f37..5e2b209 100644 --- a/codex/manual/types.md +++ b/codex/manual/types.md @@ -938,7 +938,7 @@ julia> NamedTuple{(:a, :b)}((1,"")) If field types are specified, the arguments are converted. Otherwise the types of the arguments are used directly. -#### [Singleton Types](@id man-singleton-types) +### [Singleton Types](@id man-singleton-types) There is a special kind of abstract parametric type that must be mentioned here: singleton types. For each type, `T`, the "singleton type" `Type{T}` is an abstract type whose only instance is diff --git a/src/NEWS.md b/src/NEWS.md index 51ff283..af70bb6 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -33,10 +33,14 @@ Standard library changes #### LinearAlgebra * Added keyword arguments `rtol`, `atol` to `pinv` and `nullspace` ([#29998](https://github.com/JuliaLang/julia/issues/29998)). +* `UniformScaling` instances are now callable such that e.g. `I(3)` will produce a `Diagonal` matrix ([#30298](https://github.com/JuliaLang/julia/issues/30298)). #### SparseArrays * performance improvements for sparse matrix-matrix multiplication ([#30372](https://github.com/JuliaLang/julia/issues/30372)). +* Sparse vector outer products are more performant and maintain sparsity in products of the + form `kron(u, v')`, `u * v'`, and `u .* v'` where `u` and `v` are sparse vectors or column + views. ([#24980](https://github.com/JuliaLang/julia/issues/24980)) #### Dates @@ -53,6 +57,7 @@ External dependencies * libgit2 has been updated to v0.27.7 ([#30584](https://github.com/JuliaLang/julia/issues/30584)). * OpenBLAS has been updated to v0.3.5 ([#30583](https://github.com/JuliaLang/julia/issues/30583)). * MbedTLS has been updated to v2.16.0 ([#30618](https://github.com/JuliaLang/julia/issues/30618)). +* libunwind has been updated to v1.3.1 ([#30724](https://github.com/JuliaLang/julia/issues/30724)). Deprecated or removed --------------------- diff --git a/src/devdocs/ast.md b/src/devdocs/ast.md index a30bdd1..f81ccad 100644 --- a/src/devdocs/ast.md +++ b/src/devdocs/ast.md @@ -8,11 +8,237 @@ generation. In the lowered form there are fewer types of nodes, all macros are e control flow is converted to explicit branches and sequences of statements. The lowered form is constructed by `julia-syntax.scm`. -First we will focus on the lowered form, since it is more important to the compiler. It is also -less obvious to the human, since it results from a significant rearrangement of the input syntax. +First we will focus on the AST, since it is needed to write macros. + +## Surface syntax AST + +Front end ASTs consist almost entirely of `Expr`s and atoms (e.g. symbols, numbers). +There is generally a different expression head for each visually distinct syntactic form. +Examples will be given in s-expression syntax. +Each parenthesized list corresponds to an Expr, where the first element is the head. +For example `(call f x)` corresponds to `Expr(:call, :f, :x)` in Julia. + +### Calls + +| Input | AST | +|:---------------- |:---------------------------------- | +| `f(x)` | `(call f x)` | +| `f(x, y=1, z=2)` | `(call f x (kw y 1) (kw z 2))` | +| `f(x; y=1)` | `(call f (parameters (kw y 1)) x)` | +| `f(x...)` | `(call f (... x))` | + +`do` syntax: + +```julia +f(x) do a,b + body +end +``` + +parses as `(do (call f x) (-> (tuple a b) (block body)))`. + +### Operators + +Most uses of operators are just function calls, so they are parsed with the head `call`. However +some operators are special forms (not necessarily function calls), and in those cases the operator +itself is the expression head. In julia-parser.scm these are referred to as "syntactic operators". +Some operators (`+` and `*`) use N-ary parsing; chained calls are parsed as a single N-argument +call. Finally, chains of comparisons have their own special expression structure. + +| Input | AST | +|:----------- |:------------------------- | +| `x+y` | `(call + x y)` | +| `a+b+c+d` | `(call + a b c d)` | +| `2x` | `(call * 2 x)` | +| `a&&b` | `(&& a b)` | +| `x += 1` | `(+= x 1)` | +| `a ? 1 : 2` | `(if a 1 2)` | +| `a:b` | `(: a b)` | +| `a:b:c` | `(: a b c)` | +| `a,b` | `(tuple a b)` | +| `a==b` | `(call == a b)` | +| `1 (tuple a b) (block body)))`. - -### Operators - -Most uses of operators are just function calls, so they are parsed with the head `call`. However -some operators are special forms (not necessarily function calls), and in those cases the operator -itself is the expression head. In julia-parser.scm these are referred to as "syntactic operators". -Some operators (`+` and `*`) use N-ary parsing; chained calls are parsed as a single N-argument -call. Finally, chains of comparisons have their own special expression structure. - -| Input | AST | -|:----------- |:------------------------- | -| `x+y` | `(call + x y)` | -| `a+b+c+d` | `(call + a b c d)` | -| `2x` | `(call * 2 x)` | -| `a&&b` | `(&& a b)` | -| `x += 1` | `(+= x 1)` | -| `a ? 1 : 2` | `(if a 1 2)` | -| `a:b` | `(: a b)` | -| `a:b:c` | `(: a b c)` | -| `a,b` | `(tuple a b)` | -| `a==b` | `(call == a b)` | -| `1 for p in workers() # start tasks on the workers to process requests in pa julia> @elapsed while n > 0 # print out results job_id, exec_time, where = take!(results) println("$job_id finished in $(round(exec_time; digits=2)) seconds on worker $where") - n = n - 1 + global n = n - 1 end 1 finished in 0.18 seconds on worker 4 2 finished in 0.26 seconds on worker 5 diff --git a/src/manual/types.md b/src/manual/types.md index c219f37..5e2b209 100644 --- a/src/manual/types.md +++ b/src/manual/types.md @@ -938,7 +938,7 @@ julia> NamedTuple{(:a, :b)}((1,"")) If field types are specified, the arguments are converted. Otherwise the types of the arguments are used directly. -#### [Singleton Types](@id man-singleton-types) +### [Singleton Types](@id man-singleton-types) There is a special kind of abstract parametric type that must be mentioned here: singleton types. For each type, `T`, the "singleton type" `Type{T}` is an abstract type whose only instance is From 02fd046a05eee8ef35b20b065446bf4d2cfb7ef6 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Sat, 26 Jan 2019 10:32:56 +0900 Subject: [PATCH 093/153] update Julia 1.2.0-DEV.218 (2019-01-25) Commit b0427fc1b4 --- codex/NEWS.md | 1 + codex/base/base.md | 5 +++++ codex/base/io-network.md | 3 +++ codex/base/strings.md | 2 +- codex/devdocs/ast.md | 6 +++--- codex/devdocs/reflection.md | 2 +- codex/manual/documentation.md | 3 ++- codex/manual/metaprogramming.md | 12 ++++++------ codex/manual/networking-and-streams.md | 2 +- src/NEWS.md | 1 + src/base/base.md | 5 +++++ src/base/io-network.md | 3 +++ src/base/strings.md | 2 +- src/devdocs/ast.md | 6 +++--- src/devdocs/reflection.md | 2 +- src/manual/documentation.md | 3 ++- src/manual/metaprogramming.md | 12 ++++++------ src/manual/networking-and-streams.md | 2 +- 18 files changed, 46 insertions(+), 26 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index af70bb6..4d0a375 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -6,6 +6,7 @@ New language features * The `extrema` function now accepts a function argument in the same manner as `minimum` and `maximum` ([#30323](https://github.com/JuliaLang/julia/issues/30323)). +* `hasmethod` can now check for matching keyword argument names ([#30712](https://github.com/JuliaLang/julia/issues/30712)). Multi-threading changes ----------------------- diff --git a/codex/base/base.md b/codex/base/base.md index 2e057cb..205a670 100644 --- a/codex/base/base.md +++ b/codex/base/base.md @@ -84,6 +84,7 @@ primitive type where ... ; += ``` ## Base Modules @@ -203,7 +204,11 @@ Core.Nothing Base.isnothing Base.Some Base.something +Base.Enums.Enum Base.Enums.@enum +Core.Expr +Core.Symbol +Core.Symbol(x...) ``` ## Generic Functions diff --git a/codex/base/io-network.md b/codex/base/io-network.md index 377ee41..f3f29e6 100644 --- a/codex/base/io-network.md +++ b/codex/base/io-network.md @@ -7,6 +7,7 @@ Base.stdout Base.stderr Base.stdin Base.open +Base.IOStream Base.IOBuffer Base.take!(::Base.GenericIOBuffer) Base.fdio @@ -94,6 +95,8 @@ Base.Multimedia.displayable Base.show(::Any, ::Any, ::Any) Base.Multimedia.showable Base.repr(::MIME, ::Any) +Base.MIME +Base.@MIME_str ``` As mentioned above, one can also define new display backends. For example, a module that can display diff --git a/codex/base/strings.md b/codex/base/strings.md index 95e07e3..f7bfc66 100644 --- a/codex/base/strings.md +++ b/codex/base/strings.md @@ -24,6 +24,7 @@ Base.@r_str Base.SubstitutionString Base.@s_str Base.@raw_str +Base.@b_str Base.Docs.@html_str Base.Docs.@text_str Base.isvalid(::Any) @@ -75,7 +76,6 @@ Base.ispunct Base.isspace Base.isuppercase Base.isxdigit -Core.Symbol Base.escape_string Base.unescape_string ``` diff --git a/codex/devdocs/ast.md b/codex/devdocs/ast.md index f81ccad..b89b4db 100644 --- a/codex/devdocs/ast.md +++ b/codex/devdocs/ast.md @@ -12,7 +12,7 @@ First we will focus on the AST, since it is needed to write macros. ## Surface syntax AST -Front end ASTs consist almost entirely of `Expr`s and atoms (e.g. symbols, numbers). +Front end ASTs consist almost entirely of [`Expr`](@ref)s and atoms (e.g. symbols, numbers). There is generally a different expression head for each visually distinct syntactic form. Examples will be given in s-expression syntax. Each parenthesized list corresponds to an Expr, where the first element is the head. @@ -287,9 +287,9 @@ The following data types exist in lowered form: Marks a point where a variable (slot) is created. This has the effect of resetting a variable to undefined. -### Expr types +### `Expr` types -These symbols appear in the `head` field of `Expr`s in lowered form. +These symbols appear in the `head` field of [`Expr`](@ref)s in lowered form. * `call` diff --git a/codex/devdocs/reflection.md b/codex/devdocs/reflection.md index 3e41b14..350fda7 100644 --- a/codex/devdocs/reflection.md +++ b/codex/devdocs/reflection.md @@ -77,7 +77,7 @@ table may be searched for methods accepting a given type using [`methodswith`](@ ## Expansion and lowering As discussed in the [Metaprogramming](@ref) section, the [`macroexpand`](@ref) function gives -the unquoted and interpolated expression (`Expr`) form for a given macro. To use `macroexpand`, +the unquoted and interpolated expression ([`Expr`](@ref)) form for a given macro. To use `macroexpand`, `quote` the expression block itself (otherwise, the macro will be evaluated and the result will be passed instead!). For example: diff --git a/codex/manual/documentation.md b/codex/manual/documentation.md index 4f80dc4..8d12c62 100644 --- a/codex/manual/documentation.md +++ b/codex/manual/documentation.md @@ -549,7 +549,8 @@ Macro authors should take note that only macros that generate a single expressio support docstrings. If a macro returns a block containing multiple subexpressions then the subexpression that should be documented must be marked using the [`@__doc__`](@ref Core.@__doc__) macro. -The `@enum` macro makes use of `@__doc__` to allow for documenting `Enum`s. Examining its definition +The [`@enum`](@ref) macro makes use of `@__doc__` to allow for documenting [`Enum`](@ref)s. +Examining its definition should serve as an example of how to use `@__doc__` correctly. ```@docs diff --git a/codex/manual/metaprogramming.md b/codex/manual/metaprogramming.md index 917102c..f6911cf 100644 --- a/codex/manual/metaprogramming.md +++ b/codex/manual/metaprogramming.md @@ -23,7 +23,7 @@ julia> prog = "1 + 1" **What happens next?** The next step is to [parse](https://en.wikipedia.org/wiki/Parsing#Computer_languages) each string -into an object called an expression, represented by the Julia type `Expr`: +into an object called an expression, represented by the Julia type [`Expr`](@ref): ```jldoctest prog julia> ex1 = Meta.parse(prog) @@ -144,7 +144,7 @@ julia> :(::) ### Quoting The second syntactic purpose of the `:` character is to create expression objects without using -the explicit `Expr` constructor. This is referred to as *quoting*. The `:` character, followed +the explicit [`Expr`](@ref) constructor. This is referred to as *quoting*. The `:` character, followed by paired parentheses around a single statement of Julia code, produces an `Expr` object based on the enclosed code. Here is example of the short form used to quote an arithmetic expression: @@ -198,7 +198,7 @@ Expr ### Interpolation -Direct construction of `Expr` objects with value arguments is powerful, but `Expr` constructors +Direct construction of [`Expr`](@ref) objects with value arguments is powerful, but `Expr` constructors can be tedious compared to "normal" Julia syntax. As an alternative, Julia allows *interpolation* of literals or expressions into quoted expressions. Interpolation is indicated by a prefix `$`. @@ -310,7 +310,7 @@ equivalent of `eval(eval(:x))`. ### QuoteNode -The usual representation of a `quote` form in an AST is an `Expr` with head `:quote`: +The usual representation of a `quote` form in an AST is an [`Expr`](@ref) with head `:quote`: ```jldoctest interp1 julia> dump(Meta.parse(":(1+2)")) @@ -415,7 +415,7 @@ value 1 and the variable `b`. Note the important distinction between the way `a` ### Functions on `Expr`essions As hinted above, one extremely useful feature of Julia is the capability to generate and manipulate -Julia code within Julia itself. We have already seen one example of a function returning `Expr` +Julia code within Julia itself. We have already seen one example of a function returning [`Expr`](@ref) objects: the [`parse`](@ref) function, which takes a string of Julia code and returns the corresponding `Expr`. A function can also take one or more `Expr` objects as arguments, and return another `Expr`. Here is a simple, motivating example: @@ -837,7 +837,7 @@ This kind of manipulation of variables should be used judiciously, but is occasi Getting the hygiene rules correct can be a formidable challenge. Before using a macro, you might want to consider whether a function closure would be sufficient. Another useful strategy is to defer as much work as possible to runtime. -For example, many macros simply wrap their arguments in a QuoteNode or other similar Expr. +For example, many macros simply wrap their arguments in a `QuoteNode` or other similar [`Expr`](@ref). Some examples of this include `@task body` which simply returns `schedule(Task(() -> $body))`, and `@eval expr`, which simply returns `eval(QuoteNode(expr))`. diff --git a/codex/manual/networking-and-streams.md b/codex/manual/networking-and-streams.md index 272460a..e5bd1d0 100644 --- a/codex/manual/networking-and-streams.md +++ b/codex/manual/networking-and-streams.md @@ -121,7 +121,7 @@ of common properties. ## Working with Files Like many other environments, Julia has an [`open`](@ref) function, which takes a filename and -returns an `IOStream` object that you can use to read and write things from the file. For example, +returns an [`IOStream`](@ref) object that you can use to read and write things from the file. For example, if we have a file, `hello.txt`, whose contents are `Hello, World!`: ```julia-repl diff --git a/src/NEWS.md b/src/NEWS.md index af70bb6..4d0a375 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -6,6 +6,7 @@ New language features * The `extrema` function now accepts a function argument in the same manner as `minimum` and `maximum` ([#30323](https://github.com/JuliaLang/julia/issues/30323)). +* `hasmethod` can now check for matching keyword argument names ([#30712](https://github.com/JuliaLang/julia/issues/30712)). Multi-threading changes ----------------------- diff --git a/src/base/base.md b/src/base/base.md index 2e057cb..205a670 100644 --- a/src/base/base.md +++ b/src/base/base.md @@ -84,6 +84,7 @@ primitive type where ... ; += ``` ## Base Modules @@ -203,7 +204,11 @@ Core.Nothing Base.isnothing Base.Some Base.something +Base.Enums.Enum Base.Enums.@enum +Core.Expr +Core.Symbol +Core.Symbol(x...) ``` ## Generic Functions diff --git a/src/base/io-network.md b/src/base/io-network.md index 377ee41..f3f29e6 100644 --- a/src/base/io-network.md +++ b/src/base/io-network.md @@ -7,6 +7,7 @@ Base.stdout Base.stderr Base.stdin Base.open +Base.IOStream Base.IOBuffer Base.take!(::Base.GenericIOBuffer) Base.fdio @@ -94,6 +95,8 @@ Base.Multimedia.displayable Base.show(::Any, ::Any, ::Any) Base.Multimedia.showable Base.repr(::MIME, ::Any) +Base.MIME +Base.@MIME_str ``` As mentioned above, one can also define new display backends. For example, a module that can display diff --git a/src/base/strings.md b/src/base/strings.md index 95e07e3..f7bfc66 100644 --- a/src/base/strings.md +++ b/src/base/strings.md @@ -24,6 +24,7 @@ Base.@r_str Base.SubstitutionString Base.@s_str Base.@raw_str +Base.@b_str Base.Docs.@html_str Base.Docs.@text_str Base.isvalid(::Any) @@ -75,7 +76,6 @@ Base.ispunct Base.isspace Base.isuppercase Base.isxdigit -Core.Symbol Base.escape_string Base.unescape_string ``` diff --git a/src/devdocs/ast.md b/src/devdocs/ast.md index f81ccad..b89b4db 100644 --- a/src/devdocs/ast.md +++ b/src/devdocs/ast.md @@ -12,7 +12,7 @@ First we will focus on the AST, since it is needed to write macros. ## Surface syntax AST -Front end ASTs consist almost entirely of `Expr`s and atoms (e.g. symbols, numbers). +Front end ASTs consist almost entirely of [`Expr`](@ref)s and atoms (e.g. symbols, numbers). There is generally a different expression head for each visually distinct syntactic form. Examples will be given in s-expression syntax. Each parenthesized list corresponds to an Expr, where the first element is the head. @@ -287,9 +287,9 @@ The following data types exist in lowered form: Marks a point where a variable (slot) is created. This has the effect of resetting a variable to undefined. -### Expr types +### `Expr` types -These symbols appear in the `head` field of `Expr`s in lowered form. +These symbols appear in the `head` field of [`Expr`](@ref)s in lowered form. * `call` diff --git a/src/devdocs/reflection.md b/src/devdocs/reflection.md index 3e41b14..350fda7 100644 --- a/src/devdocs/reflection.md +++ b/src/devdocs/reflection.md @@ -77,7 +77,7 @@ table may be searched for methods accepting a given type using [`methodswith`](@ ## Expansion and lowering As discussed in the [Metaprogramming](@ref) section, the [`macroexpand`](@ref) function gives -the unquoted and interpolated expression (`Expr`) form for a given macro. To use `macroexpand`, +the unquoted and interpolated expression ([`Expr`](@ref)) form for a given macro. To use `macroexpand`, `quote` the expression block itself (otherwise, the macro will be evaluated and the result will be passed instead!). For example: diff --git a/src/manual/documentation.md b/src/manual/documentation.md index 4f80dc4..8d12c62 100644 --- a/src/manual/documentation.md +++ b/src/manual/documentation.md @@ -549,7 +549,8 @@ Macro authors should take note that only macros that generate a single expressio support docstrings. If a macro returns a block containing multiple subexpressions then the subexpression that should be documented must be marked using the [`@__doc__`](@ref Core.@__doc__) macro. -The `@enum` macro makes use of `@__doc__` to allow for documenting `Enum`s. Examining its definition +The [`@enum`](@ref) macro makes use of `@__doc__` to allow for documenting [`Enum`](@ref)s. +Examining its definition should serve as an example of how to use `@__doc__` correctly. ```@docs diff --git a/src/manual/metaprogramming.md b/src/manual/metaprogramming.md index 917102c..f6911cf 100644 --- a/src/manual/metaprogramming.md +++ b/src/manual/metaprogramming.md @@ -23,7 +23,7 @@ julia> prog = "1 + 1" **What happens next?** The next step is to [parse](https://en.wikipedia.org/wiki/Parsing#Computer_languages) each string -into an object called an expression, represented by the Julia type `Expr`: +into an object called an expression, represented by the Julia type [`Expr`](@ref): ```jldoctest prog julia> ex1 = Meta.parse(prog) @@ -144,7 +144,7 @@ julia> :(::) ### Quoting The second syntactic purpose of the `:` character is to create expression objects without using -the explicit `Expr` constructor. This is referred to as *quoting*. The `:` character, followed +the explicit [`Expr`](@ref) constructor. This is referred to as *quoting*. The `:` character, followed by paired parentheses around a single statement of Julia code, produces an `Expr` object based on the enclosed code. Here is example of the short form used to quote an arithmetic expression: @@ -198,7 +198,7 @@ Expr ### Interpolation -Direct construction of `Expr` objects with value arguments is powerful, but `Expr` constructors +Direct construction of [`Expr`](@ref) objects with value arguments is powerful, but `Expr` constructors can be tedious compared to "normal" Julia syntax. As an alternative, Julia allows *interpolation* of literals or expressions into quoted expressions. Interpolation is indicated by a prefix `$`. @@ -310,7 +310,7 @@ equivalent of `eval(eval(:x))`. ### QuoteNode -The usual representation of a `quote` form in an AST is an `Expr` with head `:quote`: +The usual representation of a `quote` form in an AST is an [`Expr`](@ref) with head `:quote`: ```jldoctest interp1 julia> dump(Meta.parse(":(1+2)")) @@ -415,7 +415,7 @@ value 1 and the variable `b`. Note the important distinction between the way `a` ### Functions on `Expr`essions As hinted above, one extremely useful feature of Julia is the capability to generate and manipulate -Julia code within Julia itself. We have already seen one example of a function returning `Expr` +Julia code within Julia itself. We have already seen one example of a function returning [`Expr`](@ref) objects: the [`parse`](@ref) function, which takes a string of Julia code and returns the corresponding `Expr`. A function can also take one or more `Expr` objects as arguments, and return another `Expr`. Here is a simple, motivating example: @@ -837,7 +837,7 @@ This kind of manipulation of variables should be used judiciously, but is occasi Getting the hygiene rules correct can be a formidable challenge. Before using a macro, you might want to consider whether a function closure would be sufficient. Another useful strategy is to defer as much work as possible to runtime. -For example, many macros simply wrap their arguments in a QuoteNode or other similar Expr. +For example, many macros simply wrap their arguments in a `QuoteNode` or other similar [`Expr`](@ref). Some examples of this include `@task body` which simply returns `schedule(Task(() -> $body))`, and `@eval expr`, which simply returns `eval(QuoteNode(expr))`. diff --git a/src/manual/networking-and-streams.md b/src/manual/networking-and-streams.md index 272460a..e5bd1d0 100644 --- a/src/manual/networking-and-streams.md +++ b/src/manual/networking-and-streams.md @@ -121,7 +121,7 @@ of common properties. ## Working with Files Like many other environments, Julia has an [`open`](@ref) function, which takes a filename and -returns an `IOStream` object that you can use to read and write things from the file. For example, +returns an [`IOStream`](@ref) object that you can use to read and write things from the file. For example, if we have a file, `hello.txt`, whose contents are `Hello, World!`: ```julia-repl From f342ab68c0483682b5a77eae1793d42c97e54b1c Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Sat, 2 Feb 2019 12:26:35 +0900 Subject: [PATCH 094/153] update Julia 1.2.0-DEV.248 (2019-02-01) Commit c7338ea61a --- codex/devdocs/subarrays.md | 31 +--------- codex/manual/arrays.md | 124 +++++++++++++++++++++++++++++++++---- codex/manual/strings.md | 7 ++- codex/stdlib/Dates.md | 6 +- src/devdocs/subarrays.md | 31 +--------- src/manual/arrays.md | 123 +++++++++++++++++++++++++++++++++--- src/manual/strings.md | 7 ++- src/stdlib/Dates.md | 6 +- 8 files changed, 248 insertions(+), 87 deletions(-) diff --git a/codex/devdocs/subarrays.md b/codex/devdocs/subarrays.md index 6b91083..c86fdb0 100644 --- a/codex/devdocs/subarrays.md +++ b/codex/devdocs/subarrays.md @@ -3,34 +3,9 @@ Julia's `SubArray` type is a container encoding a "view" of a parent [`AbstractArray`](@ref). This page documents some of the design principles and implementation of `SubArray`s. -## Indexing: cartesian vs. linear indexing - -Broadly speaking, there are two main ways to access data in an array. The first, often called -cartesian indexing, uses `N` indices for an `N` -dimensional `AbstractArray`. For example, a -matrix `A` (2-dimensional) can be indexed in cartesian style as `A[i,j]`. The second indexing -method, referred to as linear indexing, uses a single index even for higher-dimensional objects. - For example, if `A = reshape(1:12, 3, 4)`, then the expression `A[5]` returns the value 5. Julia -allows you to combine these styles of indexing: for example, a 3d array `A3` can be indexed as -`A3[i,j]`, in which case `i` is interpreted as a cartesian index for the first dimension, and -`j` is a linear index over dimensions 2 and 3. - -For `Array`s, linear indexing appeals to the underlying storage format: an array is laid out as -a contiguous block of memory, and hence the linear index is just the offset (+1) of the corresponding -entry relative to the beginning of the array. However, this is not true for many other `AbstractArray` -types: examples include [`SparseMatrixCSC`](@ref) from the `SparseArrays` standard library -module, arrays that require some kind of -computation (such as interpolation), and the type under discussion here, `SubArray`. -For these types, the underlying information is more naturally described in terms of -cartesian indices. - -The `getindex` and `setindex!` functions for `AbstractArray` types may include automatic conversion -between indexing types. For explicit conversion, [`CartesianIndices`](@ref) can be used. - -While converting from a cartesian index to a linear index is fast (it's just multiplication and -addition), converting from a linear index to a cartesian index is very slow: it relies on the -`div` operation, which is one of the slowest low-level operations you can perform with a CPU. - For this reason, any code that deals with `AbstractArray` types is best designed in terms of -cartesian, rather than linear, indexing. +One of the major design goals is to ensure high performance for views of both [`IndexLinear`](@ref) and +[`IndexCartesian`](@ref) arrays. Furthermore, views of `IndexLinear` arrays should themselves be +`IndexLinear` to the extent that it is possible. ## Index replacement diff --git a/codex/manual/arrays.md b/codex/manual/arrays.md index c1c4682..4e8b4d4 100644 --- a/codex/manual/arrays.md +++ b/codex/manual/arrays.md @@ -397,17 +397,6 @@ julia> x[1, [2 3; 4 1]] 13 1 ``` -Empty ranges of the form `n:n-1` are sometimes used to indicate the inter-index location between -`n-1` and `n`. For example, the [`searchsorted`](@ref) function uses this convention to indicate -the insertion point of a value not found in a sorted array: - -```jldoctest -julia> a = [1,2,5,6,7]; - -julia> searchsorted(a, 4) -3:2 -``` - ## Assignment The general syntax for assigning values in an n-dimensional array `A` is: @@ -648,6 +637,119 @@ julia> x[mask] 16 ``` +### Number of indices + +#### Cartesian indexing + +The ordinary way to index into an `N`-dimensional array is to use exactly `N` indices; each +index selects the position(s) in its particular dimension. For example, in the three-dimensional +array `A = rand(4, 3, 2)`, `A[2, 3, 1]` will select the number in the second row of the third +column in the first "page" of the array. This is often referred to as _cartesian indexing_. + +#### Linear indexing + +When exactly one index `i` is provided, that index no longer represents a location in a +particular dimension of the array. Instead, it selects the `i`th element using the +column-major iteration order that linearly spans the entire array. This is known as _linear +indexing_. It essentially treats the array as though it had been reshaped into a +one-dimensional vector with [`vec`](@ref). + +```jldoctest linindexing +julia> A = [2 6; 4 7; 3 1] +3×2 Array{Int64,2}: + 2 6 + 4 7 + 3 1 + +julia> A[5] +7 + +julia> vec(A)[5] +7 +``` + +A linear index into the array `A` can be converted to a `CartesianIndex` for cartesian +indexing with `CartesianIndices(A)[i]` (see [`CartesianIndices`](@ref)), and a set of +`N` cartesian indices can be converted to a linear index with +`LinearIndices(A)[i_1, i_2, ..., i_N]` (see [`LinearIndices`](@ref)). + +```jldoctest linindexing +julia> CartesianIndices(A)[5] +CartesianIndex(2, 2) + +julia> LinearIndices(A)[2, 2] +5 +``` + +It's important to note that there's a very large assymmetry in the performance +of these conversions. Converting a linear index to a set of cartesian indices +requires dividing and taking the remainder, whereas going the other way is just +multiplies and adds. In modern processors, integer division can be 10-50 times +slower than multiplication. While some arrays — like [`Array`](@ref) itself — +are implemented using a linear chunk of memory and directly use a linear index +in their implementations, other arrays — like [`Diagonal`](@ref) — need the +full set of cartesian indices to do their lookup (see [`IndexStyle`](@ref) to +introspect which is which). As such, when iterating over an entire array, it's +much better to iterate over [`eachindex(A)`](@ref) instead of `1:length(A)`. +Not only will the former be much faster in cases where `A` is `IndexCartesian`, +but it will also support OffsetArrays, too. + +#### Omitted and extra indices + +In addition to linear indexing, an `N`-dimensional array may be indexed with +fewer or more than `N` indices in certain situations. + +Indices may be omitted if the trailing dimensions that are not indexed into are +all length one. In other words, trailing indices can be omitted only if there +is only one possible value that those omitted indices could be for an in-bounds +indexing expression. For example, a four-dimensional array with size `(3, 4, 2, +1)` may be indexed with only three indices as the dimension that gets skipped +(the fourth dimension) has length one. Note that linear indexing takes +precedence over this rule. + +```jldoctest +julia> A = reshape(1:24, 3, 4, 2, 1) +3×4×2×1 reshape(::UnitRange{Int64}, 3, 4, 2, 1) with eltype Int64: +[:, :, 1, 1] = + 1 4 7 10 + 2 5 8 11 + 3 6 9 12 + +[:, :, 2, 1] = + 13 16 19 22 + 14 17 20 23 + 15 18 21 24 + +julia> A[1, 3, 2] # Omits the fourth dimension (length 1) +19 + +julia> A[1, 3] # Attempts to omit dimensions 3 & 4 (lengths 2 and 1) +ERROR: BoundsError: attempt to access 3×4×2×1 reshape(::UnitRange{Int64}, 3, 4, 2, 1) with eltype Int64 at index [1, 3] + +julia> A[19] # Linear indexing +19 +``` + +When omitting _all_ indices with `A[]`, this semantic provides a simple idiom +to retrieve the only element in an array and simultaneously ensure that there +was only one element. + +Similarly, more than `N` indices may be provided if all the indices beyond the +dimensionality of the array are `1` (or more generally are the first and only +element of `axes(A, d)` where `d` is that particular dimension number). This +allows vectors to be indexed like one-column matrices, for example: + +```jldoctest +julia> A = [8,6,7] +3-element Array{Int64,1}: + 8 + 6 + 7 + +julia> A[2,1] +6 +``` + ## Iteration The recommended ways to iterate over a whole array are diff --git a/codex/manual/strings.md b/codex/manual/strings.md index 60eea9c..c9b27dc 100644 --- a/codex/manual/strings.md +++ b/codex/manual/strings.md @@ -507,7 +507,7 @@ julia> "$greet, $whom.\n" ``` This is more readable and convenient and equivalent to the above string concatenation -- the system -rewrites this apparent single string literal into a concatenation of string literals with variables. +rewrites this apparent single string literal into the call `string(greet, ", ", whom, ".\n")`. The shortest complete expression after the `$` is taken as the expression whose value is to be interpolated into the string. Thus, you can interpolate any expression into a string using parentheses: @@ -518,7 +518,10 @@ julia> "1 + 2 = $(1 + 2)" ``` Both concatenation and string interpolation call [`string`](@ref) to convert objects into string -form. Most non-`AbstractString` objects are converted to strings closely corresponding to how +form. However, `string` actually just returns the output of [`print`](@ref), so new types +should add methods to [`print`](@ref) or [`show`](@ref) instead of `string`. + +Most non-`AbstractString` objects are converted to strings closely corresponding to how they are entered as literal expressions: ```jldoctest diff --git a/codex/stdlib/Dates.md b/codex/stdlib/Dates.md index 5218861..c852943 100644 --- a/codex/stdlib/Dates.md +++ b/codex/stdlib/Dates.md @@ -244,7 +244,7 @@ Date value: Int64 735264 julia> t.instant -Dates.UTInstant{Day}(735264 days) +Dates.UTInstant{Day}(Day(735264)) julia> Dates.value(t) 735264 @@ -400,7 +400,7 @@ As a bonus, all period arithmetic objects work directly with ranges: ```jldoctest julia> dr = Date(2014,1,29):Day(1):Date(2014,2,3) -Date(2014, 1, 29):1 day:Date(2014, 2, 3) +Date(2014, 1, 29):Day(1):Date(2014, 2, 3) julia> collect(dr) 6-element Array{Date,1}: @@ -412,7 +412,7 @@ julia> collect(dr) Date(2014, 2, 3) julia> dr = Date(2014,1,29):Dates.Month(1):Date(2014,07,29) -Date(2014, 1, 29):1 month:Date(2014, 7, 29) +Date(2014, 1, 29):Month(1):Date(2014, 7, 29) julia> collect(dr) 7-element Array{Date,1}: diff --git a/src/devdocs/subarrays.md b/src/devdocs/subarrays.md index 6b91083..c86fdb0 100644 --- a/src/devdocs/subarrays.md +++ b/src/devdocs/subarrays.md @@ -3,34 +3,9 @@ Julia's `SubArray` type is a container encoding a "view" of a parent [`AbstractArray`](@ref). This page documents some of the design principles and implementation of `SubArray`s. -## Indexing: cartesian vs. linear indexing - -Broadly speaking, there are two main ways to access data in an array. The first, often called -cartesian indexing, uses `N` indices for an `N` -dimensional `AbstractArray`. For example, a -matrix `A` (2-dimensional) can be indexed in cartesian style as `A[i,j]`. The second indexing -method, referred to as linear indexing, uses a single index even for higher-dimensional objects. - For example, if `A = reshape(1:12, 3, 4)`, then the expression `A[5]` returns the value 5. Julia -allows you to combine these styles of indexing: for example, a 3d array `A3` can be indexed as -`A3[i,j]`, in which case `i` is interpreted as a cartesian index for the first dimension, and -`j` is a linear index over dimensions 2 and 3. - -For `Array`s, linear indexing appeals to the underlying storage format: an array is laid out as -a contiguous block of memory, and hence the linear index is just the offset (+1) of the corresponding -entry relative to the beginning of the array. However, this is not true for many other `AbstractArray` -types: examples include [`SparseMatrixCSC`](@ref) from the `SparseArrays` standard library -module, arrays that require some kind of -computation (such as interpolation), and the type under discussion here, `SubArray`. -For these types, the underlying information is more naturally described in terms of -cartesian indices. - -The `getindex` and `setindex!` functions for `AbstractArray` types may include automatic conversion -between indexing types. For explicit conversion, [`CartesianIndices`](@ref) can be used. - -While converting from a cartesian index to a linear index is fast (it's just multiplication and -addition), converting from a linear index to a cartesian index is very slow: it relies on the -`div` operation, which is one of the slowest low-level operations you can perform with a CPU. - For this reason, any code that deals with `AbstractArray` types is best designed in terms of -cartesian, rather than linear, indexing. +One of the major design goals is to ensure high performance for views of both [`IndexLinear`](@ref) and +[`IndexCartesian`](@ref) arrays. Furthermore, views of `IndexLinear` arrays should themselves be +`IndexLinear` to the extent that it is possible. ## Index replacement diff --git a/src/manual/arrays.md b/src/manual/arrays.md index b677b44..e8803b3 100644 --- a/src/manual/arrays.md +++ b/src/manual/arrays.md @@ -377,16 +377,6 @@ julia> x[1, [2 3; 4 1]] 13 1 ``` -`n:n-1`과 같은 식의 빈 범위는 인덱스 `n-1`과 `n`사이의 위치를 나타내기 위해 가끔 사용된다. -예를 들어, [`searchsorted`](@ref) 함수는 이 방법을 사용하여 정렬된 배열에 없는 값의 삽입 위치를 나타낸다. - -```jldoctest -julia> a = [1,2,5,6,7]; - -julia> searchsorted(a, 4) -3:2 -``` - ## 대입 n차원 배열 `A`에 값을 대입하는 일반적인 문법은 다음과 같다: @@ -606,6 +596,119 @@ julia> x[mask] 16 ``` +### Number of indices + +#### Cartesian indexing + +The ordinary way to index into an `N`-dimensional array is to use exactly `N` indices; each +index selects the position(s) in its particular dimension. For example, in the three-dimensional +array `A = rand(4, 3, 2)`, `A[2, 3, 1]` will select the number in the second row of the third +column in the first "page" of the array. This is often referred to as _cartesian indexing_. + +#### Linear indexing + +When exactly one index `i` is provided, that index no longer represents a location in a +particular dimension of the array. Instead, it selects the `i`th element using the +column-major iteration order that linearly spans the entire array. This is known as _linear +indexing_. It essentially treats the array as though it had been reshaped into a +one-dimensional vector with [`vec`](@ref). + +```jldoctest linindexing +julia> A = [2 6; 4 7; 3 1] +3×2 Array{Int64,2}: + 2 6 + 4 7 + 3 1 + +julia> A[5] +7 + +julia> vec(A)[5] +7 +``` + +A linear index into the array `A` can be converted to a `CartesianIndex` for cartesian +indexing with `CartesianIndices(A)[i]` (see [`CartesianIndices`](@ref)), and a set of +`N` cartesian indices can be converted to a linear index with +`LinearIndices(A)[i_1, i_2, ..., i_N]` (see [`LinearIndices`](@ref)). + +```jldoctest linindexing +julia> CartesianIndices(A)[5] +CartesianIndex(2, 2) + +julia> LinearIndices(A)[2, 2] +5 +``` + +It's important to note that there's a very large assymmetry in the performance +of these conversions. Converting a linear index to a set of cartesian indices +requires dividing and taking the remainder, whereas going the other way is just +multiplies and adds. In modern processors, integer division can be 10-50 times +slower than multiplication. While some arrays — like [`Array`](@ref) itself — +are implemented using a linear chunk of memory and directly use a linear index +in their implementations, other arrays — like [`Diagonal`](@ref) — need the +full set of cartesian indices to do their lookup (see [`IndexStyle`](@ref) to +introspect which is which). As such, when iterating over an entire array, it's +much better to iterate over [`eachindex(A)`](@ref) instead of `1:length(A)`. +Not only will the former be much faster in cases where `A` is `IndexCartesian`, +but it will also support OffsetArrays, too. + +#### Omitted and extra indices + +In addition to linear indexing, an `N`-dimensional array may be indexed with +fewer or more than `N` indices in certain situations. + +Indices may be omitted if the trailing dimensions that are not indexed into are +all length one. In other words, trailing indices can be omitted only if there +is only one possible value that those omitted indices could be for an in-bounds +indexing expression. For example, a four-dimensional array with size `(3, 4, 2, +1)` may be indexed with only three indices as the dimension that gets skipped +(the fourth dimension) has length one. Note that linear indexing takes +precedence over this rule. + +```jldoctest +julia> A = reshape(1:24, 3, 4, 2, 1) +3×4×2×1 reshape(::UnitRange{Int64}, 3, 4, 2, 1) with eltype Int64: +[:, :, 1, 1] = + 1 4 7 10 + 2 5 8 11 + 3 6 9 12 + +[:, :, 2, 1] = + 13 16 19 22 + 14 17 20 23 + 15 18 21 24 + +julia> A[1, 3, 2] # Omits the fourth dimension (length 1) +19 + +julia> A[1, 3] # Attempts to omit dimensions 3 & 4 (lengths 2 and 1) +ERROR: BoundsError: attempt to access 3×4×2×1 reshape(::UnitRange{Int64}, 3, 4, 2, 1) with eltype Int64 at index [1, 3] + +julia> A[19] # Linear indexing +19 +``` + +When omitting _all_ indices with `A[]`, this semantic provides a simple idiom +to retrieve the only element in an array and simultaneously ensure that there +was only one element. + +Similarly, more than `N` indices may be provided if all the indices beyond the +dimensionality of the array are `1` (or more generally are the first and only +element of `axes(A, d)` where `d` is that particular dimension number). This +allows vectors to be indexed like one-column matrices, for example: + +```jldoctest +julia> A = [8,6,7] +3-element Array{Int64,1}: + 8 + 6 + 7 + +julia> A[2,1] +6 +``` + ## [반복(Iteration)](@id Iteration) 배열 전체를 반복하는 방법으로는 다음을 추천한다: diff --git a/src/manual/strings.md b/src/manual/strings.md index 60eea9c..c9b27dc 100644 --- a/src/manual/strings.md +++ b/src/manual/strings.md @@ -507,7 +507,7 @@ julia> "$greet, $whom.\n" ``` This is more readable and convenient and equivalent to the above string concatenation -- the system -rewrites this apparent single string literal into a concatenation of string literals with variables. +rewrites this apparent single string literal into the call `string(greet, ", ", whom, ".\n")`. The shortest complete expression after the `$` is taken as the expression whose value is to be interpolated into the string. Thus, you can interpolate any expression into a string using parentheses: @@ -518,7 +518,10 @@ julia> "1 + 2 = $(1 + 2)" ``` Both concatenation and string interpolation call [`string`](@ref) to convert objects into string -form. Most non-`AbstractString` objects are converted to strings closely corresponding to how +form. However, `string` actually just returns the output of [`print`](@ref), so new types +should add methods to [`print`](@ref) or [`show`](@ref) instead of `string`. + +Most non-`AbstractString` objects are converted to strings closely corresponding to how they are entered as literal expressions: ```jldoctest diff --git a/src/stdlib/Dates.md b/src/stdlib/Dates.md index 5218861..c852943 100644 --- a/src/stdlib/Dates.md +++ b/src/stdlib/Dates.md @@ -244,7 +244,7 @@ Date value: Int64 735264 julia> t.instant -Dates.UTInstant{Day}(735264 days) +Dates.UTInstant{Day}(Day(735264)) julia> Dates.value(t) 735264 @@ -400,7 +400,7 @@ As a bonus, all period arithmetic objects work directly with ranges: ```jldoctest julia> dr = Date(2014,1,29):Day(1):Date(2014,2,3) -Date(2014, 1, 29):1 day:Date(2014, 2, 3) +Date(2014, 1, 29):Day(1):Date(2014, 2, 3) julia> collect(dr) 6-element Array{Date,1}: @@ -412,7 +412,7 @@ julia> collect(dr) Date(2014, 2, 3) julia> dr = Date(2014,1,29):Dates.Month(1):Date(2014,07,29) -Date(2014, 1, 29):1 month:Date(2014, 7, 29) +Date(2014, 1, 29):Month(1):Date(2014, 7, 29) julia> collect(dr) 7-element Array{Date,1}: From c3daa1d516a0914b767db0355330ca7adc7b6f35 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Wed, 6 Feb 2019 09:31:22 +0900 Subject: [PATCH 095/153] update Julia 1.2.0-DEV.278 (2019-02-05) Commit c3961796d0 --- codex/NEWS.md | 3 +++ codex/devdocs/inference.md | 2 +- codex/devdocs/reflection.md | 23 +++++++++++++++++++++-- codex/manual/performance-tips.md | 6 +++--- codex/stdlib/Distributed.md | 3 ++- codex/stdlib/LinearAlgebra.md | 6 +++--- src/NEWS.md | 3 +++ src/devdocs/inference.md | 2 +- src/devdocs/reflection.md | 23 +++++++++++++++++++++-- src/manual/performance-tips.md | 6 +++--- src/stdlib/Distributed.md | 3 ++- src/stdlib/LinearAlgebra.md | 6 +++--- 12 files changed, 66 insertions(+), 20 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index 4d0a375..f3b3369 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -31,10 +31,13 @@ New library functions Standard library changes ------------------------ +* Added `Base.hasproperty` and `Base.hasfield` ([#28850](https://github.com/JuliaLang/julia/issues/28850)). + #### LinearAlgebra * Added keyword arguments `rtol`, `atol` to `pinv` and `nullspace` ([#29998](https://github.com/JuliaLang/julia/issues/29998)). * `UniformScaling` instances are now callable such that e.g. `I(3)` will produce a `Diagonal` matrix ([#30298](https://github.com/JuliaLang/julia/issues/30298)). +* Eigenvalues λ of general matrices are now sorted lexicographically by (Re λ, Im λ) ([#21598](https://github.com/JuliaLang/julia/issues/21598)). #### SparseArrays diff --git a/codex/devdocs/inference.md b/codex/devdocs/inference.md index 97f2122..0603c1d 100644 --- a/codex/devdocs/inference.md +++ b/codex/devdocs/inference.md @@ -103,7 +103,7 @@ mi = Base.method_instances(f, tt)[1] ci = code_typed(f, tt)[1][1] opt = Core.Compiler.OptimizationState(mi, params) # Calculate cost of each statement -cost(stmt::Expr) = Core.Compiler.statement_cost(stmt, -1, ci, opt.sp, opt.slottypes, opt.params) +cost(stmt::Expr) = Core.Compiler.statement_cost(stmt, -1, ci, opt.sptypes, opt.slottypes, opt.params) cost(stmt) = 0 cst = map(cost, ci.code) diff --git a/codex/devdocs/reflection.md b/codex/devdocs/reflection.md index 350fda7..15d6e41 100644 --- a/codex/devdocs/reflection.md +++ b/codex/devdocs/reflection.md @@ -96,6 +96,7 @@ as assignments, branches, and calls: ```jldoctest julia> Meta.lower(@__MODULE__, :( [1+2, sin(0.5)] )) :($(Expr(:thunk, CodeInfo( + @ none within `top-level scope' 1 ─ %1 = 1 + 2 │ %2 = sin(0.5) │ %3 = (Base.vect)(%1, %2) @@ -122,7 +123,6 @@ calls and expand argument types automatically: ```julia-repl julia> @code_llvm +(1,1) -; @ int.jl:53 within `+' define i64 @"julia_+_130862"(i64, i64) { top: %2 = add i64 %1, %0 @@ -130,5 +130,24 @@ top: } ``` -See [`@code_lowered`](@ref), [`@code_typed`](@ref), [`@code_warntype`](@ref), +For more informations see [`@code_lowered`](@ref), [`@code_typed`](@ref), [`@code_warntype`](@ref), [`@code_llvm`](@ref), and [`@code_native`](@ref). + +### Printing of debug information + +The aforementioned functions and macros take the keyword argument `debuginfo` that controls the level +debug information printed. + +``` +julia> @code_typed debuginfo=:source +(1,1) +CodeInfo( + @ int.jl:53 within `+' +1 ─ %1 = (Base.add_int)(x, y)::Int64 +└── return %1 +) => Int64 +``` + +Possible values for `debuginfo` are: `:none`, `:source`, and`:default`. +Per default debug information is not printed, but that can be changed +by setting `Base.IRShow.default_debuginfo[] = :source`. + diff --git a/codex/manual/performance-tips.md b/codex/manual/performance-tips.md index 2dbd75a..62ad178 100644 --- a/codex/manual/performance-tips.md +++ b/codex/manual/performance-tips.md @@ -164,9 +164,9 @@ julia> a = Real[] julia> push!(a, 1); push!(a, 2.0); push!(a, π) 3-element Array{Real,1}: - 1 - 2.0 - π = 3.1415926535897... + 1 + 2.0 + π ``` Because `a` is a an array of abstract type [`Real`](@ref), it must be able to hold any diff --git a/codex/stdlib/Distributed.md b/codex/stdlib/Distributed.md index 4653a26..3ecbd51 100644 --- a/codex/stdlib/Distributed.md +++ b/codex/stdlib/Distributed.md @@ -18,7 +18,8 @@ Distributed.pmap Distributed.RemoteException Distributed.Future Distributed.RemoteChannel -Distributed.fetch(::Any) +Distributed.fetch(::Future) +Distributed.fetch(::RemoteChannel) Distributed.remotecall(::Any, ::Integer, ::Any...) Distributed.remotecall_wait(::Any, ::Integer, ::Any...) Distributed.remotecall_fetch(::Any, ::Integer, ::Any...) diff --git a/codex/stdlib/LinearAlgebra.md b/codex/stdlib/LinearAlgebra.md index 0b245a5..01969e1 100644 --- a/codex/stdlib/LinearAlgebra.md +++ b/codex/stdlib/LinearAlgebra.md @@ -38,13 +38,13 @@ julia> A = [-4. -17.; 2. 2.] julia> eigvals(A) 2-element Array{Complex{Float64},1}: - -1.0 + 5.0im -1.0 - 5.0im + -1.0 + 5.0im julia> eigvecs(A) 2×2 Array{Complex{Float64},2}: - 0.945905+0.0im 0.945905-0.0im - -0.166924-0.278207im -0.166924+0.278207im + 0.945905-0.0im 0.945905+0.0im + -0.166924+0.278207im -0.166924-0.278207im ``` In addition, Julia provides many [factorizations](@ref man-linalg-factorizations) which can be used to diff --git a/src/NEWS.md b/src/NEWS.md index 4d0a375..f3b3369 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -31,10 +31,13 @@ New library functions Standard library changes ------------------------ +* Added `Base.hasproperty` and `Base.hasfield` ([#28850](https://github.com/JuliaLang/julia/issues/28850)). + #### LinearAlgebra * Added keyword arguments `rtol`, `atol` to `pinv` and `nullspace` ([#29998](https://github.com/JuliaLang/julia/issues/29998)). * `UniformScaling` instances are now callable such that e.g. `I(3)` will produce a `Diagonal` matrix ([#30298](https://github.com/JuliaLang/julia/issues/30298)). +* Eigenvalues λ of general matrices are now sorted lexicographically by (Re λ, Im λ) ([#21598](https://github.com/JuliaLang/julia/issues/21598)). #### SparseArrays diff --git a/src/devdocs/inference.md b/src/devdocs/inference.md index 97f2122..0603c1d 100644 --- a/src/devdocs/inference.md +++ b/src/devdocs/inference.md @@ -103,7 +103,7 @@ mi = Base.method_instances(f, tt)[1] ci = code_typed(f, tt)[1][1] opt = Core.Compiler.OptimizationState(mi, params) # Calculate cost of each statement -cost(stmt::Expr) = Core.Compiler.statement_cost(stmt, -1, ci, opt.sp, opt.slottypes, opt.params) +cost(stmt::Expr) = Core.Compiler.statement_cost(stmt, -1, ci, opt.sptypes, opt.slottypes, opt.params) cost(stmt) = 0 cst = map(cost, ci.code) diff --git a/src/devdocs/reflection.md b/src/devdocs/reflection.md index 350fda7..15d6e41 100644 --- a/src/devdocs/reflection.md +++ b/src/devdocs/reflection.md @@ -96,6 +96,7 @@ as assignments, branches, and calls: ```jldoctest julia> Meta.lower(@__MODULE__, :( [1+2, sin(0.5)] )) :($(Expr(:thunk, CodeInfo( + @ none within `top-level scope' 1 ─ %1 = 1 + 2 │ %2 = sin(0.5) │ %3 = (Base.vect)(%1, %2) @@ -122,7 +123,6 @@ calls and expand argument types automatically: ```julia-repl julia> @code_llvm +(1,1) -; @ int.jl:53 within `+' define i64 @"julia_+_130862"(i64, i64) { top: %2 = add i64 %1, %0 @@ -130,5 +130,24 @@ top: } ``` -See [`@code_lowered`](@ref), [`@code_typed`](@ref), [`@code_warntype`](@ref), +For more informations see [`@code_lowered`](@ref), [`@code_typed`](@ref), [`@code_warntype`](@ref), [`@code_llvm`](@ref), and [`@code_native`](@ref). + +### Printing of debug information + +The aforementioned functions and macros take the keyword argument `debuginfo` that controls the level +debug information printed. + +``` +julia> @code_typed debuginfo=:source +(1,1) +CodeInfo( + @ int.jl:53 within `+' +1 ─ %1 = (Base.add_int)(x, y)::Int64 +└── return %1 +) => Int64 +``` + +Possible values for `debuginfo` are: `:none`, `:source`, and`:default`. +Per default debug information is not printed, but that can be changed +by setting `Base.IRShow.default_debuginfo[] = :source`. + diff --git a/src/manual/performance-tips.md b/src/manual/performance-tips.md index 2dbd75a..62ad178 100644 --- a/src/manual/performance-tips.md +++ b/src/manual/performance-tips.md @@ -164,9 +164,9 @@ julia> a = Real[] julia> push!(a, 1); push!(a, 2.0); push!(a, π) 3-element Array{Real,1}: - 1 - 2.0 - π = 3.1415926535897... + 1 + 2.0 + π ``` Because `a` is a an array of abstract type [`Real`](@ref), it must be able to hold any diff --git a/src/stdlib/Distributed.md b/src/stdlib/Distributed.md index 4653a26..3ecbd51 100644 --- a/src/stdlib/Distributed.md +++ b/src/stdlib/Distributed.md @@ -18,7 +18,8 @@ Distributed.pmap Distributed.RemoteException Distributed.Future Distributed.RemoteChannel -Distributed.fetch(::Any) +Distributed.fetch(::Future) +Distributed.fetch(::RemoteChannel) Distributed.remotecall(::Any, ::Integer, ::Any...) Distributed.remotecall_wait(::Any, ::Integer, ::Any...) Distributed.remotecall_fetch(::Any, ::Integer, ::Any...) diff --git a/src/stdlib/LinearAlgebra.md b/src/stdlib/LinearAlgebra.md index 0b245a5..01969e1 100644 --- a/src/stdlib/LinearAlgebra.md +++ b/src/stdlib/LinearAlgebra.md @@ -38,13 +38,13 @@ julia> A = [-4. -17.; 2. 2.] julia> eigvals(A) 2-element Array{Complex{Float64},1}: - -1.0 + 5.0im -1.0 - 5.0im + -1.0 + 5.0im julia> eigvecs(A) 2×2 Array{Complex{Float64},2}: - 0.945905+0.0im 0.945905-0.0im - -0.166924-0.278207im -0.166924+0.278207im + 0.945905-0.0im 0.945905+0.0im + -0.166924+0.278207im -0.166924-0.278207im ``` In addition, Julia provides many [factorizations](@ref man-linalg-factorizations) which can be used to From 3985f1877e6e5a5c39aa37bafbe8b8a00adf3137 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Fri, 8 Feb 2019 00:25:07 +0900 Subject: [PATCH 096/153] update Julia 1.2.0-DEV.285 (2019-02-07) Commit 03252205c7 --- codex/NEWS.md | 6 ++++-- codex/base/base.md | 2 ++ codex/devdocs/reflection.md | 6 +++--- codex/manual/metaprogramming.md | 10 +++++----- src/NEWS.md | 6 ++++-- src/base/base.md | 2 ++ src/devdocs/reflection.md | 6 +++--- src/manual/metaprogramming.md | 10 +++++----- 8 files changed, 28 insertions(+), 20 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index f3b3369..7e7519d 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -7,6 +7,7 @@ New language features * The `extrema` function now accepts a function argument in the same manner as `minimum` and `maximum` ([#30323](https://github.com/JuliaLang/julia/issues/30323)). * `hasmethod` can now check for matching keyword argument names ([#30712](https://github.com/JuliaLang/julia/issues/30712)). +* `startswith` and `endswith` now accept a `Regex` for the second argument ([#29790](https://github.com/JuliaLang/julia/issues/29790)). Multi-threading changes ----------------------- @@ -27,12 +28,13 @@ New library functions --------------------- * `getipaddrs()` function returns all the IP addresses of the local machine ([#30349](https://github.com/JuliaLang/julia/issues/30349)) +* Added `Base.hasproperty` and `Base.hasfield` ([#28850](https://github.com/JuliaLang/julia/issues/28850)). +* One argument `!=(x)`, `>(x)`, `>=(x)`, `<(x)`, `<=(x)` has been added for currying, + similar to the existing `==(x)` and `isequal(x)` methods ([#30915](https://github.com/JuliaLang/julia/issues/30915)). Standard library changes ------------------------ -* Added `Base.hasproperty` and `Base.hasfield` ([#28850](https://github.com/JuliaLang/julia/issues/28850)). - #### LinearAlgebra * Added keyword arguments `rtol`, `atol` to `pinv` and `nullspace` ([#29998](https://github.com/JuliaLang/julia/issues/29998)). diff --git a/codex/base/base.md b/codex/base/base.md index 205a670..3a1df62 100644 --- a/codex/base/base.md +++ b/codex/base/base.md @@ -122,6 +122,7 @@ Base.deepcopy Base.getproperty Base.setproperty! Base.propertynames +Base.hasproperty Core.getfield Core.setfield! Core.isdefined @@ -158,6 +159,7 @@ Base.isstructtype Base.nameof(::DataType) Base.fieldnames Base.fieldname +Base.hasfield ``` ### Memory layout diff --git a/codex/devdocs/reflection.md b/codex/devdocs/reflection.md index 15d6e41..726be76 100644 --- a/codex/devdocs/reflection.md +++ b/codex/devdocs/reflection.md @@ -83,7 +83,7 @@ be passed instead!). For example: ```jldoctest; setup = :(using InteractiveUtils) julia> macroexpand(@__MODULE__, :(@edit println("")) ) -:((InteractiveUtils.edit)(println, (Base.typesof)(""))) +:(InteractiveUtils.edit(println, (Base.typesof)(""))) ``` The functions `Base.Meta.show_sexpr` and [`dump`](@ref) are used to display S-expr style views @@ -99,7 +99,7 @@ julia> Meta.lower(@__MODULE__, :( [1+2, sin(0.5)] )) @ none within `top-level scope' 1 ─ %1 = 1 + 2 │ %2 = sin(0.5) -│ %3 = (Base.vect)(%1, %2) +│ %3 = Base.vect(%1, %2) └── return %3 )))) ``` @@ -142,7 +142,7 @@ debug information printed. julia> @code_typed debuginfo=:source +(1,1) CodeInfo( @ int.jl:53 within `+' -1 ─ %1 = (Base.add_int)(x, y)::Int64 +1 ─ %1 = Base.add_int(x, y)::Int64 └── return %1 ) => Int64 ``` diff --git a/codex/manual/metaprogramming.md b/codex/manual/metaprogramming.md index f6911cf..a1c0722 100644 --- a/codex/manual/metaprogramming.md +++ b/codex/manual/metaprogramming.md @@ -511,7 +511,7 @@ this is an extremely useful tool for debugging macros): ```julia-repl sayhello2 julia> ex = macroexpand(Main, :(@sayhello("human")) ) -:((Main.println)("Hello, ", "human")) +:(Main.println("Hello, ", "human")) julia> typeof(ex) Expr @@ -524,7 +524,7 @@ There also exists a macro [`@macroexpand`](@ref) that is perhaps a bit more conv ```jldoctest sayhello2 julia> @macroexpand @sayhello "human" -:((println)("Hello, ", "human")) +:(println("Hello, ", "human")) ``` ### Hold up: why macros? @@ -555,7 +555,7 @@ julia> typeof(ex) Expr julia> ex -:((println)("I execute at runtime. The argument is: ", $(Expr(:copyast, :($(QuoteNode(:((1, 2, 3))))))))) +:(println("I execute at runtime. The argument is: ", $(Expr(:copyast, :($(QuoteNode(:((1, 2, 3))))))))) julia> eval(ex) I execute at runtime. The argument is: (1, 2, 3) @@ -698,14 +698,14 @@ julia> @macroexpand @assert a == b :(if Main.a == Main.b Main.nothing else - (Main.throw)((Main.AssertionError)("a == b")) + Main.throw(Main.AssertionError("a == b")) end) julia> @macroexpand @assert a==b "a should equal b!" :(if Main.a == Main.b Main.nothing else - (Main.throw)((Main.AssertionError)("a should equal b!")) + Main.throw(Main.AssertionError("a should equal b!")) end) ``` diff --git a/src/NEWS.md b/src/NEWS.md index f3b3369..7e7519d 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -7,6 +7,7 @@ New language features * The `extrema` function now accepts a function argument in the same manner as `minimum` and `maximum` ([#30323](https://github.com/JuliaLang/julia/issues/30323)). * `hasmethod` can now check for matching keyword argument names ([#30712](https://github.com/JuliaLang/julia/issues/30712)). +* `startswith` and `endswith` now accept a `Regex` for the second argument ([#29790](https://github.com/JuliaLang/julia/issues/29790)). Multi-threading changes ----------------------- @@ -27,12 +28,13 @@ New library functions --------------------- * `getipaddrs()` function returns all the IP addresses of the local machine ([#30349](https://github.com/JuliaLang/julia/issues/30349)) +* Added `Base.hasproperty` and `Base.hasfield` ([#28850](https://github.com/JuliaLang/julia/issues/28850)). +* One argument `!=(x)`, `>(x)`, `>=(x)`, `<(x)`, `<=(x)` has been added for currying, + similar to the existing `==(x)` and `isequal(x)` methods ([#30915](https://github.com/JuliaLang/julia/issues/30915)). Standard library changes ------------------------ -* Added `Base.hasproperty` and `Base.hasfield` ([#28850](https://github.com/JuliaLang/julia/issues/28850)). - #### LinearAlgebra * Added keyword arguments `rtol`, `atol` to `pinv` and `nullspace` ([#29998](https://github.com/JuliaLang/julia/issues/29998)). diff --git a/src/base/base.md b/src/base/base.md index 205a670..3a1df62 100644 --- a/src/base/base.md +++ b/src/base/base.md @@ -122,6 +122,7 @@ Base.deepcopy Base.getproperty Base.setproperty! Base.propertynames +Base.hasproperty Core.getfield Core.setfield! Core.isdefined @@ -158,6 +159,7 @@ Base.isstructtype Base.nameof(::DataType) Base.fieldnames Base.fieldname +Base.hasfield ``` ### Memory layout diff --git a/src/devdocs/reflection.md b/src/devdocs/reflection.md index 15d6e41..726be76 100644 --- a/src/devdocs/reflection.md +++ b/src/devdocs/reflection.md @@ -83,7 +83,7 @@ be passed instead!). For example: ```jldoctest; setup = :(using InteractiveUtils) julia> macroexpand(@__MODULE__, :(@edit println("")) ) -:((InteractiveUtils.edit)(println, (Base.typesof)(""))) +:(InteractiveUtils.edit(println, (Base.typesof)(""))) ``` The functions `Base.Meta.show_sexpr` and [`dump`](@ref) are used to display S-expr style views @@ -99,7 +99,7 @@ julia> Meta.lower(@__MODULE__, :( [1+2, sin(0.5)] )) @ none within `top-level scope' 1 ─ %1 = 1 + 2 │ %2 = sin(0.5) -│ %3 = (Base.vect)(%1, %2) +│ %3 = Base.vect(%1, %2) └── return %3 )))) ``` @@ -142,7 +142,7 @@ debug information printed. julia> @code_typed debuginfo=:source +(1,1) CodeInfo( @ int.jl:53 within `+' -1 ─ %1 = (Base.add_int)(x, y)::Int64 +1 ─ %1 = Base.add_int(x, y)::Int64 └── return %1 ) => Int64 ``` diff --git a/src/manual/metaprogramming.md b/src/manual/metaprogramming.md index f6911cf..a1c0722 100644 --- a/src/manual/metaprogramming.md +++ b/src/manual/metaprogramming.md @@ -511,7 +511,7 @@ this is an extremely useful tool for debugging macros): ```julia-repl sayhello2 julia> ex = macroexpand(Main, :(@sayhello("human")) ) -:((Main.println)("Hello, ", "human")) +:(Main.println("Hello, ", "human")) julia> typeof(ex) Expr @@ -524,7 +524,7 @@ There also exists a macro [`@macroexpand`](@ref) that is perhaps a bit more conv ```jldoctest sayhello2 julia> @macroexpand @sayhello "human" -:((println)("Hello, ", "human")) +:(println("Hello, ", "human")) ``` ### Hold up: why macros? @@ -555,7 +555,7 @@ julia> typeof(ex) Expr julia> ex -:((println)("I execute at runtime. The argument is: ", $(Expr(:copyast, :($(QuoteNode(:((1, 2, 3))))))))) +:(println("I execute at runtime. The argument is: ", $(Expr(:copyast, :($(QuoteNode(:((1, 2, 3))))))))) julia> eval(ex) I execute at runtime. The argument is: (1, 2, 3) @@ -698,14 +698,14 @@ julia> @macroexpand @assert a == b :(if Main.a == Main.b Main.nothing else - (Main.throw)((Main.AssertionError)("a == b")) + Main.throw(Main.AssertionError("a == b")) end) julia> @macroexpand @assert a==b "a should equal b!" :(if Main.a == Main.b Main.nothing else - (Main.throw)((Main.AssertionError)("a should equal b!")) + Main.throw(Main.AssertionError("a should equal b!")) end) ``` From c0de3aca9fd8b2c7d0efd83646541e0829c4188c Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Sun, 10 Feb 2019 20:42:35 +0900 Subject: [PATCH 097/153] update Julia 1.2.0-DEV.303 (2019-02-09) Commit 0680f19907 --- codex/NEWS.md | 13 ++++-- codex/devdocs/ast.md | 5 +++ codex/manual/environment-variables.md | 58 ++++++++++++++++++++------- codex/manual/modules.md | 13 ------ src/NEWS.md | 13 ++++-- src/devdocs/ast.md | 5 +++ src/manual/environment-variables.md | 58 ++++++++++++++++++++------- src/manual/modules.md | 13 ------ 8 files changed, 116 insertions(+), 62 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index 7e7519d..d161449 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -4,10 +4,8 @@ Julia v1.2 Release Notes New language features --------------------- -* The `extrema` function now accepts a function argument in the same manner as `minimum` and - `maximum` ([#30323](https://github.com/JuliaLang/julia/issues/30323)). -* `hasmethod` can now check for matching keyword argument names ([#30712](https://github.com/JuliaLang/julia/issues/30712)). -* `startswith` and `endswith` now accept a `Regex` for the second argument ([#29790](https://github.com/JuliaLang/julia/issues/29790)). + * Argument splatting (`x...`) can now be used in calls to the `new` pseudo-function in + constructors ([#30577](https://github.com/JuliaLang/julia/issues/30577)). Multi-threading changes ----------------------- @@ -35,11 +33,18 @@ New library functions Standard library changes ------------------------ + * The `extrema` function now accepts a function argument in the same manner as `minimum` and + `maximum` ([#30323](https://github.com/JuliaLang/julia/issues/30323)). + * `hasmethod` can now check for matching keyword argument names ([#30712](https://github.com/JuliaLang/julia/issues/30712)). + * `startswith` and `endswith` now accept a `Regex` for the second argument ([#29790](https://github.com/JuliaLang/julia/issues/29790)). + #### LinearAlgebra * Added keyword arguments `rtol`, `atol` to `pinv` and `nullspace` ([#29998](https://github.com/JuliaLang/julia/issues/29998)). * `UniformScaling` instances are now callable such that e.g. `I(3)` will produce a `Diagonal` matrix ([#30298](https://github.com/JuliaLang/julia/issues/30298)). * Eigenvalues λ of general matrices are now sorted lexicographically by (Re λ, Im λ) ([#21598](https://github.com/JuliaLang/julia/issues/21598)). +* `one` for structured matrices (`Diagonal`, `Bidiagonal`, `Tridiagonal`, `Symtridiagonal`) now preserves + structure and type. ([#29777](https://github.com/JuliaLang/julia/issues/29777)) #### SparseArrays diff --git a/codex/devdocs/ast.md b/codex/devdocs/ast.md index b89b4db..2b27c94 100644 --- a/codex/devdocs/ast.md +++ b/codex/devdocs/ast.md @@ -359,6 +359,11 @@ These symbols appear in the `head` field of [`Expr`](@ref)s in lowered form. to this, and the type is always inserted by the compiler. This is very much an internal-only feature, and does no checking. Evaluating arbitrary `new` expressions can easily segfault. + * `splatnew` + + Similar to `new`, except field values are passed as a single tuple. Works similarly to + `Base.splat(new)` if `new` were a first-class function, hence the name. + * `return` Returns its argument as the value of the enclosing function. diff --git a/codex/manual/environment-variables.md b/codex/manual/environment-variables.md index a5c1e77..3deef38 100644 --- a/codex/manual/environment-variables.md +++ b/codex/manual/environment-variables.md @@ -75,27 +75,40 @@ and a global configuration search path of ### `JULIA_PROJECT` -A directory path that points to the current Julia project. Setting this -environment variable has the same effect as specifying the `--project` start-up -option, but `--project` has higher precedence. If the variable is set to `@.` then -Julia tries to find a project directory that contains `Project.toml` or -`JuliaProject.toml` file from the current directory and its parents. See also +A directory path that indicates which project should be the initial active project. +Setting this environment variable has the same effect as specifying the `--project` +start-up option, but `--project` has higher precedence. If the variable is set to `@.` +then Julia tries to find a project directory that contains `Project.toml` or +`JuliaProject.toml` file from the current directory and its parents. See also the chapter on [Code Loading](@ref). !!! note - `JULIA_PROJECT` must be defined before starting julia; defining it in `startup.jl` is too late in the startup process. + `JULIA_PROJECT` must be defined before starting julia; defining it in `startup.jl` + is too late in the startup process. ### `JULIA_LOAD_PATH` -A separated list of absolute paths that are to be appended to the variable -[`LOAD_PATH`](@ref). (In Unix-like systems, `:` is the path separator; in -Windows systems, `;` is the path separator.) The `LOAD_PATH` variable is where -[`Base.require`](@ref) and `Base.load_in_path()` look for code; it defaults to -the absolute path -`$JULIA_HOME/../share/julia/stdlib/v$(VERSION.major).$(VERSION.minor)` so that, -e.g., version 0.7 of Julia on a Linux system with a Julia executable at -`/bin/julia` will have a default `LOAD_PATH` of `/share/julia/stdlib/v0.7`. +The `JULIA_LOAD_PATH` environment variable is used to populate the global Julia +[`LOAD_PATH`](@ref) variable, which determines which packages can be loaded via +`import` and `using` (see [Code Loading](@ref)). Unlike the shell `PATH` variable, +empty entries in `JULIA_LOAD_PATH` are expanded to the default value of `LOAD_PATH`, +`["@", "@v#.#", "@stdlib"]` when populating `LOAD_PATH`. This allows easy appending, +prepending, etc. of the load path value in shell scripts regardless of whether +`JULIA_LOAD_PATH` is already set or not. For example, to prepend the directory +`/foo/bar` to `LOAD_PATH` just do +```sh +export JULIA_LOAD_PATH="/foo/bar:$JULIA_LOAD_PATH" +``` +If the `JULIA_LOAD_PATH` environment variable is already set, its old value will be +prepended with `/foo/bar`. On the other hand, if `JULIA_LOAD_PATH` is not set, then +it will be set to `/foo/bar:` which will expand to a `LOAD_PATH` value of +`["/foo/bar", "@", "@v#.#", "@stdlib"]`. If `JULIA_LOAD_PATH` is set to the empty +string, it expands to an empty `LOAD_PATH` array. In other words, the empty string +is interpreted as a zero-element array, not a one-element array of the empty string. +This behavior was chosen so that it would be possible to set an empty load path via +the environment variable. If you want the default load path, either unset the +environment variable or if it must have a value, set it to the string `:`. ### `JULIA_HISTORY` @@ -119,6 +132,23 @@ Suppose the value of `$JULIA_PKGRESOLVE_ACCURACY` is `n`. Then * the number of iterations between decimation steps is `10*n`, and * at decimation steps, at most one in every `20*n` packages is decimated. +### `JULIA_DEPOT_PATH` + +A stack of depot locations where the package manager, as well as Julia's code loading +mechanisms, look for package registries, installed packages, named environments, +repo clones, cached compiled package images, and configuration files. + +The depot path is controlled by Julia's `DEPOT_PATH` global variable which is populated at +startup based on the value of the `JULIA_DEPOT_PATH` environment variable. The first entry +is the “user depot” and should be writable by and owned by the current user. The user depot +is where: registries are cloned, new package versions are installed, named environments are +created and updated, package repos are cloned, newly compiled package image files are +saved, log files are written, development packages are checked out by default, and global +configuration data is saved. Later entries in the depot path are treated as read-only and +are appropriate for registries, packages, etc. installed and managed by system +administrators. + + ## External applications ### `JULIA_SHELL` diff --git a/codex/manual/modules.md b/codex/manual/modules.md index ef073cb..62a509e 100644 --- a/codex/manual/modules.md +++ b/codex/manual/modules.md @@ -183,19 +183,6 @@ look for `Utils` in `Parent`'s enclosing module rather than in `Parent` itself. Note that relative-import qualifiers are only valid in `using` and `import` statements. -### Module file paths - -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 `~/.julia/config/startup.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 If a name is qualified (e.g. `Base.sin`), then it can be accessed even if it is not exported. diff --git a/src/NEWS.md b/src/NEWS.md index 7e7519d..d161449 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -4,10 +4,8 @@ Julia v1.2 Release Notes New language features --------------------- -* The `extrema` function now accepts a function argument in the same manner as `minimum` and - `maximum` ([#30323](https://github.com/JuliaLang/julia/issues/30323)). -* `hasmethod` can now check for matching keyword argument names ([#30712](https://github.com/JuliaLang/julia/issues/30712)). -* `startswith` and `endswith` now accept a `Regex` for the second argument ([#29790](https://github.com/JuliaLang/julia/issues/29790)). + * Argument splatting (`x...`) can now be used in calls to the `new` pseudo-function in + constructors ([#30577](https://github.com/JuliaLang/julia/issues/30577)). Multi-threading changes ----------------------- @@ -35,11 +33,18 @@ New library functions Standard library changes ------------------------ + * The `extrema` function now accepts a function argument in the same manner as `minimum` and + `maximum` ([#30323](https://github.com/JuliaLang/julia/issues/30323)). + * `hasmethod` can now check for matching keyword argument names ([#30712](https://github.com/JuliaLang/julia/issues/30712)). + * `startswith` and `endswith` now accept a `Regex` for the second argument ([#29790](https://github.com/JuliaLang/julia/issues/29790)). + #### LinearAlgebra * Added keyword arguments `rtol`, `atol` to `pinv` and `nullspace` ([#29998](https://github.com/JuliaLang/julia/issues/29998)). * `UniformScaling` instances are now callable such that e.g. `I(3)` will produce a `Diagonal` matrix ([#30298](https://github.com/JuliaLang/julia/issues/30298)). * Eigenvalues λ of general matrices are now sorted lexicographically by (Re λ, Im λ) ([#21598](https://github.com/JuliaLang/julia/issues/21598)). +* `one` for structured matrices (`Diagonal`, `Bidiagonal`, `Tridiagonal`, `Symtridiagonal`) now preserves + structure and type. ([#29777](https://github.com/JuliaLang/julia/issues/29777)) #### SparseArrays diff --git a/src/devdocs/ast.md b/src/devdocs/ast.md index b89b4db..2b27c94 100644 --- a/src/devdocs/ast.md +++ b/src/devdocs/ast.md @@ -359,6 +359,11 @@ These symbols appear in the `head` field of [`Expr`](@ref)s in lowered form. to this, and the type is always inserted by the compiler. This is very much an internal-only feature, and does no checking. Evaluating arbitrary `new` expressions can easily segfault. + * `splatnew` + + Similar to `new`, except field values are passed as a single tuple. Works similarly to + `Base.splat(new)` if `new` were a first-class function, hence the name. + * `return` Returns its argument as the value of the enclosing function. diff --git a/src/manual/environment-variables.md b/src/manual/environment-variables.md index a5c1e77..3deef38 100644 --- a/src/manual/environment-variables.md +++ b/src/manual/environment-variables.md @@ -75,27 +75,40 @@ and a global configuration search path of ### `JULIA_PROJECT` -A directory path that points to the current Julia project. Setting this -environment variable has the same effect as specifying the `--project` start-up -option, but `--project` has higher precedence. If the variable is set to `@.` then -Julia tries to find a project directory that contains `Project.toml` or -`JuliaProject.toml` file from the current directory and its parents. See also +A directory path that indicates which project should be the initial active project. +Setting this environment variable has the same effect as specifying the `--project` +start-up option, but `--project` has higher precedence. If the variable is set to `@.` +then Julia tries to find a project directory that contains `Project.toml` or +`JuliaProject.toml` file from the current directory and its parents. See also the chapter on [Code Loading](@ref). !!! note - `JULIA_PROJECT` must be defined before starting julia; defining it in `startup.jl` is too late in the startup process. + `JULIA_PROJECT` must be defined before starting julia; defining it in `startup.jl` + is too late in the startup process. ### `JULIA_LOAD_PATH` -A separated list of absolute paths that are to be appended to the variable -[`LOAD_PATH`](@ref). (In Unix-like systems, `:` is the path separator; in -Windows systems, `;` is the path separator.) The `LOAD_PATH` variable is where -[`Base.require`](@ref) and `Base.load_in_path()` look for code; it defaults to -the absolute path -`$JULIA_HOME/../share/julia/stdlib/v$(VERSION.major).$(VERSION.minor)` so that, -e.g., version 0.7 of Julia on a Linux system with a Julia executable at -`/bin/julia` will have a default `LOAD_PATH` of `/share/julia/stdlib/v0.7`. +The `JULIA_LOAD_PATH` environment variable is used to populate the global Julia +[`LOAD_PATH`](@ref) variable, which determines which packages can be loaded via +`import` and `using` (see [Code Loading](@ref)). Unlike the shell `PATH` variable, +empty entries in `JULIA_LOAD_PATH` are expanded to the default value of `LOAD_PATH`, +`["@", "@v#.#", "@stdlib"]` when populating `LOAD_PATH`. This allows easy appending, +prepending, etc. of the load path value in shell scripts regardless of whether +`JULIA_LOAD_PATH` is already set or not. For example, to prepend the directory +`/foo/bar` to `LOAD_PATH` just do +```sh +export JULIA_LOAD_PATH="/foo/bar:$JULIA_LOAD_PATH" +``` +If the `JULIA_LOAD_PATH` environment variable is already set, its old value will be +prepended with `/foo/bar`. On the other hand, if `JULIA_LOAD_PATH` is not set, then +it will be set to `/foo/bar:` which will expand to a `LOAD_PATH` value of +`["/foo/bar", "@", "@v#.#", "@stdlib"]`. If `JULIA_LOAD_PATH` is set to the empty +string, it expands to an empty `LOAD_PATH` array. In other words, the empty string +is interpreted as a zero-element array, not a one-element array of the empty string. +This behavior was chosen so that it would be possible to set an empty load path via +the environment variable. If you want the default load path, either unset the +environment variable or if it must have a value, set it to the string `:`. ### `JULIA_HISTORY` @@ -119,6 +132,23 @@ Suppose the value of `$JULIA_PKGRESOLVE_ACCURACY` is `n`. Then * the number of iterations between decimation steps is `10*n`, and * at decimation steps, at most one in every `20*n` packages is decimated. +### `JULIA_DEPOT_PATH` + +A stack of depot locations where the package manager, as well as Julia's code loading +mechanisms, look for package registries, installed packages, named environments, +repo clones, cached compiled package images, and configuration files. + +The depot path is controlled by Julia's `DEPOT_PATH` global variable which is populated at +startup based on the value of the `JULIA_DEPOT_PATH` environment variable. The first entry +is the “user depot” and should be writable by and owned by the current user. The user depot +is where: registries are cloned, new package versions are installed, named environments are +created and updated, package repos are cloned, newly compiled package image files are +saved, log files are written, development packages are checked out by default, and global +configuration data is saved. Later entries in the depot path are treated as read-only and +are appropriate for registries, packages, etc. installed and managed by system +administrators. + + ## External applications ### `JULIA_SHELL` diff --git a/src/manual/modules.md b/src/manual/modules.md index ef073cb..62a509e 100644 --- a/src/manual/modules.md +++ b/src/manual/modules.md @@ -183,19 +183,6 @@ look for `Utils` in `Parent`'s enclosing module rather than in `Parent` itself. Note that relative-import qualifiers are only valid in `using` and `import` statements. -### Module file paths - -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 `~/.julia/config/startup.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 If a name is qualified (e.g. `Base.sin`), then it can be accessed even if it is not exported. From 3575d882f578eb3c82b74e5f011ac62d6ec154b8 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Thu, 14 Feb 2019 16:45:27 +0900 Subject: [PATCH 098/153] update Julia 1.2.0-DEV.321 (2019-02-14) Commit a03da7312e --- codex/NEWS.md | 9 +++++---- codex/manual/performance-tips.md | 2 +- codex/manual/strings.md | 21 +++++++++++++++++++++ src/NEWS.md | 9 +++++---- src/manual/performance-tips.md | 2 +- src/manual/strings.md | 21 +++++++++++++++++++++ 6 files changed, 54 insertions(+), 10 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index d161449..3c6eab8 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -33,10 +33,11 @@ New library functions Standard library changes ------------------------ - * The `extrema` function now accepts a function argument in the same manner as `minimum` and - `maximum` ([#30323](https://github.com/JuliaLang/julia/issues/30323)). - * `hasmethod` can now check for matching keyword argument names ([#30712](https://github.com/JuliaLang/julia/issues/30712)). - * `startswith` and `endswith` now accept a `Regex` for the second argument ([#29790](https://github.com/JuliaLang/julia/issues/29790)). +* The `extrema` function now accepts a function argument in the same manner as `minimum` and + `maximum` ([#30323](https://github.com/JuliaLang/julia/issues/30323)). +* `hasmethod` can now check for matching keyword argument names ([#30712](https://github.com/JuliaLang/julia/issues/30712)). +* `startswith` and `endswith` now accept a `Regex` for the second argument ([#29790](https://github.com/JuliaLang/julia/issues/29790)). +* `retry` supports arbitrary callable objects ([#30382](https://github.com/JuliaLang/julia/issues/30382)). #### LinearAlgebra diff --git a/codex/manual/performance-tips.md b/codex/manual/performance-tips.md index 62ad178..b5d0eec 100644 --- a/codex/manual/performance-tips.md +++ b/codex/manual/performance-tips.md @@ -36,7 +36,7 @@ Passing arguments to functions is better style. It leads to more reusable code a !!! note All code in the REPL is evaluated in global scope, so a variable defined and assigned - at toplevel will be a **global** variable. Variables defined in at top level scope inside + at top level will be a **global** variable. Variables defined at top level scope inside modules are also global. In the following REPL session: diff --git a/codex/manual/strings.md b/codex/manual/strings.md index c9b27dc..d77486b 100644 --- a/codex/manual/strings.md +++ b/codex/manual/strings.md @@ -295,6 +295,27 @@ In this case, the character `∀` is a three-byte character, so the indices 2 an and the next character's index is 4; this next valid index can be computed by [`nextind(s,1)`](@ref), and the next index after that by `nextind(s,4)` and so on. +Since `end` is always the last valid index into a collection, `end-1` references an invalid +byte index if the second-to-last character is multibyte. + +```jldoctest unicodestring +julia> s[end-1] +' ': ASCII/Unicode U+0020 (category Zs: Separator, space) + +julia> s[end-2] +ERROR: StringIndexError("∀ x ∃ y", 9) +Stacktrace: +[...] + +julia> s[prevind(s, end, 2)] +'∃': Unicode U+2203 (category Sm: Symbol, math) +``` + +The first case works, because the last character `y` and the space are one-byte characters, +whereas `end-2` indexes into the middle of the `∃` multibyte representation. The correct +way for this case is using `prevind(s, lastindex(s), 2)` or, if you're using that value to index +into `s` you can write `s[prevind(s, end, 2)]` and `end` expands to `lastindex(s)`. + Extraction of a substring using range indexing also expects valid byte indices or an error is thrown: ```jldoctest unicodestring diff --git a/src/NEWS.md b/src/NEWS.md index d161449..3c6eab8 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -33,10 +33,11 @@ New library functions Standard library changes ------------------------ - * The `extrema` function now accepts a function argument in the same manner as `minimum` and - `maximum` ([#30323](https://github.com/JuliaLang/julia/issues/30323)). - * `hasmethod` can now check for matching keyword argument names ([#30712](https://github.com/JuliaLang/julia/issues/30712)). - * `startswith` and `endswith` now accept a `Regex` for the second argument ([#29790](https://github.com/JuliaLang/julia/issues/29790)). +* The `extrema` function now accepts a function argument in the same manner as `minimum` and + `maximum` ([#30323](https://github.com/JuliaLang/julia/issues/30323)). +* `hasmethod` can now check for matching keyword argument names ([#30712](https://github.com/JuliaLang/julia/issues/30712)). +* `startswith` and `endswith` now accept a `Regex` for the second argument ([#29790](https://github.com/JuliaLang/julia/issues/29790)). +* `retry` supports arbitrary callable objects ([#30382](https://github.com/JuliaLang/julia/issues/30382)). #### LinearAlgebra diff --git a/src/manual/performance-tips.md b/src/manual/performance-tips.md index 62ad178..b5d0eec 100644 --- a/src/manual/performance-tips.md +++ b/src/manual/performance-tips.md @@ -36,7 +36,7 @@ Passing arguments to functions is better style. It leads to more reusable code a !!! note All code in the REPL is evaluated in global scope, so a variable defined and assigned - at toplevel will be a **global** variable. Variables defined in at top level scope inside + at top level will be a **global** variable. Variables defined at top level scope inside modules are also global. In the following REPL session: diff --git a/src/manual/strings.md b/src/manual/strings.md index c9b27dc..d77486b 100644 --- a/src/manual/strings.md +++ b/src/manual/strings.md @@ -295,6 +295,27 @@ In this case, the character `∀` is a three-byte character, so the indices 2 an and the next character's index is 4; this next valid index can be computed by [`nextind(s,1)`](@ref), and the next index after that by `nextind(s,4)` and so on. +Since `end` is always the last valid index into a collection, `end-1` references an invalid +byte index if the second-to-last character is multibyte. + +```jldoctest unicodestring +julia> s[end-1] +' ': ASCII/Unicode U+0020 (category Zs: Separator, space) + +julia> s[end-2] +ERROR: StringIndexError("∀ x ∃ y", 9) +Stacktrace: +[...] + +julia> s[prevind(s, end, 2)] +'∃': Unicode U+2203 (category Sm: Symbol, math) +``` + +The first case works, because the last character `y` and the space are one-byte characters, +whereas `end-2` indexes into the middle of the `∃` multibyte representation. The correct +way for this case is using `prevind(s, lastindex(s), 2)` or, if you're using that value to index +into `s` you can write `s[prevind(s, end, 2)]` and `end` expands to `lastindex(s)`. + Extraction of a substring using range indexing also expects valid byte indices or an error is thrown: ```jldoctest unicodestring From 1d3d30ec27824655a4475f0fbfb49e00cf102d98 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Mon, 18 Feb 2019 02:28:59 +0900 Subject: [PATCH 099/153] update Julia 1.2.0-DEV.351 (2019-02-16) Commit dfee9457c0 --- codex/NEWS.md | 3 +- codex/base/constants.md | 1 + codex/devdocs/ast.md | 64 +++++++++++++++++++++++++-- codex/devdocs/sysimg.md | 2 +- codex/manual/environment-variables.md | 61 ++++++++++++++----------- codex/manual/functions.md | 55 +++++++++++++++++++++++ codex/manual/performance-tips.md | 30 +++++-------- src/NEWS.md | 3 +- src/base/constants.md | 1 + src/devdocs/ast.md | 64 +++++++++++++++++++++++++-- src/devdocs/sysimg.md | 2 +- src/manual/environment-variables.md | 61 ++++++++++++++----------- src/manual/functions.md | 55 +++++++++++++++++++++++ src/manual/performance-tips.md | 30 +++++-------- 14 files changed, 332 insertions(+), 100 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index 3c6eab8..ef2b09a 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -15,7 +15,7 @@ Multi-threading changes Language changes ---------------- - +* Empty entries in `JULIA_DEPOT_PATH` are now expanded to default depot entries ([#31009](https://github.com/JuliaLang/julia/issues/31009)). * `Enum` now behaves like a scalar when used in broadcasting ([#30670](https://github.com/JuliaLang/julia/issues/30670)). Command-line option changes @@ -38,6 +38,7 @@ Standard library changes * `hasmethod` can now check for matching keyword argument names ([#30712](https://github.com/JuliaLang/julia/issues/30712)). * `startswith` and `endswith` now accept a `Regex` for the second argument ([#29790](https://github.com/JuliaLang/julia/issues/29790)). * `retry` supports arbitrary callable objects ([#30382](https://github.com/JuliaLang/julia/issues/30382)). +* A no-argument construct to `Ptr{T}` has been added which constructs a null pointer ([#30919](https://github.com/JuliaLang/julia/issues/30919)) #### LinearAlgebra diff --git a/codex/base/constants.md b/codex/base/constants.md index 0893c3a..4ba0e62 100644 --- a/codex/base/constants.md +++ b/codex/base/constants.md @@ -6,6 +6,7 @@ Base.PROGRAM_FILE Base.ARGS Base.C_NULL Base.VERSION +Base.DEPOT_PATH Base.LOAD_PATH Base.Sys.BINDIR Base.Sys.CPU_THREADS diff --git a/codex/devdocs/ast.md b/codex/devdocs/ast.md index 2b27c94..b2593f9 100644 --- a/codex/devdocs/ast.md +++ b/codex/devdocs/ast.md @@ -239,7 +239,8 @@ Lowered form (IR) is more important to the compiler, since it is used for type i optimizations like inlining, and and code generation. It is also less obvious to the human, since it results from a significant rearrangement of the input syntax. -The following data types exist in lowered form: +In addition to `Symbol`s and some number types, the following data +types exist in lowered form: * `Expr` @@ -316,7 +317,7 @@ These symbols appear in the `head` field of [`Expr`](@ref)s in lowered form. Adds a method to a generic function and assigns the result if necessary. - Has a 1-argument form and a 4-argument form. The 1-argument form arises from the syntax `function foo end`. + Has a 1-argument form and a 3-argument form. The 1-argument form arises from the syntax `function foo end`. In the 1-argument form, the argument is a symbol. If this symbol already names a function in the current scope, nothing happens. If the symbol is undefined, a new function is created and assigned to the identifier specified by the symbol. If the symbol is defined but names a non-function, @@ -325,7 +326,7 @@ These symbols appear in the `head` field of [`Expr`](@ref)s in lowered form. type uniquely identifies the type to add the method to. When the type has fields, it wouldn't be clear whether the method was being added to the instance or its type. - The 4-argument form has the following arguments: + The 3-argument form has the following arguments: * `args[1]` @@ -345,9 +346,55 @@ These symbols appear in the `head` field of [`Expr`](@ref)s in lowered form. method to a function that also has methods defined in different scopes) this is an expression that evaluates to a `:lambda` expression. + * `struct_type` + + A 7-argument expression that defines a new `struct`: + + * `args[1]` + + The name of the `struct` + + * `args[2]` + + A `call` expression that creates `SimpleVector` specifying its parameters + + * `args[3]` + + A `call` expression that creates `SimpleVector` specifying its fieldnames + * `args[4]` - `true` or `false`, identifying whether the method is staged (`@generated function`). + A `Symbol` or `GlobalRef` specifying the supertype (e.g., `:Integer` or + `GlobalRef(Core, :Any)`) + + * `args[5]` + + A `call` expression that creates `SimpleVector` specifying its fieldtypes + + * `args[6]` + + A Bool, true if `mutable` + + * `args[7]` + + The number of arguments to initialize. This will be the number + of fields, or the minimum number of fields called by an inner + constructor's `new` statement. + + * `abstract_type` + + A 3-argument expression that defines a new abstract type. The + arguments are the same as the first three arguments of + `struct_type` expressions. + + * `primitive_type` + + A 4-argument expression that defines a new primitive type. Arguments 1, 2, and 4 + are the same as `struct_type`. Argument 3 is the number of bits. + + * `global` + + Declares a global binding. * `const` @@ -368,6 +415,11 @@ These symbols appear in the `head` field of [`Expr`](@ref)s in lowered form. Returns its argument as the value of the enclosing function. + * `isdefined` + + `Expr(:isdefined, :x)` returns a Bool indicating whether `x` has + already been defined in the current scope. + * `the_exception` Yields the caught exception inside a `catch` block, as returned by `jl_current_exception()`. @@ -400,6 +452,10 @@ These symbols appear in the `head` field of [`Expr`](@ref)s in lowered form. Has the value `false` if inlined into a section of code marked with `@inbounds`, otherwise has the value `true`. + * `simdloop` + + Marks the end of the inner loop of a `@simd` expression. + * `copyast` Part of the implementation of quasi-quote. The argument is a surface syntax AST that is simply diff --git a/codex/devdocs/sysimg.md b/codex/devdocs/sysimg.md index 8010df8..aa0da76 100644 --- a/codex/devdocs/sysimg.md +++ b/codex/devdocs/sysimg.md @@ -65,7 +65,7 @@ Additionally, a few special features are supported to control the function cloni 4. `min_size` - This cause the function for the targe to be optimize for size that might have + This causes the function for the target to be optimized for size that might have a significant runtime performance impact. This corresponds to `-Oz` Clang option. As an example, at the time of this writing, the following string is used in the creation of diff --git a/codex/manual/environment-variables.md b/codex/manual/environment-variables.md index 3deef38..0f84f78 100644 --- a/codex/manual/environment-variables.md +++ b/codex/manual/environment-variables.md @@ -91,12 +91,13 @@ the chapter on [Code Loading](@ref). The `JULIA_LOAD_PATH` environment variable is used to populate the global Julia [`LOAD_PATH`](@ref) variable, which determines which packages can be loaded via -`import` and `using` (see [Code Loading](@ref)). Unlike the shell `PATH` variable, -empty entries in `JULIA_LOAD_PATH` are expanded to the default value of `LOAD_PATH`, -`["@", "@v#.#", "@stdlib"]` when populating `LOAD_PATH`. This allows easy appending, -prepending, etc. of the load path value in shell scripts regardless of whether -`JULIA_LOAD_PATH` is already set or not. For example, to prepend the directory -`/foo/bar` to `LOAD_PATH` just do +`import` and `using` (see [Code Loading](@ref)). + +Unlike the shell `PATH` variable, empty entries in `JULIA_LOAD_PATH` are expanded to +the default value of `LOAD_PATH`, `["@", "@v#.#", "@stdlib"]` when populating +`LOAD_PATH`. This allows easy appending, prepending, etc. of the load path value in +shell scripts regardless of whether `JULIA_LOAD_PATH` is already set or not. For +example, to prepend the directory `/foo/bar` to `LOAD_PATH` just do ```sh export JULIA_LOAD_PATH="/foo/bar:$JULIA_LOAD_PATH" ``` @@ -110,6 +111,32 @@ This behavior was chosen so that it would be possible to set an empty load path the environment variable. If you want the default load path, either unset the environment variable or if it must have a value, set it to the string `:`. +### `JULIA_DEPOT_PATH` + +The `JULIA_DEPOT_PATH` environment variable is used to populate the global Julia +[`DEPOT_PATH`](@ref) variable, which controls where the package manager, as well +as Julia's code loading mechanisms, look for package registries, installed +packages, named environments, repo clones, cached compiled package images, and +configuration files. + +Unlike the shell `PATH` variable but similar to `JULIA_LOAD_PATH`, empty entries in +`JULIA_DEPOT_PATH` are expanded to the default value of `DEPOT_PATH`. This allows +easy appending, prepending, etc. of the depot path value in shell scripts regardless +of whether `JULIA_DEPOT_PATH` is already set or not. For example, to prepend the +directory `/foo/bar` to `DEPOT_PATH` just do +```sh +export JULIA_DEPOT_PATH="/foo/bar:$JULIA_DEPOT_PATH" +``` +If the `JULIA_DEPOT_PATH` environment variable is already set, its old value will be +prepended with `/foo/bar`. On the other hand, if `JULIA_DEPOT_PATH` is not set, then +it will be set to `/foo/bar:` which will have the effect of prepending `/foo/bar` to +the default depot path. If `JULIA_DEPOT_PATH` is set to the empty string, it expands +to an empty `DEPOT_PATH` array. In other words, the empty string is interpreted as a +zero-element array, not a one-element array of the empty string. This behavior was +chosen so that it would be possible to set an empty depot path via the environment +variable. If you want the default depot path, either unset the environment variable +or if it must have a value, set it to the string `:`. + ### `JULIA_HISTORY` The absolute path `REPL.find_hist_file()` of the REPL's history file. If @@ -128,25 +155,9 @@ by default `1`, and larger values correspond to larger amounts of time. Suppose the value of `$JULIA_PKGRESOLVE_ACCURACY` is `n`. Then -* the number of pre-decimation iterations is `20*n`, -* the number of iterations between decimation steps is `10*n`, and -* at decimation steps, at most one in every `20*n` packages is decimated. - -### `JULIA_DEPOT_PATH` - -A stack of depot locations where the package manager, as well as Julia's code loading -mechanisms, look for package registries, installed packages, named environments, -repo clones, cached compiled package images, and configuration files. - -The depot path is controlled by Julia's `DEPOT_PATH` global variable which is populated at -startup based on the value of the `JULIA_DEPOT_PATH` environment variable. The first entry -is the “user depot” and should be writable by and owned by the current user. The user depot -is where: registries are cloned, new package versions are installed, named environments are -created and updated, package repos are cloned, newly compiled package image files are -saved, log files are written, development packages are checked out by default, and global -configuration data is saved. Later entries in the depot path are treated as read-only and -are appropriate for registries, packages, etc. installed and managed by system -administrators. +* the number of pre-decimation iterations is `20*n`, +* the number of iterations between decimation steps is `10*n`, and +* at decimation steps, at most one in every `20*n` packages is decimated. ## External applications diff --git a/codex/manual/functions.md b/codex/manual/functions.md index 5e9ec95..1c68f08 100644 --- a/codex/manual/functions.md +++ b/codex/manual/functions.md @@ -660,6 +660,61 @@ enclosing scope. For example, the variable `data` in the above example of `open...do` is captured from the outer scope. Captured variables can create performance challenges as discussed in [performance tips](@ref man-performance-tips). +## Function composition and piping + +Functions in Julia can be combined by composing or piping (chaining) them together. + +Function composition is when you combine functions together and apply the resulting composition to arguments. +You use the function composition operator (`∘`) to compose the functions, so `(f ∘ g)(args...)` is the same as `f(g(args...))`. + +You can type the composition operator at the REPL and suitably-configured editors using `\circ`. + +For example, the `sqrt` and `+` functions can be composed like this: + +```jldoctest +julia> (sqrt ∘ +)(3, 6) +3.0 +``` + +This adds the numbers first, then finds the square root of the result. + +The next example composes three functions and maps the result over an array of strings: + +```jldoctest +julia> map(first ∘ reverse ∘ uppercase, split("you can compose functions like this")) +6-element Array{Char,1}: + 'U' + 'N' + 'E' + 'S' + 'E' + 'S' +``` + +Function chaining (sometimes called "piping" or "using a pipe" to send data to a subsequent function) is when you apply a function to the previous function's output: + +```jldoctest +julia> 1:10 |> sum |> sqrt +7.416198487095663 +``` + +Here, the total produced by `sum` is passed to the `sqrt` function. The equivalent composition would be: + +```jldoctest +julia> (sqrt ∘ sum)(1:10) +7.416198487095663 +``` + +The pipe operator can also be used with broadcasting, as `.|>`, to provide a useful combination of the chaining/piping and dot vectorization syntax (described next). + +```jldoctest +julia> ["a", "list", "of", "strings"] .|> [uppercase, reverse, titlecase, length] +4-element Array{Any,1}: + "A" + "tsil" + "Of" + 7 +``` ## [Dot Syntax for Vectorizing Functions](@id man-vectorized) diff --git a/codex/manual/performance-tips.md b/codex/manual/performance-tips.md index b5d0eec..71a5234 100644 --- a/codex/manual/performance-tips.md +++ b/codex/manual/performance-tips.md @@ -1362,29 +1362,21 @@ julia> @noinline pos(x) = x < 0 ? 0 : x; julia> function f(x) y = pos(x) - sin(y*x + 1) + return sin(y*x + 1) end; julia> @code_warntype f(3.2) +Variables + #self#::Core.Compiler.Const(f, false) + x::Float64 + y::Union{Float64, Int64} + Body::Float64 -2 1 ─ %1 = invoke Main.pos(%%x::Float64)::UNION{FLOAT64, INT64} -3 │ %2 = isa(%1, Float64)::Bool - └── goto 3 if not %2 - 2 ─ %4 = π (%1, Float64) - │ %5 = Base.mul_float(%4, %%x)::Float64 - └── goto 6 - 3 ─ %7 = isa(%1, Int64)::Bool - └── goto 5 if not %7 - 4 ─ %9 = π (%1, Int64) - │ %10 = Base.sitofp(Float64, %9)::Float64 - │ %11 = Base.mul_float(%10, %%x)::Float64 - └── goto 6 - 5 ─ Base.error("fatal error in type inference (type bound)") - └── unreachable - 6 ┄ %15 = φ (2 => %5, 4 => %11)::Float64 - │ %16 = Base.add_float(%15, 1.0)::Float64 - │ %17 = invoke Main.sin(%16::Float64)::Float64 - └── return %17 +1 ─ (y = Main.pos(x)) +│ %2 = (y * x)::Float64 +│ %3 = (%2 + 1)::Float64 +│ %4 = Main.sin(%3)::Float64 +└── return %4 ``` Interpreting the output of [`@code_warntype`](@ref), like that of its cousins [`@code_lowered`](@ref), diff --git a/src/NEWS.md b/src/NEWS.md index 3c6eab8..ef2b09a 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -15,7 +15,7 @@ Multi-threading changes Language changes ---------------- - +* Empty entries in `JULIA_DEPOT_PATH` are now expanded to default depot entries ([#31009](https://github.com/JuliaLang/julia/issues/31009)). * `Enum` now behaves like a scalar when used in broadcasting ([#30670](https://github.com/JuliaLang/julia/issues/30670)). Command-line option changes @@ -38,6 +38,7 @@ Standard library changes * `hasmethod` can now check for matching keyword argument names ([#30712](https://github.com/JuliaLang/julia/issues/30712)). * `startswith` and `endswith` now accept a `Regex` for the second argument ([#29790](https://github.com/JuliaLang/julia/issues/29790)). * `retry` supports arbitrary callable objects ([#30382](https://github.com/JuliaLang/julia/issues/30382)). +* A no-argument construct to `Ptr{T}` has been added which constructs a null pointer ([#30919](https://github.com/JuliaLang/julia/issues/30919)) #### LinearAlgebra diff --git a/src/base/constants.md b/src/base/constants.md index 0893c3a..4ba0e62 100644 --- a/src/base/constants.md +++ b/src/base/constants.md @@ -6,6 +6,7 @@ Base.PROGRAM_FILE Base.ARGS Base.C_NULL Base.VERSION +Base.DEPOT_PATH Base.LOAD_PATH Base.Sys.BINDIR Base.Sys.CPU_THREADS diff --git a/src/devdocs/ast.md b/src/devdocs/ast.md index 2b27c94..b2593f9 100644 --- a/src/devdocs/ast.md +++ b/src/devdocs/ast.md @@ -239,7 +239,8 @@ Lowered form (IR) is more important to the compiler, since it is used for type i optimizations like inlining, and and code generation. It is also less obvious to the human, since it results from a significant rearrangement of the input syntax. -The following data types exist in lowered form: +In addition to `Symbol`s and some number types, the following data +types exist in lowered form: * `Expr` @@ -316,7 +317,7 @@ These symbols appear in the `head` field of [`Expr`](@ref)s in lowered form. Adds a method to a generic function and assigns the result if necessary. - Has a 1-argument form and a 4-argument form. The 1-argument form arises from the syntax `function foo end`. + Has a 1-argument form and a 3-argument form. The 1-argument form arises from the syntax `function foo end`. In the 1-argument form, the argument is a symbol. If this symbol already names a function in the current scope, nothing happens. If the symbol is undefined, a new function is created and assigned to the identifier specified by the symbol. If the symbol is defined but names a non-function, @@ -325,7 +326,7 @@ These symbols appear in the `head` field of [`Expr`](@ref)s in lowered form. type uniquely identifies the type to add the method to. When the type has fields, it wouldn't be clear whether the method was being added to the instance or its type. - The 4-argument form has the following arguments: + The 3-argument form has the following arguments: * `args[1]` @@ -345,9 +346,55 @@ These symbols appear in the `head` field of [`Expr`](@ref)s in lowered form. method to a function that also has methods defined in different scopes) this is an expression that evaluates to a `:lambda` expression. + * `struct_type` + + A 7-argument expression that defines a new `struct`: + + * `args[1]` + + The name of the `struct` + + * `args[2]` + + A `call` expression that creates `SimpleVector` specifying its parameters + + * `args[3]` + + A `call` expression that creates `SimpleVector` specifying its fieldnames + * `args[4]` - `true` or `false`, identifying whether the method is staged (`@generated function`). + A `Symbol` or `GlobalRef` specifying the supertype (e.g., `:Integer` or + `GlobalRef(Core, :Any)`) + + * `args[5]` + + A `call` expression that creates `SimpleVector` specifying its fieldtypes + + * `args[6]` + + A Bool, true if `mutable` + + * `args[7]` + + The number of arguments to initialize. This will be the number + of fields, or the minimum number of fields called by an inner + constructor's `new` statement. + + * `abstract_type` + + A 3-argument expression that defines a new abstract type. The + arguments are the same as the first three arguments of + `struct_type` expressions. + + * `primitive_type` + + A 4-argument expression that defines a new primitive type. Arguments 1, 2, and 4 + are the same as `struct_type`. Argument 3 is the number of bits. + + * `global` + + Declares a global binding. * `const` @@ -368,6 +415,11 @@ These symbols appear in the `head` field of [`Expr`](@ref)s in lowered form. Returns its argument as the value of the enclosing function. + * `isdefined` + + `Expr(:isdefined, :x)` returns a Bool indicating whether `x` has + already been defined in the current scope. + * `the_exception` Yields the caught exception inside a `catch` block, as returned by `jl_current_exception()`. @@ -400,6 +452,10 @@ These symbols appear in the `head` field of [`Expr`](@ref)s in lowered form. Has the value `false` if inlined into a section of code marked with `@inbounds`, otherwise has the value `true`. + * `simdloop` + + Marks the end of the inner loop of a `@simd` expression. + * `copyast` Part of the implementation of quasi-quote. The argument is a surface syntax AST that is simply diff --git a/src/devdocs/sysimg.md b/src/devdocs/sysimg.md index 8010df8..aa0da76 100644 --- a/src/devdocs/sysimg.md +++ b/src/devdocs/sysimg.md @@ -65,7 +65,7 @@ Additionally, a few special features are supported to control the function cloni 4. `min_size` - This cause the function for the targe to be optimize for size that might have + This causes the function for the target to be optimized for size that might have a significant runtime performance impact. This corresponds to `-Oz` Clang option. As an example, at the time of this writing, the following string is used in the creation of diff --git a/src/manual/environment-variables.md b/src/manual/environment-variables.md index 3deef38..0f84f78 100644 --- a/src/manual/environment-variables.md +++ b/src/manual/environment-variables.md @@ -91,12 +91,13 @@ the chapter on [Code Loading](@ref). The `JULIA_LOAD_PATH` environment variable is used to populate the global Julia [`LOAD_PATH`](@ref) variable, which determines which packages can be loaded via -`import` and `using` (see [Code Loading](@ref)). Unlike the shell `PATH` variable, -empty entries in `JULIA_LOAD_PATH` are expanded to the default value of `LOAD_PATH`, -`["@", "@v#.#", "@stdlib"]` when populating `LOAD_PATH`. This allows easy appending, -prepending, etc. of the load path value in shell scripts regardless of whether -`JULIA_LOAD_PATH` is already set or not. For example, to prepend the directory -`/foo/bar` to `LOAD_PATH` just do +`import` and `using` (see [Code Loading](@ref)). + +Unlike the shell `PATH` variable, empty entries in `JULIA_LOAD_PATH` are expanded to +the default value of `LOAD_PATH`, `["@", "@v#.#", "@stdlib"]` when populating +`LOAD_PATH`. This allows easy appending, prepending, etc. of the load path value in +shell scripts regardless of whether `JULIA_LOAD_PATH` is already set or not. For +example, to prepend the directory `/foo/bar` to `LOAD_PATH` just do ```sh export JULIA_LOAD_PATH="/foo/bar:$JULIA_LOAD_PATH" ``` @@ -110,6 +111,32 @@ This behavior was chosen so that it would be possible to set an empty load path the environment variable. If you want the default load path, either unset the environment variable or if it must have a value, set it to the string `:`. +### `JULIA_DEPOT_PATH` + +The `JULIA_DEPOT_PATH` environment variable is used to populate the global Julia +[`DEPOT_PATH`](@ref) variable, which controls where the package manager, as well +as Julia's code loading mechanisms, look for package registries, installed +packages, named environments, repo clones, cached compiled package images, and +configuration files. + +Unlike the shell `PATH` variable but similar to `JULIA_LOAD_PATH`, empty entries in +`JULIA_DEPOT_PATH` are expanded to the default value of `DEPOT_PATH`. This allows +easy appending, prepending, etc. of the depot path value in shell scripts regardless +of whether `JULIA_DEPOT_PATH` is already set or not. For example, to prepend the +directory `/foo/bar` to `DEPOT_PATH` just do +```sh +export JULIA_DEPOT_PATH="/foo/bar:$JULIA_DEPOT_PATH" +``` +If the `JULIA_DEPOT_PATH` environment variable is already set, its old value will be +prepended with `/foo/bar`. On the other hand, if `JULIA_DEPOT_PATH` is not set, then +it will be set to `/foo/bar:` which will have the effect of prepending `/foo/bar` to +the default depot path. If `JULIA_DEPOT_PATH` is set to the empty string, it expands +to an empty `DEPOT_PATH` array. In other words, the empty string is interpreted as a +zero-element array, not a one-element array of the empty string. This behavior was +chosen so that it would be possible to set an empty depot path via the environment +variable. If you want the default depot path, either unset the environment variable +or if it must have a value, set it to the string `:`. + ### `JULIA_HISTORY` The absolute path `REPL.find_hist_file()` of the REPL's history file. If @@ -128,25 +155,9 @@ by default `1`, and larger values correspond to larger amounts of time. Suppose the value of `$JULIA_PKGRESOLVE_ACCURACY` is `n`. Then -* the number of pre-decimation iterations is `20*n`, -* the number of iterations between decimation steps is `10*n`, and -* at decimation steps, at most one in every `20*n` packages is decimated. - -### `JULIA_DEPOT_PATH` - -A stack of depot locations where the package manager, as well as Julia's code loading -mechanisms, look for package registries, installed packages, named environments, -repo clones, cached compiled package images, and configuration files. - -The depot path is controlled by Julia's `DEPOT_PATH` global variable which is populated at -startup based on the value of the `JULIA_DEPOT_PATH` environment variable. The first entry -is the “user depot” and should be writable by and owned by the current user. The user depot -is where: registries are cloned, new package versions are installed, named environments are -created and updated, package repos are cloned, newly compiled package image files are -saved, log files are written, development packages are checked out by default, and global -configuration data is saved. Later entries in the depot path are treated as read-only and -are appropriate for registries, packages, etc. installed and managed by system -administrators. +* the number of pre-decimation iterations is `20*n`, +* the number of iterations between decimation steps is `10*n`, and +* at decimation steps, at most one in every `20*n` packages is decimated. ## External applications diff --git a/src/manual/functions.md b/src/manual/functions.md index 5e9ec95..1c68f08 100644 --- a/src/manual/functions.md +++ b/src/manual/functions.md @@ -660,6 +660,61 @@ enclosing scope. For example, the variable `data` in the above example of `open...do` is captured from the outer scope. Captured variables can create performance challenges as discussed in [performance tips](@ref man-performance-tips). +## Function composition and piping + +Functions in Julia can be combined by composing or piping (chaining) them together. + +Function composition is when you combine functions together and apply the resulting composition to arguments. +You use the function composition operator (`∘`) to compose the functions, so `(f ∘ g)(args...)` is the same as `f(g(args...))`. + +You can type the composition operator at the REPL and suitably-configured editors using `\circ`. + +For example, the `sqrt` and `+` functions can be composed like this: + +```jldoctest +julia> (sqrt ∘ +)(3, 6) +3.0 +``` + +This adds the numbers first, then finds the square root of the result. + +The next example composes three functions and maps the result over an array of strings: + +```jldoctest +julia> map(first ∘ reverse ∘ uppercase, split("you can compose functions like this")) +6-element Array{Char,1}: + 'U' + 'N' + 'E' + 'S' + 'E' + 'S' +``` + +Function chaining (sometimes called "piping" or "using a pipe" to send data to a subsequent function) is when you apply a function to the previous function's output: + +```jldoctest +julia> 1:10 |> sum |> sqrt +7.416198487095663 +``` + +Here, the total produced by `sum` is passed to the `sqrt` function. The equivalent composition would be: + +```jldoctest +julia> (sqrt ∘ sum)(1:10) +7.416198487095663 +``` + +The pipe operator can also be used with broadcasting, as `.|>`, to provide a useful combination of the chaining/piping and dot vectorization syntax (described next). + +```jldoctest +julia> ["a", "list", "of", "strings"] .|> [uppercase, reverse, titlecase, length] +4-element Array{Any,1}: + "A" + "tsil" + "Of" + 7 +``` ## [Dot Syntax for Vectorizing Functions](@id man-vectorized) diff --git a/src/manual/performance-tips.md b/src/manual/performance-tips.md index b5d0eec..71a5234 100644 --- a/src/manual/performance-tips.md +++ b/src/manual/performance-tips.md @@ -1362,29 +1362,21 @@ julia> @noinline pos(x) = x < 0 ? 0 : x; julia> function f(x) y = pos(x) - sin(y*x + 1) + return sin(y*x + 1) end; julia> @code_warntype f(3.2) +Variables + #self#::Core.Compiler.Const(f, false) + x::Float64 + y::Union{Float64, Int64} + Body::Float64 -2 1 ─ %1 = invoke Main.pos(%%x::Float64)::UNION{FLOAT64, INT64} -3 │ %2 = isa(%1, Float64)::Bool - └── goto 3 if not %2 - 2 ─ %4 = π (%1, Float64) - │ %5 = Base.mul_float(%4, %%x)::Float64 - └── goto 6 - 3 ─ %7 = isa(%1, Int64)::Bool - └── goto 5 if not %7 - 4 ─ %9 = π (%1, Int64) - │ %10 = Base.sitofp(Float64, %9)::Float64 - │ %11 = Base.mul_float(%10, %%x)::Float64 - └── goto 6 - 5 ─ Base.error("fatal error in type inference (type bound)") - └── unreachable - 6 ┄ %15 = φ (2 => %5, 4 => %11)::Float64 - │ %16 = Base.add_float(%15, 1.0)::Float64 - │ %17 = invoke Main.sin(%16::Float64)::Float64 - └── return %17 +1 ─ (y = Main.pos(x)) +│ %2 = (y * x)::Float64 +│ %3 = (%2 + 1)::Float64 +│ %4 = Main.sin(%3)::Float64 +└── return %4 ``` Interpreting the output of [`@code_warntype`](@ref), like that of its cousins [`@code_lowered`](@ref), From 083e5b415b46f47ef24a38b1a3223fc470053917 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Sat, 23 Feb 2019 14:00:15 +0900 Subject: [PATCH 100/153] update Julia 1.2.0-DEV.364 (2019-02-22) Commit 33795c8317 --- codex/NEWS.md | 5 +++ codex/manual/conversion-and-promotion.md | 14 ++++---- codex/manual/missing.md | 44 ++++++++++++++++++++---- codex/manual/modules.md | 36 +++++++++---------- src/NEWS.md | 5 +++ src/manual/conversion-and-promotion.md | 14 ++++---- src/manual/missing.md | 44 ++++++++++++++++++++---- src/manual/modules.md | 36 +++++++++---------- 8 files changed, 136 insertions(+), 62 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index ef2b09a..5dc3808 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -7,6 +7,11 @@ New language features * Argument splatting (`x...`) can now be used in calls to the `new` pseudo-function in constructors ([#30577](https://github.com/JuliaLang/julia/issues/30577)). + * Objects created by calling `skipmissing` on an array can now be indexed using indices + from the parent at non-missing positions. This allows functions such as + `findall`, `findfirst`, `argmin`/`argmax` and `findmin`/`findmax` to work with these + objects, returning the index of matching non-missing elements in the parent ([#31008](https://github.com/JuliaLang/julia/issues/31008)). + Multi-threading changes ----------------------- diff --git a/codex/manual/conversion-and-promotion.md b/codex/manual/conversion-and-promotion.md index a193100..baf2314 100644 --- a/codex/manual/conversion-and-promotion.md +++ b/codex/manual/conversion-and-promotion.md @@ -47,7 +47,7 @@ without the programmer asking for it explicitly. One example is assigning a value into an array: if `A` is a `Vector{Float64}`, the expression `A[1] = 2` should work by automatically converting the `2` from `Int` to `Float64`, and storing the result in the array. -This is done via the `convert` function. +This is done via the [`convert`](@ref) function. The `convert` function generally takes two arguments: the first is a type object and the second is a value to convert to that type. The returned value is the value converted to an instance of given type. @@ -95,7 +95,7 @@ ERROR: MethodError: Cannot `convert` an object of type String to an object of ty Some languages consider parsing strings as numbers or formatting numbers as strings to be conversions (many dynamic languages will even perform conversion for you automatically), however Julia does not: even though some strings can be parsed as numbers, most strings are not valid representations -of numbers, and only a very limited subset of them are. Therefore in Julia the dedicated `parse` +of numbers, and only a very limited subset of them are. Therefore in Julia the dedicated [`parse`](@ref) function must be used to perform this operation, making it more explicit. ### When is `convert` called? @@ -104,10 +104,10 @@ The following language constructs call `convert`: * Assigning to an array converts to the array's element type. * Assigning to a field of an object converts to the declared type of the field. - * Constructing an object with `new` converts to the object's declared field types. + * Constructing an object with [`new`](@ref) converts to the object's declared field types. * Assigning to a variable with a declared type (e.g. `local x::T`) converts to that type. * A function with a declared return type converts its return value to that type. - * Passing a value to `ccall` converts it to the corresponding argument type. + * Passing a value to [`ccall`](@ref) converts it to the corresponding argument type. ### Conversion vs. Construction @@ -208,7 +208,7 @@ do with the type hierarchy, and everything to do with converting between alterna For instance, although every [`Int32`](@ref) value can also be represented as a [`Float64`](@ref) value, `Int32` is not a subtype of `Float64`. -Promotion to a common "greater" type is performed in Julia by the `promote` function, which takes +Promotion to a common "greater" type is performed in Julia by the [`promote`](@ref) function, which takes any number of arguments, and returns a tuple of the same number of values, converted to a common type, or throws an exception if promotion is not possible. The most common use case for promotion is to convert numeric arguments to a common type: @@ -286,7 +286,7 @@ can be convenient to do promotion automatically. Although one could, in principle, define methods for the `promote` function directly, this would require many redundant definitions for all possible permutations of argument types. Instead, the -behavior of `promote` is defined in terms of an auxiliary function called `promote_rule`, which +behavior of `promote` is defined in terms of an auxiliary function called [`promote_rule`](@ref), which one can provide methods for. The `promote_rule` function takes a pair of type objects and returns another type object, such that instances of the argument types will be promoted to the returned type. Thus, by defining the rule: @@ -310,7 +310,7 @@ one does not need to define both `promote_rule(::Type{A}, ::Type{B})` and `promote_rule(::Type{B}, ::Type{A})` -- the symmetry is implied by the way `promote_rule` is used in the promotion process. -The `promote_rule` function is used as a building block to define a second function called `promote_type`, +The `promote_rule` function is used as a building block to define a second function called [`promote_type`](@ref), which, given any number of type objects, returns the common type to which those values, as arguments to `promote` should be promoted. Thus, if one wants to know, in absence of actual values, what type a collection of values of certain types would promote to, one can use `promote_type`: diff --git a/codex/manual/missing.md b/codex/manual/missing.md index 647434f..fbe7068 100644 --- a/codex/manual/missing.md +++ b/codex/manual/missing.md @@ -294,20 +294,52 @@ julia> sum(skipmissing([1, missing])) This convenience function returns an iterator which filters out `missing` values efficiently. It can therefore be used with any function which supports iterators -```jldoctest; setup = :(using Statistics) -julia> maximum(skipmissing([3, missing, 2, 1])) +```jldoctest skipmissing; setup = :(using Statistics) +julia> x = skipmissing([3, missing, 2, 1]) +Base.SkipMissing{Array{Union{Missing, Int64},1}}(Union{Missing, Int64}[3, missing, 2, 1]) + +julia> maximum(x) 3 -julia> mean(skipmissing([3, missing, 2, 1])) +julia> mean(x) 2.0 -julia> mapreduce(sqrt, +, skipmissing([3, missing, 2, 1])) +julia> mapreduce(sqrt, +, x) 4.146264369941973 ``` +Objects created by calling `skipmissing` on an array can be indexed using indices +from the parent array. Indices corresponding to missing values are not valid for +these objects and an error is thrown when trying to use them (they are also skipped +by `keys` and `eachindex`) +```jldoctest skipmissing +julia> x[1] +3 + +julia> x[2] +ERROR: MissingException: the value at index (2,) is missing +[...] +``` + +This allows functions which operate on indices to work in combination with `skipmissing`. +This is notably the case for search and find functions, which return indices +valid for the object returned by `skipmissing` which are also the indices of the +matching entries *in the parent array* +```jldoctest skipmissing +julia> findall(==(1), x) +1-element Array{Int64,1}: + 4 + +julia> findfirst(!iszero, x) +1 + +julia> argmax(x) +1 +``` + Use [`collect`](@ref) to extract non-`missing` values and store them in an array -```jldoctest -julia> collect(skipmissing([3, missing, 2, 1])) +```jldoctest skipmissing +julia> collect(x) 3-element Array{Int64,1}: 3 2 diff --git a/codex/manual/modules.md b/codex/manual/modules.md index 62a509e..16ebfdb 100644 --- a/codex/manual/modules.md +++ b/codex/manual/modules.md @@ -46,11 +46,11 @@ The statement `using BigLib: thing1, thing2` brings just the identifiers `thing1 into scope from module `BigLib`. If these names refer to functions, adding methods to them will not be allowed (you may only "use" them, not extend them). -The `import` keyword supports the same syntax as `using`, but only operates on a single name +The [`import`](@ref) keyword supports the same syntax as [`using`](@ref), but only operates on a single name at a time. It does not add modules to be searched the way `using` does. `import` also differs from `using` in that functions imported using `import` can be extended with new methods. -In `MyModule` above we wanted to add a method to the standard `show` function, so we had to write +In `MyModule` above we wanted to add a method to the standard [`show`](@ref) function, so we had to write `import Base.show`. Functions whose names are only visible via `using` cannot be extended. Once a variable is made visible via `using` or `import`, a module may not create its own variable @@ -117,25 +117,25 @@ end ### Standard modules -There are three important standard modules: Main, Core, and Base. +There are three important standard modules: `Main`, `Core`, and `Base`. -Main is the top-level module, and Julia starts with Main set as the current module. Variables -defined at the prompt go in Main, and `varinfo()` lists variables in Main. +`Main` is the top-level module, and Julia starts with `Main` set as the current module. Variables +defined at the prompt go in `Main`, and [`varinfo()`](@ref) lists variables in `Main`. -Core contains all identifiers considered "built in" to the language, i.e. part of the core language +`Core` contains all identifiers considered "built in" to the language, i.e. part of the core language and not libraries. Every module implicitly specifies `using Core`, since you can't do anything without those definitions. -Base is a module that contains basic functionality (the contents of base/). All modules implicitly contain `using Base`, +`Base` is a module that contains basic functionality (the contents of `base/`). All modules implicitly contain `using Base`, since this is needed in the vast majority of cases. ### Default top-level definitions and bare modules In addition to `using Base`, modules also automatically contain -definitions of the `eval` and `include` functions, +definitions of the [`eval`](@ref) and [`include`](@ref) functions, which evaluate expressions/files within the global scope of that module. -If these default definitions are not wanted, modules can be defined using the keyword `baremodule` +If these default definitions are not wanted, modules can be defined using the keyword [`baremodule`](@ref) instead (note: `Core` is still imported, as per above). In terms of `baremodule`, a standard `module` looks like this: @@ -209,10 +209,10 @@ Julia creates precompiled caches of the module to reduce this time. The incremental precompiled module file are created and used automatically when using `import` or `using` to load a module. This will cause it to be automatically compiled the first time -it is imported. Alternatively, you can manually call `Base.compilecache(modulename)`. The resulting +it is imported. Alternatively, you can manually call [`Base.compilecache(modulename)`](@ref). The resulting cache files will be stored in `DEPOT_PATH[1]/compiled/`. Subsequently, the module is automatically recompiled upon `using` or `import` whenever any of its dependencies change; dependencies are modules it -imports, the Julia build, files it includes, or explicit dependencies declared by `include_dependency(path)` +imports, the Julia build, files it includes, or explicit dependencies declared by [`include_dependency(path)`](@ref) in the module file(s). For file dependencies, a change is determined by examining whether the modification time (mtime) @@ -275,12 +275,12 @@ we can ensure that the type is known to the compiler and allow it to generate be code. Obviously, any other globals in your module that depends on `foo_data_ptr` would also have to be initialized in `__init__`. -Constants involving most Julia objects that are not produced by `ccall` do not need to be placed +Constants involving most Julia objects that are not produced by [`ccall`](@ref) do not need to be placed in `__init__`: their definitions can be precompiled and loaded from the cached module image. This includes complicated heap-allocated objects like arrays. However, any routine that returns a raw -pointer value must be called at runtime for precompilation to work (Ptr objects will turn into -null pointers unless they are hidden inside an isbits object). This includes the return values -of the Julia functions `cfunction` and `pointer`. +pointer value must be called at runtime for precompilation to work ([`Ptr`](@ref) objects will turn into +null pointers unless they are hidden inside an [`isbits`](@ref) object). This includes the return values +of the Julia functions `cfunction` and [`pointer`](@ref). Dictionary and set types, or in general anything that depends on the output of a `hash(key)` method, are a trickier case. In the common case where the keys are numbers, strings, symbols, ranges, @@ -289,7 +289,7 @@ precompile. However, for a few other key types, such as `Function` or `DataType user-defined types where you haven't defined a `hash` method, the fallback `hash` method depends on the memory address of the object (via its `objectid`) and hence may change from run to run. If you have one of these key types, or if you aren't sure, to be safe you can initialize this -dictionary from within your `__init__` function. Alternatively, you can use the `IdDict` +dictionary from within your `__init__` function. Alternatively, you can use the [`IdDict`](@ref) dictionary type, which is specially handled by precompilation so that it is safe to initialize at compile-time. @@ -300,7 +300,7 @@ that also generates compiled code. Other known potential failure scenarios include: -1. Global counters (for example, for attempting to uniquely identify objects) Consider the following +1. Global counters (for example, for attempting to uniquely identify objects). Consider the following code snippet: ```julia @@ -349,7 +349,7 @@ code to help the user avoid other wrong-behavior situations: 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`), and no cleanup is done after `Pkg.rm` 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__`](@ref)/`source_path()` diff --git a/src/NEWS.md b/src/NEWS.md index ef2b09a..5dc3808 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -7,6 +7,11 @@ New language features * Argument splatting (`x...`) can now be used in calls to the `new` pseudo-function in constructors ([#30577](https://github.com/JuliaLang/julia/issues/30577)). + * Objects created by calling `skipmissing` on an array can now be indexed using indices + from the parent at non-missing positions. This allows functions such as + `findall`, `findfirst`, `argmin`/`argmax` and `findmin`/`findmax` to work with these + objects, returning the index of matching non-missing elements in the parent ([#31008](https://github.com/JuliaLang/julia/issues/31008)). + Multi-threading changes ----------------------- diff --git a/src/manual/conversion-and-promotion.md b/src/manual/conversion-and-promotion.md index a193100..baf2314 100644 --- a/src/manual/conversion-and-promotion.md +++ b/src/manual/conversion-and-promotion.md @@ -47,7 +47,7 @@ without the programmer asking for it explicitly. One example is assigning a value into an array: if `A` is a `Vector{Float64}`, the expression `A[1] = 2` should work by automatically converting the `2` from `Int` to `Float64`, and storing the result in the array. -This is done via the `convert` function. +This is done via the [`convert`](@ref) function. The `convert` function generally takes two arguments: the first is a type object and the second is a value to convert to that type. The returned value is the value converted to an instance of given type. @@ -95,7 +95,7 @@ ERROR: MethodError: Cannot `convert` an object of type String to an object of ty Some languages consider parsing strings as numbers or formatting numbers as strings to be conversions (many dynamic languages will even perform conversion for you automatically), however Julia does not: even though some strings can be parsed as numbers, most strings are not valid representations -of numbers, and only a very limited subset of them are. Therefore in Julia the dedicated `parse` +of numbers, and only a very limited subset of them are. Therefore in Julia the dedicated [`parse`](@ref) function must be used to perform this operation, making it more explicit. ### When is `convert` called? @@ -104,10 +104,10 @@ The following language constructs call `convert`: * Assigning to an array converts to the array's element type. * Assigning to a field of an object converts to the declared type of the field. - * Constructing an object with `new` converts to the object's declared field types. + * Constructing an object with [`new`](@ref) converts to the object's declared field types. * Assigning to a variable with a declared type (e.g. `local x::T`) converts to that type. * A function with a declared return type converts its return value to that type. - * Passing a value to `ccall` converts it to the corresponding argument type. + * Passing a value to [`ccall`](@ref) converts it to the corresponding argument type. ### Conversion vs. Construction @@ -208,7 +208,7 @@ do with the type hierarchy, and everything to do with converting between alterna For instance, although every [`Int32`](@ref) value can also be represented as a [`Float64`](@ref) value, `Int32` is not a subtype of `Float64`. -Promotion to a common "greater" type is performed in Julia by the `promote` function, which takes +Promotion to a common "greater" type is performed in Julia by the [`promote`](@ref) function, which takes any number of arguments, and returns a tuple of the same number of values, converted to a common type, or throws an exception if promotion is not possible. The most common use case for promotion is to convert numeric arguments to a common type: @@ -286,7 +286,7 @@ can be convenient to do promotion automatically. Although one could, in principle, define methods for the `promote` function directly, this would require many redundant definitions for all possible permutations of argument types. Instead, the -behavior of `promote` is defined in terms of an auxiliary function called `promote_rule`, which +behavior of `promote` is defined in terms of an auxiliary function called [`promote_rule`](@ref), which one can provide methods for. The `promote_rule` function takes a pair of type objects and returns another type object, such that instances of the argument types will be promoted to the returned type. Thus, by defining the rule: @@ -310,7 +310,7 @@ one does not need to define both `promote_rule(::Type{A}, ::Type{B})` and `promote_rule(::Type{B}, ::Type{A})` -- the symmetry is implied by the way `promote_rule` is used in the promotion process. -The `promote_rule` function is used as a building block to define a second function called `promote_type`, +The `promote_rule` function is used as a building block to define a second function called [`promote_type`](@ref), which, given any number of type objects, returns the common type to which those values, as arguments to `promote` should be promoted. Thus, if one wants to know, in absence of actual values, what type a collection of values of certain types would promote to, one can use `promote_type`: diff --git a/src/manual/missing.md b/src/manual/missing.md index 647434f..fbe7068 100644 --- a/src/manual/missing.md +++ b/src/manual/missing.md @@ -294,20 +294,52 @@ julia> sum(skipmissing([1, missing])) This convenience function returns an iterator which filters out `missing` values efficiently. It can therefore be used with any function which supports iterators -```jldoctest; setup = :(using Statistics) -julia> maximum(skipmissing([3, missing, 2, 1])) +```jldoctest skipmissing; setup = :(using Statistics) +julia> x = skipmissing([3, missing, 2, 1]) +Base.SkipMissing{Array{Union{Missing, Int64},1}}(Union{Missing, Int64}[3, missing, 2, 1]) + +julia> maximum(x) 3 -julia> mean(skipmissing([3, missing, 2, 1])) +julia> mean(x) 2.0 -julia> mapreduce(sqrt, +, skipmissing([3, missing, 2, 1])) +julia> mapreduce(sqrt, +, x) 4.146264369941973 ``` +Objects created by calling `skipmissing` on an array can be indexed using indices +from the parent array. Indices corresponding to missing values are not valid for +these objects and an error is thrown when trying to use them (they are also skipped +by `keys` and `eachindex`) +```jldoctest skipmissing +julia> x[1] +3 + +julia> x[2] +ERROR: MissingException: the value at index (2,) is missing +[...] +``` + +This allows functions which operate on indices to work in combination with `skipmissing`. +This is notably the case for search and find functions, which return indices +valid for the object returned by `skipmissing` which are also the indices of the +matching entries *in the parent array* +```jldoctest skipmissing +julia> findall(==(1), x) +1-element Array{Int64,1}: + 4 + +julia> findfirst(!iszero, x) +1 + +julia> argmax(x) +1 +``` + Use [`collect`](@ref) to extract non-`missing` values and store them in an array -```jldoctest -julia> collect(skipmissing([3, missing, 2, 1])) +```jldoctest skipmissing +julia> collect(x) 3-element Array{Int64,1}: 3 2 diff --git a/src/manual/modules.md b/src/manual/modules.md index 62a509e..16ebfdb 100644 --- a/src/manual/modules.md +++ b/src/manual/modules.md @@ -46,11 +46,11 @@ The statement `using BigLib: thing1, thing2` brings just the identifiers `thing1 into scope from module `BigLib`. If these names refer to functions, adding methods to them will not be allowed (you may only "use" them, not extend them). -The `import` keyword supports the same syntax as `using`, but only operates on a single name +The [`import`](@ref) keyword supports the same syntax as [`using`](@ref), but only operates on a single name at a time. It does not add modules to be searched the way `using` does. `import` also differs from `using` in that functions imported using `import` can be extended with new methods. -In `MyModule` above we wanted to add a method to the standard `show` function, so we had to write +In `MyModule` above we wanted to add a method to the standard [`show`](@ref) function, so we had to write `import Base.show`. Functions whose names are only visible via `using` cannot be extended. Once a variable is made visible via `using` or `import`, a module may not create its own variable @@ -117,25 +117,25 @@ end ### Standard modules -There are three important standard modules: Main, Core, and Base. +There are three important standard modules: `Main`, `Core`, and `Base`. -Main is the top-level module, and Julia starts with Main set as the current module. Variables -defined at the prompt go in Main, and `varinfo()` lists variables in Main. +`Main` is the top-level module, and Julia starts with `Main` set as the current module. Variables +defined at the prompt go in `Main`, and [`varinfo()`](@ref) lists variables in `Main`. -Core contains all identifiers considered "built in" to the language, i.e. part of the core language +`Core` contains all identifiers considered "built in" to the language, i.e. part of the core language and not libraries. Every module implicitly specifies `using Core`, since you can't do anything without those definitions. -Base is a module that contains basic functionality (the contents of base/). All modules implicitly contain `using Base`, +`Base` is a module that contains basic functionality (the contents of `base/`). All modules implicitly contain `using Base`, since this is needed in the vast majority of cases. ### Default top-level definitions and bare modules In addition to `using Base`, modules also automatically contain -definitions of the `eval` and `include` functions, +definitions of the [`eval`](@ref) and [`include`](@ref) functions, which evaluate expressions/files within the global scope of that module. -If these default definitions are not wanted, modules can be defined using the keyword `baremodule` +If these default definitions are not wanted, modules can be defined using the keyword [`baremodule`](@ref) instead (note: `Core` is still imported, as per above). In terms of `baremodule`, a standard `module` looks like this: @@ -209,10 +209,10 @@ Julia creates precompiled caches of the module to reduce this time. The incremental precompiled module file are created and used automatically when using `import` or `using` to load a module. This will cause it to be automatically compiled the first time -it is imported. Alternatively, you can manually call `Base.compilecache(modulename)`. The resulting +it is imported. Alternatively, you can manually call [`Base.compilecache(modulename)`](@ref). The resulting cache files will be stored in `DEPOT_PATH[1]/compiled/`. Subsequently, the module is automatically recompiled upon `using` or `import` whenever any of its dependencies change; dependencies are modules it -imports, the Julia build, files it includes, or explicit dependencies declared by `include_dependency(path)` +imports, the Julia build, files it includes, or explicit dependencies declared by [`include_dependency(path)`](@ref) in the module file(s). For file dependencies, a change is determined by examining whether the modification time (mtime) @@ -275,12 +275,12 @@ we can ensure that the type is known to the compiler and allow it to generate be code. Obviously, any other globals in your module that depends on `foo_data_ptr` would also have to be initialized in `__init__`. -Constants involving most Julia objects that are not produced by `ccall` do not need to be placed +Constants involving most Julia objects that are not produced by [`ccall`](@ref) do not need to be placed in `__init__`: their definitions can be precompiled and loaded from the cached module image. This includes complicated heap-allocated objects like arrays. However, any routine that returns a raw -pointer value must be called at runtime for precompilation to work (Ptr objects will turn into -null pointers unless they are hidden inside an isbits object). This includes the return values -of the Julia functions `cfunction` and `pointer`. +pointer value must be called at runtime for precompilation to work ([`Ptr`](@ref) objects will turn into +null pointers unless they are hidden inside an [`isbits`](@ref) object). This includes the return values +of the Julia functions `cfunction` and [`pointer`](@ref). Dictionary and set types, or in general anything that depends on the output of a `hash(key)` method, are a trickier case. In the common case where the keys are numbers, strings, symbols, ranges, @@ -289,7 +289,7 @@ precompile. However, for a few other key types, such as `Function` or `DataType user-defined types where you haven't defined a `hash` method, the fallback `hash` method depends on the memory address of the object (via its `objectid`) and hence may change from run to run. If you have one of these key types, or if you aren't sure, to be safe you can initialize this -dictionary from within your `__init__` function. Alternatively, you can use the `IdDict` +dictionary from within your `__init__` function. Alternatively, you can use the [`IdDict`](@ref) dictionary type, which is specially handled by precompilation so that it is safe to initialize at compile-time. @@ -300,7 +300,7 @@ that also generates compiled code. Other known potential failure scenarios include: -1. Global counters (for example, for attempting to uniquely identify objects) Consider the following +1. Global counters (for example, for attempting to uniquely identify objects). Consider the following code snippet: ```julia @@ -349,7 +349,7 @@ code to help the user avoid other wrong-behavior situations: 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`), and no cleanup is done after `Pkg.rm` 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__`](@ref)/`source_path()` From f58a24f699ff46a2f6b06c9ea46f0da3190ff2f9 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Fri, 1 Mar 2019 14:35:10 +0900 Subject: [PATCH 101/153] update Julia 1.2.0-DEV.396 (2019-03-01) Commit 8639dc1dbf --- codex/base/multi-threading.md | 2 +- codex/devdocs/types.md | 16 +++--- codex/manual/metaprogramming.md | 14 ++--- codex/manual/parallel-computing.md | 84 +++++++++++++++--------------- src/base/multi-threading.md | 2 +- src/devdocs/types.md | 16 +++--- src/manual/metaprogramming.md | 14 ++--- src/manual/parallel-computing.md | 84 +++++++++++++++--------------- 8 files changed, 116 insertions(+), 116 deletions(-) diff --git a/codex/base/multi-threading.md b/codex/base/multi-threading.md index 93f36b5..1b58e61 100644 --- a/codex/base/multi-threading.md +++ b/codex/base/multi-threading.md @@ -1,4 +1,4 @@ -# Multi-Threading +# [Multi-Threading](@id lib-multithreading) This experimental interface supports Julia's multi-threading capabilities. Types and functions described here might (and likely will) change in the future. diff --git a/codex/devdocs/types.md b/codex/devdocs/types.md index b795add..d4ea216 100644 --- a/codex/devdocs/types.md +++ b/codex/devdocs/types.md @@ -7,21 +7,21 @@ try to get under the hood, focusing particularly on [Parametric Types](@ref). It's perhaps easiest to conceive of Julia's type system in terms of sets. While programs manipulate individual values, a type refers to a set of values. This is not the same thing as a collection; -for example a `Set` of values is itself a single `Set` value. +for example a [`Set`](@ref) of values is itself a single `Set` value. Rather, a type describes a set of *possible* values, expressing uncertainty about which value we have. -A *concrete* type `T` describes the set of values whose direct tag, as returned by the `typeof` +A *concrete* type `T` describes the set of values whose direct tag, as returned by the [`typeof`](@ref) function, is `T`. An *abstract* type describes some possibly-larger set of values. -`Any` describes the entire universe of possible values. [`Integer`](@ref) is a subset of +[`Any`](@ref) describes the entire universe of possible values. [`Integer`](@ref) is a subset of `Any` that includes `Int`, [`Int8`](@ref), and other concrete types. Internally, Julia also makes heavy use of another type known as `Bottom`, which can also be written as `Union{}`. This corresponds to the empty set. Julia's types support the standard operations of set theory: you can ask whether `T1` is a "subset" -(subtype) of `T2` with `T1 <: T2`. Likewise, you intersect two types using `typeintersect`, take -their union with `Union`, and compute a type that contains their union with `typejoin`: +(subtype) of `T2` with `T1 <: T2`. Likewise, you intersect two types using [`typeintersect`](@ref), take +their union with [`Union`](@ref), and compute a type that contains their union with [`typejoin`](@ref): ```jldoctest julia> typeintersect(Int, Float64) @@ -66,7 +66,7 @@ Julia's type system can also express an *iterated union* of types: a union of ty of some variable. This is needed to describe parametric types where the values of some parameters are not known. -For example, :obj:`Array` has two parameters as in `Array{Int,2}`. If we did not know the element +For example, [`Array`](@ref) has two parameters as in `Array{Int,2}`. If we did not know the element type, we could write `Array{T,2} where T`, which is the union of `Array{T,2}` for all values of `T`: `Union{Array{Int8,2}, Array{Int16,2}, ...}`. @@ -365,7 +365,7 @@ f(a::Array{T}, x::T, y::T) where {T} = ... In this case, `T` occurs in invariant position inside `Array{T}`. That means whatever type of array is passed unambiguously determines -the value of `T` --- we say `T` has an *equality constraint* on it. +the value of `T` -- we say `T` has an *equality constraint* on it. Therefore in this case the diagonal rule is not really necessary, since the array determines `T` and we can then allow `x` and `y` to be of any subtypes of `T`. @@ -388,7 +388,7 @@ f(x::Union{Nothing,T}, y::T) where {T} = ... ``` Consider what this declaration means. -`y` has type `T`. `x` then can have either the same type `T`, or else be of type `Nothing`. +`y` has type `T`. `x` then can have either the same type `T`, or else be of type [`Nothing`](@ref). So all of the following calls should match: ```julia diff --git a/codex/manual/metaprogramming.md b/codex/manual/metaprogramming.md index a1c0722..fcfe422 100644 --- a/codex/manual/metaprogramming.md +++ b/codex/manual/metaprogramming.md @@ -35,7 +35,7 @@ Expr `Expr` objects contain two parts: - * a `Symbol` identifying the kind of expression. A symbol is an [interned string](https://en.wikipedia.org/wiki/String_interning) + * a [`Symbol`](@ref) identifying the kind of expression. A symbol is an [interned string](https://en.wikipedia.org/wiki/String_interning) identifier (more discussion below). ```jldoctest prog @@ -129,7 +129,7 @@ julia> Symbol(:var,'_',"sym") In the context of an expression, symbols are used to indicate access to variables; when an expression is evaluated, a symbol is replaced with the value bound to that symbol in the appropriate [scope](@ref scope-of-variables). -Sometimes extra parentheses around the argument to `:` are needed to avoid ambiguity in parsing.: +Sometimes extra parentheses around the argument to `:` are needed to avoid ambiguity in parsing: ```jldoctest julia> :(:) @@ -613,7 +613,7 @@ The argument `__source__` provides information (in the form of a `LineNumberNode of the `@` sign from the macro invocation. This allows macros to include better error diagnostic information, and is commonly used by logging, string-parser macros, and docs, for example, -as well as to implement the `@__LINE__`, `@__FILE__`, and `@__DIR__` macros. +as well as to implement the [`@__LINE__`](@ref), [`@__FILE__`](@ref), and [`@__DIR__`](@ref) macros. The location information can be accessed by referencing `__source__.line` and `__source__.file`: @@ -638,7 +638,7 @@ in the current module. ### Building an advanced macro -Here is a simplified definition of Julia's `@assert` macro: +Here is a simplified definition of Julia's [`@assert`](@ref) macro: ```jldoctest building julia> macro assert(ex) @@ -667,7 +667,7 @@ This is equivalent to writing: That is, in the first call, the expression `:(1 == 1.0)` is spliced into the test condition slot, while the value of `string(:(1 == 1.0))` is spliced into the assertion message slot. The entire expression, thus constructed, is placed into the syntax tree where the `@assert` macro call occurs. -Then at execution time, if the test expression evaluates to true, then `nothing` is returned, +Then at execution time, if the test expression evaluates to true, then [`nothing`](@ref) is returned, whereas if the test is false, an error is raised indicating the asserted expression that was false. Notice that it would not be possible to write this as a function, since only the *value* of the condition is available and it would be impossible to display the expression that computed it in @@ -675,7 +675,7 @@ the error message. The actual definition of `@assert` in Julia Base is more complicated. It allows the user to optionally specify their own error message, instead of just printing the failed expression. -Just like in functions with a variable number of arguments, this is specified with an ellipses +Just like in functions with a variable number of arguments ([Varargs Functions](@ref)), this is specified with an ellipses following the last argument: ```jldoctest assert2 @@ -1094,7 +1094,7 @@ When defining generated functions, there are four main differences to ordinary f 3. Instead of calculating something or performing some action, you return a *quoted expression* which, when evaluated, does what you want. 4. Generated functions must not *mutate* or *observe* any non-constant global state (including, - for example, IO, locks, non-local dictionaries, or using `hasmethod`). + for example, IO, locks, non-local dictionaries, or using [`hasmethod`](@ref)). This means they can only read global constants, and cannot have any side effects. In other words, they must be completely pure. Due to an implementation limitation, this also means that they currently cannot define a closure diff --git a/codex/manual/parallel-computing.md b/codex/manual/parallel-computing.md index f79521b..efa9077 100644 --- a/codex/manual/parallel-computing.md +++ b/codex/manual/parallel-computing.md @@ -12,10 +12,10 @@ Julia also supports communication between `Tasks` through operations like [`wait Communication and data synchronization is managed through [`Channel`](@ref)s, which are the conduits that provide inter-`Tasks` communication. -Julia also supports experimental multi-threading, where execution is forked and an anonymous function is run across all +Julia also supports [experimental multi-threading](@ref man-multithreading), where execution is forked and an anonymous function is run across all threads. Known as the fork-join approach, parallel threads execute independently, and must ultimately be joined in Julia's main thread to allow serial execution to continue. -Multi-threading is supported using the `Base.Threads` module that is still considered experimental, as Julia is +Multi-threading is supported using the [`Base.Threads`](@ref lib-multithreading) module that is still considered experimental, as Julia is not yet fully thread-safe. In particular segfaults seem to occur during I/O operations and task switching. As an up-to-date reference, keep an eye on [the issue tracker](https://github.com/JuliaLang/julia/issues?q=is%3Aopen+is%3Aissue+label%3Amultithreading). Multi-Threading should only be used if you take into consideration global variables, locks and @@ -80,51 +80,51 @@ A channel can be visualized as a pipe, i.e., it has a write end and a read end : @async foo() end ``` -* Channels are created via the `Channel{T}(sz)` constructor. The channel will only hold objects - of type `T`. If the type is not specified, the channel can hold objects of any type. `sz` refers - to the maximum number of elements that can be held in the channel at any time. For example, `Channel(32)` - creates a channel that can hold a maximum of 32 objects of any type. A `Channel{MyType}(64)` can - hold up to 64 objects of `MyType` at any time. -* If a [`Channel`](@ref) is empty, readers (on a [`take!`](@ref) call) will block until data is available. -* If a [`Channel`](@ref) is full, writers (on a [`put!`](@ref) call) will block until space becomes available. -* [`isready`](@ref) tests for the presence of any object in the channel, while [`wait`](@ref) - waits for an object to become available. -* A [`Channel`](@ref) is in an open state initially. This means that it can be read from and written to - freely via [`take!`](@ref) and [`put!`](@ref) calls. [`close`](@ref) closes a [`Channel`](@ref). - On a closed [`Channel`](@ref), [`put!`](@ref) will fail. For example: - -```julia-repl -julia> c = Channel(2); - -julia> put!(c, 1) # `put!` on an open channel succeeds -1 - -julia> close(c); - -julia> put!(c, 2) # `put!` on a closed channel throws an exception. -ERROR: InvalidStateException("Channel is closed.",:closed) -Stacktrace: -[...] -``` + * Channels are created via the `Channel{T}(sz)` constructor. The channel will only hold objects + of type `T`. If the type is not specified, the channel can hold objects of any type. `sz` refers + to the maximum number of elements that can be held in the channel at any time. For example, `Channel(32)` + creates a channel that can hold a maximum of 32 objects of any type. A `Channel{MyType}(64)` can + hold up to 64 objects of `MyType` at any time. + * If a [`Channel`](@ref) is empty, readers (on a [`take!`](@ref) call) will block until data is available. + * If a [`Channel`](@ref) is full, writers (on a [`put!`](@ref) call) will block until space becomes available. + * [`isready`](@ref) tests for the presence of any object in the channel, while [`wait`](@ref) + waits for an object to become available. + * A [`Channel`](@ref) is in an open state initially. This means that it can be read from and written to + freely via [`take!`](@ref) and [`put!`](@ref) calls. [`close`](@ref) closes a [`Channel`](@ref). + On a closed [`Channel`](@ref), [`put!`](@ref) will fail. For example: + + ```julia-repl + julia> c = Channel(2); + + julia> put!(c, 1) # `put!` on an open channel succeeds + 1 + + julia> close(c); + + julia> put!(c, 2) # `put!` on a closed channel throws an exception. + ERROR: InvalidStateException("Channel is closed.",:closed) + Stacktrace: + [...] + ``` * [`take!`](@ref) and [`fetch`](@ref) (which retrieves but does not remove the value) on a closed channel successfully return any existing values until it is emptied. Continuing the above example: -```julia-repl -julia> fetch(c) # Any number of `fetch` calls succeed. -1 + ```julia-repl + julia> fetch(c) # Any number of `fetch` calls succeed. + 1 -julia> fetch(c) -1 + julia> fetch(c) + 1 -julia> take!(c) # The first `take!` removes the value. -1 + julia> take!(c) # The first `take!` removes the value. + 1 -julia> take!(c) # No more data available on a closed channel. -ERROR: InvalidStateException("Channel is closed.",:closed) -Stacktrace: -[...] -``` + julia> take!(c) # No more data available on a closed channel. + ERROR: InvalidStateException("Channel is closed.",:closed) + Stacktrace: + [...] + ``` A `Channel` can be used as an iterable object in a `for` loop, in which case the loop runs as long as the `Channel` has data or is open. The loop variable takes on all values added to the @@ -216,7 +216,7 @@ executed sequentially on a single OS thread. Future versions of Julia may suppor tasks on multiple threads, in which case compute bound tasks will see benefits of parallel execution too. -# Multi-Threading (Experimental) +# [Multi-Threading (Experimental)](@id man-multithreading) In addition to tasks Julia forwards natively supports multi-threading. Note that this section is experimental and the interfaces may change in the future. @@ -638,7 +638,7 @@ the same time. -## Code Availability and Loading Packages +## [Code Availability and Loading Packages](@id code-availability) Your code must be available on any process that runs it. For example, type the following into the Julia prompt: diff --git a/src/base/multi-threading.md b/src/base/multi-threading.md index 93f36b5..1b58e61 100644 --- a/src/base/multi-threading.md +++ b/src/base/multi-threading.md @@ -1,4 +1,4 @@ -# Multi-Threading +# [Multi-Threading](@id lib-multithreading) This experimental interface supports Julia's multi-threading capabilities. Types and functions described here might (and likely will) change in the future. diff --git a/src/devdocs/types.md b/src/devdocs/types.md index b795add..d4ea216 100644 --- a/src/devdocs/types.md +++ b/src/devdocs/types.md @@ -7,21 +7,21 @@ try to get under the hood, focusing particularly on [Parametric Types](@ref). It's perhaps easiest to conceive of Julia's type system in terms of sets. While programs manipulate individual values, a type refers to a set of values. This is not the same thing as a collection; -for example a `Set` of values is itself a single `Set` value. +for example a [`Set`](@ref) of values is itself a single `Set` value. Rather, a type describes a set of *possible* values, expressing uncertainty about which value we have. -A *concrete* type `T` describes the set of values whose direct tag, as returned by the `typeof` +A *concrete* type `T` describes the set of values whose direct tag, as returned by the [`typeof`](@ref) function, is `T`. An *abstract* type describes some possibly-larger set of values. -`Any` describes the entire universe of possible values. [`Integer`](@ref) is a subset of +[`Any`](@ref) describes the entire universe of possible values. [`Integer`](@ref) is a subset of `Any` that includes `Int`, [`Int8`](@ref), and other concrete types. Internally, Julia also makes heavy use of another type known as `Bottom`, which can also be written as `Union{}`. This corresponds to the empty set. Julia's types support the standard operations of set theory: you can ask whether `T1` is a "subset" -(subtype) of `T2` with `T1 <: T2`. Likewise, you intersect two types using `typeintersect`, take -their union with `Union`, and compute a type that contains their union with `typejoin`: +(subtype) of `T2` with `T1 <: T2`. Likewise, you intersect two types using [`typeintersect`](@ref), take +their union with [`Union`](@ref), and compute a type that contains their union with [`typejoin`](@ref): ```jldoctest julia> typeintersect(Int, Float64) @@ -66,7 +66,7 @@ Julia's type system can also express an *iterated union* of types: a union of ty of some variable. This is needed to describe parametric types where the values of some parameters are not known. -For example, :obj:`Array` has two parameters as in `Array{Int,2}`. If we did not know the element +For example, [`Array`](@ref) has two parameters as in `Array{Int,2}`. If we did not know the element type, we could write `Array{T,2} where T`, which is the union of `Array{T,2}` for all values of `T`: `Union{Array{Int8,2}, Array{Int16,2}, ...}`. @@ -365,7 +365,7 @@ f(a::Array{T}, x::T, y::T) where {T} = ... In this case, `T` occurs in invariant position inside `Array{T}`. That means whatever type of array is passed unambiguously determines -the value of `T` --- we say `T` has an *equality constraint* on it. +the value of `T` -- we say `T` has an *equality constraint* on it. Therefore in this case the diagonal rule is not really necessary, since the array determines `T` and we can then allow `x` and `y` to be of any subtypes of `T`. @@ -388,7 +388,7 @@ f(x::Union{Nothing,T}, y::T) where {T} = ... ``` Consider what this declaration means. -`y` has type `T`. `x` then can have either the same type `T`, or else be of type `Nothing`. +`y` has type `T`. `x` then can have either the same type `T`, or else be of type [`Nothing`](@ref). So all of the following calls should match: ```julia diff --git a/src/manual/metaprogramming.md b/src/manual/metaprogramming.md index a1c0722..fcfe422 100644 --- a/src/manual/metaprogramming.md +++ b/src/manual/metaprogramming.md @@ -35,7 +35,7 @@ Expr `Expr` objects contain two parts: - * a `Symbol` identifying the kind of expression. A symbol is an [interned string](https://en.wikipedia.org/wiki/String_interning) + * a [`Symbol`](@ref) identifying the kind of expression. A symbol is an [interned string](https://en.wikipedia.org/wiki/String_interning) identifier (more discussion below). ```jldoctest prog @@ -129,7 +129,7 @@ julia> Symbol(:var,'_',"sym") In the context of an expression, symbols are used to indicate access to variables; when an expression is evaluated, a symbol is replaced with the value bound to that symbol in the appropriate [scope](@ref scope-of-variables). -Sometimes extra parentheses around the argument to `:` are needed to avoid ambiguity in parsing.: +Sometimes extra parentheses around the argument to `:` are needed to avoid ambiguity in parsing: ```jldoctest julia> :(:) @@ -613,7 +613,7 @@ The argument `__source__` provides information (in the form of a `LineNumberNode of the `@` sign from the macro invocation. This allows macros to include better error diagnostic information, and is commonly used by logging, string-parser macros, and docs, for example, -as well as to implement the `@__LINE__`, `@__FILE__`, and `@__DIR__` macros. +as well as to implement the [`@__LINE__`](@ref), [`@__FILE__`](@ref), and [`@__DIR__`](@ref) macros. The location information can be accessed by referencing `__source__.line` and `__source__.file`: @@ -638,7 +638,7 @@ in the current module. ### Building an advanced macro -Here is a simplified definition of Julia's `@assert` macro: +Here is a simplified definition of Julia's [`@assert`](@ref) macro: ```jldoctest building julia> macro assert(ex) @@ -667,7 +667,7 @@ This is equivalent to writing: That is, in the first call, the expression `:(1 == 1.0)` is spliced into the test condition slot, while the value of `string(:(1 == 1.0))` is spliced into the assertion message slot. The entire expression, thus constructed, is placed into the syntax tree where the `@assert` macro call occurs. -Then at execution time, if the test expression evaluates to true, then `nothing` is returned, +Then at execution time, if the test expression evaluates to true, then [`nothing`](@ref) is returned, whereas if the test is false, an error is raised indicating the asserted expression that was false. Notice that it would not be possible to write this as a function, since only the *value* of the condition is available and it would be impossible to display the expression that computed it in @@ -675,7 +675,7 @@ the error message. The actual definition of `@assert` in Julia Base is more complicated. It allows the user to optionally specify their own error message, instead of just printing the failed expression. -Just like in functions with a variable number of arguments, this is specified with an ellipses +Just like in functions with a variable number of arguments ([Varargs Functions](@ref)), this is specified with an ellipses following the last argument: ```jldoctest assert2 @@ -1094,7 +1094,7 @@ When defining generated functions, there are four main differences to ordinary f 3. Instead of calculating something or performing some action, you return a *quoted expression* which, when evaluated, does what you want. 4. Generated functions must not *mutate* or *observe* any non-constant global state (including, - for example, IO, locks, non-local dictionaries, or using `hasmethod`). + for example, IO, locks, non-local dictionaries, or using [`hasmethod`](@ref)). This means they can only read global constants, and cannot have any side effects. In other words, they must be completely pure. Due to an implementation limitation, this also means that they currently cannot define a closure diff --git a/src/manual/parallel-computing.md b/src/manual/parallel-computing.md index f79521b..efa9077 100644 --- a/src/manual/parallel-computing.md +++ b/src/manual/parallel-computing.md @@ -12,10 +12,10 @@ Julia also supports communication between `Tasks` through operations like [`wait Communication and data synchronization is managed through [`Channel`](@ref)s, which are the conduits that provide inter-`Tasks` communication. -Julia also supports experimental multi-threading, where execution is forked and an anonymous function is run across all +Julia also supports [experimental multi-threading](@ref man-multithreading), where execution is forked and an anonymous function is run across all threads. Known as the fork-join approach, parallel threads execute independently, and must ultimately be joined in Julia's main thread to allow serial execution to continue. -Multi-threading is supported using the `Base.Threads` module that is still considered experimental, as Julia is +Multi-threading is supported using the [`Base.Threads`](@ref lib-multithreading) module that is still considered experimental, as Julia is not yet fully thread-safe. In particular segfaults seem to occur during I/O operations and task switching. As an up-to-date reference, keep an eye on [the issue tracker](https://github.com/JuliaLang/julia/issues?q=is%3Aopen+is%3Aissue+label%3Amultithreading). Multi-Threading should only be used if you take into consideration global variables, locks and @@ -80,51 +80,51 @@ A channel can be visualized as a pipe, i.e., it has a write end and a read end : @async foo() end ``` -* Channels are created via the `Channel{T}(sz)` constructor. The channel will only hold objects - of type `T`. If the type is not specified, the channel can hold objects of any type. `sz` refers - to the maximum number of elements that can be held in the channel at any time. For example, `Channel(32)` - creates a channel that can hold a maximum of 32 objects of any type. A `Channel{MyType}(64)` can - hold up to 64 objects of `MyType` at any time. -* If a [`Channel`](@ref) is empty, readers (on a [`take!`](@ref) call) will block until data is available. -* If a [`Channel`](@ref) is full, writers (on a [`put!`](@ref) call) will block until space becomes available. -* [`isready`](@ref) tests for the presence of any object in the channel, while [`wait`](@ref) - waits for an object to become available. -* A [`Channel`](@ref) is in an open state initially. This means that it can be read from and written to - freely via [`take!`](@ref) and [`put!`](@ref) calls. [`close`](@ref) closes a [`Channel`](@ref). - On a closed [`Channel`](@ref), [`put!`](@ref) will fail. For example: - -```julia-repl -julia> c = Channel(2); - -julia> put!(c, 1) # `put!` on an open channel succeeds -1 - -julia> close(c); - -julia> put!(c, 2) # `put!` on a closed channel throws an exception. -ERROR: InvalidStateException("Channel is closed.",:closed) -Stacktrace: -[...] -``` + * Channels are created via the `Channel{T}(sz)` constructor. The channel will only hold objects + of type `T`. If the type is not specified, the channel can hold objects of any type. `sz` refers + to the maximum number of elements that can be held in the channel at any time. For example, `Channel(32)` + creates a channel that can hold a maximum of 32 objects of any type. A `Channel{MyType}(64)` can + hold up to 64 objects of `MyType` at any time. + * If a [`Channel`](@ref) is empty, readers (on a [`take!`](@ref) call) will block until data is available. + * If a [`Channel`](@ref) is full, writers (on a [`put!`](@ref) call) will block until space becomes available. + * [`isready`](@ref) tests for the presence of any object in the channel, while [`wait`](@ref) + waits for an object to become available. + * A [`Channel`](@ref) is in an open state initially. This means that it can be read from and written to + freely via [`take!`](@ref) and [`put!`](@ref) calls. [`close`](@ref) closes a [`Channel`](@ref). + On a closed [`Channel`](@ref), [`put!`](@ref) will fail. For example: + + ```julia-repl + julia> c = Channel(2); + + julia> put!(c, 1) # `put!` on an open channel succeeds + 1 + + julia> close(c); + + julia> put!(c, 2) # `put!` on a closed channel throws an exception. + ERROR: InvalidStateException("Channel is closed.",:closed) + Stacktrace: + [...] + ``` * [`take!`](@ref) and [`fetch`](@ref) (which retrieves but does not remove the value) on a closed channel successfully return any existing values until it is emptied. Continuing the above example: -```julia-repl -julia> fetch(c) # Any number of `fetch` calls succeed. -1 + ```julia-repl + julia> fetch(c) # Any number of `fetch` calls succeed. + 1 -julia> fetch(c) -1 + julia> fetch(c) + 1 -julia> take!(c) # The first `take!` removes the value. -1 + julia> take!(c) # The first `take!` removes the value. + 1 -julia> take!(c) # No more data available on a closed channel. -ERROR: InvalidStateException("Channel is closed.",:closed) -Stacktrace: -[...] -``` + julia> take!(c) # No more data available on a closed channel. + ERROR: InvalidStateException("Channel is closed.",:closed) + Stacktrace: + [...] + ``` A `Channel` can be used as an iterable object in a `for` loop, in which case the loop runs as long as the `Channel` has data or is open. The loop variable takes on all values added to the @@ -216,7 +216,7 @@ executed sequentially on a single OS thread. Future versions of Julia may suppor tasks on multiple threads, in which case compute bound tasks will see benefits of parallel execution too. -# Multi-Threading (Experimental) +# [Multi-Threading (Experimental)](@id man-multithreading) In addition to tasks Julia forwards natively supports multi-threading. Note that this section is experimental and the interfaces may change in the future. @@ -638,7 +638,7 @@ the same time. -## Code Availability and Loading Packages +## [Code Availability and Loading Packages](@id code-availability) Your code must be available on any process that runs it. For example, type the following into the Julia prompt: From fc36f54b37c94bf52e681bc21cb47bda7b1677e2 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Tue, 5 Mar 2019 17:18:25 +0900 Subject: [PATCH 102/153] update Julia 1.2.0-DEV.420 (2019-03-05) Commit 3f646245d4 --- codex/NEWS.md | 2 + codex/base/base.md | 12 +++- codex/base/collections.md | 2 + codex/base/io-network.md | 7 ++- codex/manual/conversion-and-promotion.md | 2 +- codex/manual/modules.md | 15 ++--- codex/stdlib/LinearAlgebra.md | 72 +++++++++++++----------- codex/stdlib/Logging.md | 7 ++- codex/stdlib/Sockets.md | 3 + src/NEWS.md | 2 + src/base/base.md | 12 +++- src/base/collections.md | 2 + src/base/io-network.md | 7 ++- src/manual/conversion-and-promotion.md | 2 +- src/manual/modules.md | 15 ++--- src/stdlib/LinearAlgebra.md | 72 +++++++++++++----------- src/stdlib/Logging.md | 7 ++- src/stdlib/Sockets.md | 3 + 18 files changed, 144 insertions(+), 100 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index 5dc3808..ea8778d 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -44,6 +44,7 @@ Standard library changes * `startswith` and `endswith` now accept a `Regex` for the second argument ([#29790](https://github.com/JuliaLang/julia/issues/29790)). * `retry` supports arbitrary callable objects ([#30382](https://github.com/JuliaLang/julia/issues/30382)). * A no-argument construct to `Ptr{T}` has been added which constructs a null pointer ([#30919](https://github.com/JuliaLang/julia/issues/30919)) +* `strip` now accepts a function argument in the same manner as `lstrip` and `rstrip` ([#31211](https://github.com/JuliaLang/julia/issues/31211)) #### LinearAlgebra @@ -52,6 +53,7 @@ Standard library changes * Eigenvalues λ of general matrices are now sorted lexicographically by (Re λ, Im λ) ([#21598](https://github.com/JuliaLang/julia/issues/21598)). * `one` for structured matrices (`Diagonal`, `Bidiagonal`, `Tridiagonal`, `Symtridiagonal`) now preserves structure and type. ([#29777](https://github.com/JuliaLang/julia/issues/29777)) +* `diagm(v)` is now a shorthand for `diagm(0 => v)`. ([#31125](https://github.com/JuliaLang/julia/issues/31125)). #### SparseArrays diff --git a/codex/base/base.md b/codex/base/base.md index 3a1df62..ed75d27 100644 --- a/codex/base/base.md +++ b/codex/base/base.md @@ -87,9 +87,15 @@ where = ``` -## Base Modules +## Standard Modules +```@docs +Main +Core +Base +``` + +## Base Submodules ```@docs -Base.Base Base.Broadcast Base.Docs Base.Iterators @@ -211,6 +217,7 @@ Base.Enums.@enum Core.Expr Core.Symbol Core.Symbol(x...) +Core.Module ``` ## Generic Functions @@ -248,6 +255,7 @@ Base.@simd Base.@polly Base.@generated Base.@pure +Base.@deprecate ``` ## Missing Values diff --git a/codex/base/collections.md b/codex/base/collections.md index c070111..2e5ad94 100644 --- a/codex/base/collections.md +++ b/codex/base/collections.md @@ -191,6 +191,7 @@ for the key `x`). Multiple arguments to `D[...]` are converted to tuples; for e `D[x,y]` is equivalent to `D[(x,y)]`, i.e. it refers to the value keyed by the tuple `(x,y)`. ```@docs +Base.AbstractDict Base.Dict Base.IdDict Base.WeakKeyDict @@ -233,6 +234,7 @@ Partially implemented by: ## Set-Like Collections ```@docs +Base.AbstractSet Base.Set Base.BitSet Base.union diff --git a/codex/base/io-network.md b/codex/base/io-network.md index f3f29e6..a972f7c 100644 --- a/codex/base/io-network.md +++ b/codex/base/io-network.md @@ -81,7 +81,7 @@ output (such as images, formatted text, or even audio and video), consisting of `x` (with a plain-text fallback). * Overloading [`show`](@ref) allows one to indicate arbitrary multimedia representations (keyed by standard MIME types) of user-defined types. - * Multimedia-capable display backends may be registered by subclassing a generic `AbstractDisplay` type + * Multimedia-capable display backends may be registered by subclassing a generic [`AbstractDisplay`](@ref) type and pushing them onto a stack of display backends via [`pushdisplay`](@ref). The base Julia runtime provides only plain-text display, but richer displays may be enabled by @@ -89,6 +89,7 @@ loading external modules or by using graphical Julia environments (such as the I notebook). ```@docs +Base.AbstractDisplay Base.Multimedia.display Base.Multimedia.redisplay Base.Multimedia.displayable @@ -104,10 +105,10 @@ PNG images in a window can register this capability with Julia, so that calling types with PNG representations will automatically display the image using the module's window. In order to define a new display backend, one should first create a subtype `D` of the abstract -class `AbstractDisplay`. Then, for each MIME type (`mime` string) that can be displayed on `D`, one should +class [`AbstractDisplay`](@ref). Then, for each MIME type (`mime` string) that can be displayed on `D`, one should define a function `display(d::D, ::MIME"mime", x) = ...` that displays `x` as that MIME type, usually by calling [`show(io, mime, x)`](@ref) or [`repr(io, mime, x)`](@ref). -A `MethodError` should be thrown if `x` cannot be displayed +A [`MethodError`](@ref) should be thrown if `x` cannot be displayed as that MIME type; this is automatic if one calls `show` or `repr`. Finally, one should define a function `display(d::D, x)` that queries [`showable(mime, x)`](@ref) for the `mime` types supported by `D` and displays the "best" one; a `MethodError` should be thrown if no supported MIME types are found diff --git a/codex/manual/conversion-and-promotion.md b/codex/manual/conversion-and-promotion.md index baf2314..8a9c72b 100644 --- a/codex/manual/conversion-and-promotion.md +++ b/codex/manual/conversion-and-promotion.md @@ -194,7 +194,7 @@ already of the requested type: convert(::Type{T}, x::T) where {T<:Number} = x ``` -Similar definitions exist for `AbstractString`, `AbstractArray`, and `AbstractDict`. +Similar definitions exist for `AbstractString`, [`AbstractArray`](@ref), and [`AbstractDict`](@ref). ## Promotion diff --git a/codex/manual/modules.md b/codex/manual/modules.md index 16ebfdb..80f59ff 100644 --- a/codex/manual/modules.md +++ b/codex/manual/modules.md @@ -117,17 +117,10 @@ end ### Standard modules -There are three important standard modules: `Main`, `Core`, and `Base`. - -`Main` is the top-level module, and Julia starts with `Main` set as the current module. Variables -defined at the prompt go in `Main`, and [`varinfo()`](@ref) lists variables in `Main`. - -`Core` contains all identifiers considered "built in" to the language, i.e. part of the core language -and not libraries. Every module implicitly specifies `using Core`, since you can't do anything -without those definitions. - -`Base` is a module that contains basic functionality (the contents of `base/`). All modules implicitly contain `using Base`, -since this is needed in the vast majority of cases. +There are three important standard modules: +* [`Core`](@ref) contains all functionality "built into" the language. +* [`Base`](@ref) contains basic functionality that is useful in almost all cases. +* [`Main`](@ref) is the top-level module and the current module, when Julia is started. ### Default top-level definitions and bare modules diff --git a/codex/stdlib/LinearAlgebra.md b/codex/stdlib/LinearAlgebra.md index 01969e1..afe31b5 100644 --- a/codex/stdlib/LinearAlgebra.md +++ b/codex/stdlib/LinearAlgebra.md @@ -162,31 +162,35 @@ specialized routines that are specially developed for particular matrix types. The following tables summarize the types of special matrices that have been implemented in Julia, as well as whether hooks to various optimized methods for them in LAPACK are available. -| Type | Description | -|:------------------------- |:-------------------------------------------------------------------------------- | -| [`Symmetric`](@ref) | [Symmetric matrix](https://en.wikipedia.org/wiki/Symmetric_matrix) | -| [`Hermitian`](@ref) | [Hermitian matrix](https://en.wikipedia.org/wiki/Hermitian_matrix) | -| [`UpperTriangular`](@ref) | Upper [triangular matrix](https://en.wikipedia.org/wiki/Triangular_matrix) | -| [`LowerTriangular`](@ref) | Lower [triangular matrix](https://en.wikipedia.org/wiki/Triangular_matrix) | -| [`Tridiagonal`](@ref) | [Tridiagonal matrix](https://en.wikipedia.org/wiki/Tridiagonal_matrix) | -| [`SymTridiagonal`](@ref) | Symmetric tridiagonal matrix | -| [`Bidiagonal`](@ref) | Upper/lower [bidiagonal matrix](https://en.wikipedia.org/wiki/Bidiagonal_matrix) | -| [`Diagonal`](@ref) | [Diagonal matrix](https://en.wikipedia.org/wiki/Diagonal_matrix) | -| [`UniformScaling`](@ref) | [Uniform scaling operator](https://en.wikipedia.org/wiki/Uniform_scaling) | +| Type | Description | +|:----------------------------- |:--------------------------------------------------------------------------------------------- | +| [`Symmetric`](@ref) | [Symmetric matrix](https://en.wikipedia.org/wiki/Symmetric_matrix) | +| [`Hermitian`](@ref) | [Hermitian matrix](https://en.wikipedia.org/wiki/Hermitian_matrix) | +| [`UpperTriangular`](@ref) | Upper [triangular matrix](https://en.wikipedia.org/wiki/Triangular_matrix) | +| [`UnitUpperTriangular`](@ref) | Upper [triangular matrix](https://en.wikipedia.org/wiki/Triangular_matrix) with unit diagonal | +| [`LowerTriangular`](@ref) | Lower [triangular matrix](https://en.wikipedia.org/wiki/Triangular_matrix) | +| [`UnitLowerTriangular`](@ref) | Lower [triangular matrix](https://en.wikipedia.org/wiki/Triangular_matrix) with unit diagonal | +| [`Tridiagonal`](@ref) | [Tridiagonal matrix](https://en.wikipedia.org/wiki/Tridiagonal_matrix) | +| [`SymTridiagonal`](@ref) | Symmetric tridiagonal matrix | +| [`Bidiagonal`](@ref) | Upper/lower [bidiagonal matrix](https://en.wikipedia.org/wiki/Bidiagonal_matrix) | +| [`Diagonal`](@ref) | [Diagonal matrix](https://en.wikipedia.org/wiki/Diagonal_matrix) | +| [`UniformScaling`](@ref) | [Uniform scaling operator](https://en.wikipedia.org/wiki/Uniform_scaling) | ### Elementary operations -| Matrix type | `+` | `-` | `*` | `\` | Other functions with optimized methods | -|:------------------------- |:--- |:--- |:--- |:--- |:----------------------------------------------------------- | -| [`Symmetric`](@ref) | | | | MV | [`inv`](@ref), [`sqrt`](@ref), [`exp`](@ref) | -| [`Hermitian`](@ref) | | | | MV | [`inv`](@ref), [`sqrt`](@ref), [`exp`](@ref) | -| [`UpperTriangular`](@ref) | | | MV | MV | [`inv`](@ref), [`det`](@ref) | -| [`LowerTriangular`](@ref) | | | MV | MV | [`inv`](@ref), [`det`](@ref) | -| [`SymTridiagonal`](@ref) | M | M | MS | MV | [`eigmax`](@ref), [`eigmin`](@ref) | -| [`Tridiagonal`](@ref) | M | M | MS | MV | | -| [`Bidiagonal`](@ref) | M | M | MS | MV | | -| [`Diagonal`](@ref) | M | M | MV | MV | [`inv`](@ref), [`det`](@ref), [`logdet`](@ref), [`/`](@ref) | -| [`UniformScaling`](@ref) | M | M | MVS | MVS | [`/`](@ref) | +| Matrix type | `+` | `-` | `*` | `\` | Other functions with optimized methods | +|:----------------------------- |:--- |:--- |:--- |:--- |:----------------------------------------------------------- | +| [`Symmetric`](@ref) | | | | MV | [`inv`](@ref), [`sqrt`](@ref), [`exp`](@ref) | +| [`Hermitian`](@ref) | | | | MV | [`inv`](@ref), [`sqrt`](@ref), [`exp`](@ref) | +| [`UpperTriangular`](@ref) | | | MV | MV | [`inv`](@ref), [`det`](@ref) | +| [`UnitUpperTriangular`](@ref) | | | MV | MV | [`inv`](@ref), [`det`](@ref) | +| [`LowerTriangular`](@ref) | | | MV | MV | [`inv`](@ref), [`det`](@ref) | +| [`UnitLowerTriangular`](@ref) | | | MV | MV | [`inv`](@ref), [`det`](@ref) | +| [`SymTridiagonal`](@ref) | M | M | MS | MV | [`eigmax`](@ref), [`eigmin`](@ref) | +| [`Tridiagonal`](@ref) | M | M | MS | MV | | +| [`Bidiagonal`](@ref) | M | M | MS | MV | | +| [`Diagonal`](@ref) | M | M | MV | MV | [`inv`](@ref), [`det`](@ref), [`logdet`](@ref), [`/`](@ref) | +| [`UniformScaling`](@ref) | M | M | MVS | MVS | [`/`](@ref) | Legend: @@ -198,16 +202,18 @@ Legend: ### Matrix factorizations -| Matrix type | LAPACK | [`eigen`](@ref) | [`eigvals`](@ref) | [`eigvecs`](@ref) | [`svd`](@ref) | [`svdvals`](@ref) | -|:------------------------- |:------ |:------------- |:----------------- |:----------------- |:------------- |:----------------- | -| [`Symmetric`](@ref) | SY | | ARI | | | | -| [`Hermitian`](@ref) | HE | | ARI | | | | -| [`UpperTriangular`](@ref) | TR | A | A | A | | | -| [`LowerTriangular`](@ref) | TR | A | A | A | | | -| [`SymTridiagonal`](@ref) | ST | A | ARI | AV | | | -| [`Tridiagonal`](@ref) | GT | | | | | | -| [`Bidiagonal`](@ref) | BD | | | | A | A | -| [`Diagonal`](@ref) | DI | | A | | | | +| Matrix type | LAPACK | [`eigen`](@ref) | [`eigvals`](@ref) | [`eigvecs`](@ref) | [`svd`](@ref) | [`svdvals`](@ref) | +|:----------------------------- |:------ |:------------- |:----------------- |:----------------- |:------------- |:----------------- | +| [`Symmetric`](@ref) | SY | | ARI | | | | +| [`Hermitian`](@ref) | HE | | ARI | | | | +| [`UpperTriangular`](@ref) | TR | A | A | A | | | +| [`UnitUpperTriangular`](@ref) | TR | A | A | A | | | +| [`LowerTriangular`](@ref) | TR | A | A | A | | | +| [`UnitLowerTriangular`](@ref) | TR | A | A | A | | | +| [`SymTridiagonal`](@ref) | ST | A | ARI | AV | | | +| [`Tridiagonal`](@ref) | GT | | | | | | +| [`Bidiagonal`](@ref) | BD | | | | A | A | +| [`Diagonal`](@ref) | DI | | A | | | | Legend: @@ -309,6 +315,8 @@ LinearAlgebra.Symmetric LinearAlgebra.Hermitian LinearAlgebra.LowerTriangular LinearAlgebra.UpperTriangular +LinearAlgebra.UnitLowerTriangular +LinearAlgebra.UnitUpperTriangular LinearAlgebra.UniformScaling LinearAlgebra.lu LinearAlgebra.lu! diff --git a/codex/stdlib/Logging.md b/codex/stdlib/Logging.md index 8831569..add2985 100644 --- a/codex/stdlib/Logging.md +++ b/codex/stdlib/Logging.md @@ -1,6 +1,6 @@ # Logging -The `Logging` module provides a way to record the history and progress of a +The [`Logging`](@ref Logging.Logging) module provides a way to record the history and progress of a computation as a log of events. Events are created by inserting a logging statement into the source code, for example: @@ -233,6 +233,11 @@ julia> close(io) ## Reference +### Logging module +```@docs +Logging.Logging +``` + ### Creating events ```@docs diff --git a/codex/stdlib/Sockets.md b/codex/stdlib/Sockets.md index 710a95f..f993e83 100644 --- a/codex/stdlib/Sockets.md +++ b/codex/stdlib/Sockets.md @@ -5,6 +5,7 @@ DocTestSetup = :(using Sockets) ``` ```@docs +Sockets.Sockets Sockets.connect(::TCPSocket, ::Integer) Sockets.connect(::AbstractString) Sockets.listen(::Any) @@ -16,8 +17,10 @@ Sockets.getalladdrinfo Sockets.getnameinfo Sockets.getsockname Sockets.getpeername +Sockets.IPAddr Sockets.IPv4 Sockets.IPv6 +Sockets.@ip_str Sockets.TCPSocket Sockets.UDPSocket Sockets.accept diff --git a/src/NEWS.md b/src/NEWS.md index 5dc3808..ea8778d 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -44,6 +44,7 @@ Standard library changes * `startswith` and `endswith` now accept a `Regex` for the second argument ([#29790](https://github.com/JuliaLang/julia/issues/29790)). * `retry` supports arbitrary callable objects ([#30382](https://github.com/JuliaLang/julia/issues/30382)). * A no-argument construct to `Ptr{T}` has been added which constructs a null pointer ([#30919](https://github.com/JuliaLang/julia/issues/30919)) +* `strip` now accepts a function argument in the same manner as `lstrip` and `rstrip` ([#31211](https://github.com/JuliaLang/julia/issues/31211)) #### LinearAlgebra @@ -52,6 +53,7 @@ Standard library changes * Eigenvalues λ of general matrices are now sorted lexicographically by (Re λ, Im λ) ([#21598](https://github.com/JuliaLang/julia/issues/21598)). * `one` for structured matrices (`Diagonal`, `Bidiagonal`, `Tridiagonal`, `Symtridiagonal`) now preserves structure and type. ([#29777](https://github.com/JuliaLang/julia/issues/29777)) +* `diagm(v)` is now a shorthand for `diagm(0 => v)`. ([#31125](https://github.com/JuliaLang/julia/issues/31125)). #### SparseArrays diff --git a/src/base/base.md b/src/base/base.md index 3a1df62..ed75d27 100644 --- a/src/base/base.md +++ b/src/base/base.md @@ -87,9 +87,15 @@ where = ``` -## Base Modules +## Standard Modules +```@docs +Main +Core +Base +``` + +## Base Submodules ```@docs -Base.Base Base.Broadcast Base.Docs Base.Iterators @@ -211,6 +217,7 @@ Base.Enums.@enum Core.Expr Core.Symbol Core.Symbol(x...) +Core.Module ``` ## Generic Functions @@ -248,6 +255,7 @@ Base.@simd Base.@polly Base.@generated Base.@pure +Base.@deprecate ``` ## Missing Values diff --git a/src/base/collections.md b/src/base/collections.md index c070111..2e5ad94 100644 --- a/src/base/collections.md +++ b/src/base/collections.md @@ -191,6 +191,7 @@ for the key `x`). Multiple arguments to `D[...]` are converted to tuples; for e `D[x,y]` is equivalent to `D[(x,y)]`, i.e. it refers to the value keyed by the tuple `(x,y)`. ```@docs +Base.AbstractDict Base.Dict Base.IdDict Base.WeakKeyDict @@ -233,6 +234,7 @@ Partially implemented by: ## Set-Like Collections ```@docs +Base.AbstractSet Base.Set Base.BitSet Base.union diff --git a/src/base/io-network.md b/src/base/io-network.md index f3f29e6..a972f7c 100644 --- a/src/base/io-network.md +++ b/src/base/io-network.md @@ -81,7 +81,7 @@ output (such as images, formatted text, or even audio and video), consisting of `x` (with a plain-text fallback). * Overloading [`show`](@ref) allows one to indicate arbitrary multimedia representations (keyed by standard MIME types) of user-defined types. - * Multimedia-capable display backends may be registered by subclassing a generic `AbstractDisplay` type + * Multimedia-capable display backends may be registered by subclassing a generic [`AbstractDisplay`](@ref) type and pushing them onto a stack of display backends via [`pushdisplay`](@ref). The base Julia runtime provides only plain-text display, but richer displays may be enabled by @@ -89,6 +89,7 @@ loading external modules or by using graphical Julia environments (such as the I notebook). ```@docs +Base.AbstractDisplay Base.Multimedia.display Base.Multimedia.redisplay Base.Multimedia.displayable @@ -104,10 +105,10 @@ PNG images in a window can register this capability with Julia, so that calling types with PNG representations will automatically display the image using the module's window. In order to define a new display backend, one should first create a subtype `D` of the abstract -class `AbstractDisplay`. Then, for each MIME type (`mime` string) that can be displayed on `D`, one should +class [`AbstractDisplay`](@ref). Then, for each MIME type (`mime` string) that can be displayed on `D`, one should define a function `display(d::D, ::MIME"mime", x) = ...` that displays `x` as that MIME type, usually by calling [`show(io, mime, x)`](@ref) or [`repr(io, mime, x)`](@ref). -A `MethodError` should be thrown if `x` cannot be displayed +A [`MethodError`](@ref) should be thrown if `x` cannot be displayed as that MIME type; this is automatic if one calls `show` or `repr`. Finally, one should define a function `display(d::D, x)` that queries [`showable(mime, x)`](@ref) for the `mime` types supported by `D` and displays the "best" one; a `MethodError` should be thrown if no supported MIME types are found diff --git a/src/manual/conversion-and-promotion.md b/src/manual/conversion-and-promotion.md index baf2314..8a9c72b 100644 --- a/src/manual/conversion-and-promotion.md +++ b/src/manual/conversion-and-promotion.md @@ -194,7 +194,7 @@ already of the requested type: convert(::Type{T}, x::T) where {T<:Number} = x ``` -Similar definitions exist for `AbstractString`, `AbstractArray`, and `AbstractDict`. +Similar definitions exist for `AbstractString`, [`AbstractArray`](@ref), and [`AbstractDict`](@ref). ## Promotion diff --git a/src/manual/modules.md b/src/manual/modules.md index 16ebfdb..80f59ff 100644 --- a/src/manual/modules.md +++ b/src/manual/modules.md @@ -117,17 +117,10 @@ end ### Standard modules -There are three important standard modules: `Main`, `Core`, and `Base`. - -`Main` is the top-level module, and Julia starts with `Main` set as the current module. Variables -defined at the prompt go in `Main`, and [`varinfo()`](@ref) lists variables in `Main`. - -`Core` contains all identifiers considered "built in" to the language, i.e. part of the core language -and not libraries. Every module implicitly specifies `using Core`, since you can't do anything -without those definitions. - -`Base` is a module that contains basic functionality (the contents of `base/`). All modules implicitly contain `using Base`, -since this is needed in the vast majority of cases. +There are three important standard modules: +* [`Core`](@ref) contains all functionality "built into" the language. +* [`Base`](@ref) contains basic functionality that is useful in almost all cases. +* [`Main`](@ref) is the top-level module and the current module, when Julia is started. ### Default top-level definitions and bare modules diff --git a/src/stdlib/LinearAlgebra.md b/src/stdlib/LinearAlgebra.md index 01969e1..afe31b5 100644 --- a/src/stdlib/LinearAlgebra.md +++ b/src/stdlib/LinearAlgebra.md @@ -162,31 +162,35 @@ specialized routines that are specially developed for particular matrix types. The following tables summarize the types of special matrices that have been implemented in Julia, as well as whether hooks to various optimized methods for them in LAPACK are available. -| Type | Description | -|:------------------------- |:-------------------------------------------------------------------------------- | -| [`Symmetric`](@ref) | [Symmetric matrix](https://en.wikipedia.org/wiki/Symmetric_matrix) | -| [`Hermitian`](@ref) | [Hermitian matrix](https://en.wikipedia.org/wiki/Hermitian_matrix) | -| [`UpperTriangular`](@ref) | Upper [triangular matrix](https://en.wikipedia.org/wiki/Triangular_matrix) | -| [`LowerTriangular`](@ref) | Lower [triangular matrix](https://en.wikipedia.org/wiki/Triangular_matrix) | -| [`Tridiagonal`](@ref) | [Tridiagonal matrix](https://en.wikipedia.org/wiki/Tridiagonal_matrix) | -| [`SymTridiagonal`](@ref) | Symmetric tridiagonal matrix | -| [`Bidiagonal`](@ref) | Upper/lower [bidiagonal matrix](https://en.wikipedia.org/wiki/Bidiagonal_matrix) | -| [`Diagonal`](@ref) | [Diagonal matrix](https://en.wikipedia.org/wiki/Diagonal_matrix) | -| [`UniformScaling`](@ref) | [Uniform scaling operator](https://en.wikipedia.org/wiki/Uniform_scaling) | +| Type | Description | +|:----------------------------- |:--------------------------------------------------------------------------------------------- | +| [`Symmetric`](@ref) | [Symmetric matrix](https://en.wikipedia.org/wiki/Symmetric_matrix) | +| [`Hermitian`](@ref) | [Hermitian matrix](https://en.wikipedia.org/wiki/Hermitian_matrix) | +| [`UpperTriangular`](@ref) | Upper [triangular matrix](https://en.wikipedia.org/wiki/Triangular_matrix) | +| [`UnitUpperTriangular`](@ref) | Upper [triangular matrix](https://en.wikipedia.org/wiki/Triangular_matrix) with unit diagonal | +| [`LowerTriangular`](@ref) | Lower [triangular matrix](https://en.wikipedia.org/wiki/Triangular_matrix) | +| [`UnitLowerTriangular`](@ref) | Lower [triangular matrix](https://en.wikipedia.org/wiki/Triangular_matrix) with unit diagonal | +| [`Tridiagonal`](@ref) | [Tridiagonal matrix](https://en.wikipedia.org/wiki/Tridiagonal_matrix) | +| [`SymTridiagonal`](@ref) | Symmetric tridiagonal matrix | +| [`Bidiagonal`](@ref) | Upper/lower [bidiagonal matrix](https://en.wikipedia.org/wiki/Bidiagonal_matrix) | +| [`Diagonal`](@ref) | [Diagonal matrix](https://en.wikipedia.org/wiki/Diagonal_matrix) | +| [`UniformScaling`](@ref) | [Uniform scaling operator](https://en.wikipedia.org/wiki/Uniform_scaling) | ### Elementary operations -| Matrix type | `+` | `-` | `*` | `\` | Other functions with optimized methods | -|:------------------------- |:--- |:--- |:--- |:--- |:----------------------------------------------------------- | -| [`Symmetric`](@ref) | | | | MV | [`inv`](@ref), [`sqrt`](@ref), [`exp`](@ref) | -| [`Hermitian`](@ref) | | | | MV | [`inv`](@ref), [`sqrt`](@ref), [`exp`](@ref) | -| [`UpperTriangular`](@ref) | | | MV | MV | [`inv`](@ref), [`det`](@ref) | -| [`LowerTriangular`](@ref) | | | MV | MV | [`inv`](@ref), [`det`](@ref) | -| [`SymTridiagonal`](@ref) | M | M | MS | MV | [`eigmax`](@ref), [`eigmin`](@ref) | -| [`Tridiagonal`](@ref) | M | M | MS | MV | | -| [`Bidiagonal`](@ref) | M | M | MS | MV | | -| [`Diagonal`](@ref) | M | M | MV | MV | [`inv`](@ref), [`det`](@ref), [`logdet`](@ref), [`/`](@ref) | -| [`UniformScaling`](@ref) | M | M | MVS | MVS | [`/`](@ref) | +| Matrix type | `+` | `-` | `*` | `\` | Other functions with optimized methods | +|:----------------------------- |:--- |:--- |:--- |:--- |:----------------------------------------------------------- | +| [`Symmetric`](@ref) | | | | MV | [`inv`](@ref), [`sqrt`](@ref), [`exp`](@ref) | +| [`Hermitian`](@ref) | | | | MV | [`inv`](@ref), [`sqrt`](@ref), [`exp`](@ref) | +| [`UpperTriangular`](@ref) | | | MV | MV | [`inv`](@ref), [`det`](@ref) | +| [`UnitUpperTriangular`](@ref) | | | MV | MV | [`inv`](@ref), [`det`](@ref) | +| [`LowerTriangular`](@ref) | | | MV | MV | [`inv`](@ref), [`det`](@ref) | +| [`UnitLowerTriangular`](@ref) | | | MV | MV | [`inv`](@ref), [`det`](@ref) | +| [`SymTridiagonal`](@ref) | M | M | MS | MV | [`eigmax`](@ref), [`eigmin`](@ref) | +| [`Tridiagonal`](@ref) | M | M | MS | MV | | +| [`Bidiagonal`](@ref) | M | M | MS | MV | | +| [`Diagonal`](@ref) | M | M | MV | MV | [`inv`](@ref), [`det`](@ref), [`logdet`](@ref), [`/`](@ref) | +| [`UniformScaling`](@ref) | M | M | MVS | MVS | [`/`](@ref) | Legend: @@ -198,16 +202,18 @@ Legend: ### Matrix factorizations -| Matrix type | LAPACK | [`eigen`](@ref) | [`eigvals`](@ref) | [`eigvecs`](@ref) | [`svd`](@ref) | [`svdvals`](@ref) | -|:------------------------- |:------ |:------------- |:----------------- |:----------------- |:------------- |:----------------- | -| [`Symmetric`](@ref) | SY | | ARI | | | | -| [`Hermitian`](@ref) | HE | | ARI | | | | -| [`UpperTriangular`](@ref) | TR | A | A | A | | | -| [`LowerTriangular`](@ref) | TR | A | A | A | | | -| [`SymTridiagonal`](@ref) | ST | A | ARI | AV | | | -| [`Tridiagonal`](@ref) | GT | | | | | | -| [`Bidiagonal`](@ref) | BD | | | | A | A | -| [`Diagonal`](@ref) | DI | | A | | | | +| Matrix type | LAPACK | [`eigen`](@ref) | [`eigvals`](@ref) | [`eigvecs`](@ref) | [`svd`](@ref) | [`svdvals`](@ref) | +|:----------------------------- |:------ |:------------- |:----------------- |:----------------- |:------------- |:----------------- | +| [`Symmetric`](@ref) | SY | | ARI | | | | +| [`Hermitian`](@ref) | HE | | ARI | | | | +| [`UpperTriangular`](@ref) | TR | A | A | A | | | +| [`UnitUpperTriangular`](@ref) | TR | A | A | A | | | +| [`LowerTriangular`](@ref) | TR | A | A | A | | | +| [`UnitLowerTriangular`](@ref) | TR | A | A | A | | | +| [`SymTridiagonal`](@ref) | ST | A | ARI | AV | | | +| [`Tridiagonal`](@ref) | GT | | | | | | +| [`Bidiagonal`](@ref) | BD | | | | A | A | +| [`Diagonal`](@ref) | DI | | A | | | | Legend: @@ -309,6 +315,8 @@ LinearAlgebra.Symmetric LinearAlgebra.Hermitian LinearAlgebra.LowerTriangular LinearAlgebra.UpperTriangular +LinearAlgebra.UnitLowerTriangular +LinearAlgebra.UnitUpperTriangular LinearAlgebra.UniformScaling LinearAlgebra.lu LinearAlgebra.lu! diff --git a/src/stdlib/Logging.md b/src/stdlib/Logging.md index 8831569..add2985 100644 --- a/src/stdlib/Logging.md +++ b/src/stdlib/Logging.md @@ -1,6 +1,6 @@ # Logging -The `Logging` module provides a way to record the history and progress of a +The [`Logging`](@ref Logging.Logging) module provides a way to record the history and progress of a computation as a log of events. Events are created by inserting a logging statement into the source code, for example: @@ -233,6 +233,11 @@ julia> close(io) ## Reference +### Logging module +```@docs +Logging.Logging +``` + ### Creating events ```@docs diff --git a/src/stdlib/Sockets.md b/src/stdlib/Sockets.md index 710a95f..f993e83 100644 --- a/src/stdlib/Sockets.md +++ b/src/stdlib/Sockets.md @@ -5,6 +5,7 @@ DocTestSetup = :(using Sockets) ``` ```@docs +Sockets.Sockets Sockets.connect(::TCPSocket, ::Integer) Sockets.connect(::AbstractString) Sockets.listen(::Any) @@ -16,8 +17,10 @@ Sockets.getalladdrinfo Sockets.getnameinfo Sockets.getsockname Sockets.getpeername +Sockets.IPAddr Sockets.IPv4 Sockets.IPv6 +Sockets.@ip_str Sockets.TCPSocket Sockets.UDPSocket Sockets.accept From a85aa5e3daebdb545bdf6335e6170d8706ceb9be Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Fri, 8 Mar 2019 20:23:56 +0900 Subject: [PATCH 103/153] update Julia 1.2.0-DEV.444 (2019-03-08) Commit 95a52a5d62 --- codex/NEWS.md | 1 + codex/stdlib/Distributed.md | 2 ++ codex/stdlib/LinearAlgebra.md | 2 ++ codex/stdlib/Pkg.md | 2 ++ codex/stdlib/Random.md | 5 +++++ codex/stdlib/SharedArrays.md | 2 ++ src/NEWS.md | 1 + src/stdlib/Distributed.md | 2 ++ src/stdlib/LinearAlgebra.md | 2 ++ src/stdlib/Pkg.md | 2 ++ src/stdlib/Random.md | 5 +++++ src/stdlib/SharedArrays.md | 2 ++ 12 files changed, 28 insertions(+) diff --git a/codex/NEWS.md b/codex/NEWS.md index ea8778d..17cfa45 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -43,6 +43,7 @@ Standard library changes * `hasmethod` can now check for matching keyword argument names ([#30712](https://github.com/JuliaLang/julia/issues/30712)). * `startswith` and `endswith` now accept a `Regex` for the second argument ([#29790](https://github.com/JuliaLang/julia/issues/29790)). * `retry` supports arbitrary callable objects ([#30382](https://github.com/JuliaLang/julia/issues/30382)). +* `filter` now supports `SkipMissing`-wrapped arrays ([#31235](https://github.com/JuliaLang/julia/issues/31235)). * A no-argument construct to `Ptr{T}` has been added which constructs a null pointer ([#30919](https://github.com/JuliaLang/julia/issues/30919)) * `strip` now accepts a function argument in the same manner as `lstrip` and `rstrip` ([#31211](https://github.com/JuliaLang/julia/issues/31211)) diff --git a/codex/stdlib/Distributed.md b/codex/stdlib/Distributed.md index 3ecbd51..eea3dbb 100644 --- a/codex/stdlib/Distributed.md +++ b/codex/stdlib/Distributed.md @@ -60,6 +60,8 @@ same host, and `SSHManager`, for launching on remote hosts via `ssh`. TCP/IP soc and transport messages between processes. It is possible for Cluster Managers to provide a different transport. ```@docs +Distributed.ClusterManager +Distributed.WorkerConfig Distributed.launch Distributed.manage Distributed.kill(::ClusterManager, ::Int, ::WorkerConfig) diff --git a/codex/stdlib/LinearAlgebra.md b/codex/stdlib/LinearAlgebra.md index afe31b5..e929bbe 100644 --- a/codex/stdlib/LinearAlgebra.md +++ b/codex/stdlib/LinearAlgebra.md @@ -304,6 +304,8 @@ Linear algebra functions in Julia are largely implemented by calling functions f ```@docs Base.:*(::AbstractMatrix, ::AbstractMatrix) Base.:\(::AbstractMatrix, ::AbstractVecOrMat) +LinearAlgebra.SingularException +LinearAlgebra.PosDefException LinearAlgebra.dot LinearAlgebra.cross LinearAlgebra.factorize diff --git a/codex/stdlib/Pkg.md b/codex/stdlib/Pkg.md index e5c14ac..354235c 100644 --- a/codex/stdlib/Pkg.md +++ b/codex/stdlib/Pkg.md @@ -13,5 +13,7 @@ import Markdown file = joinpath(Sys.STDLIB, "Pkg", "docs", "src", "getting-started.md") str = read(file, String) str = replace(str, r"^#.*$"m => "") +str = replace(str, "[API Reference](@ref)" => + "[API Reference](https://julialang.github.io/Pkg.jl/v1/api/)") Markdown.parse(str) ``` diff --git a/codex/stdlib/Random.md b/codex/stdlib/Random.md index d150b53..f321901 100644 --- a/codex/stdlib/Random.md +++ b/codex/stdlib/Random.md @@ -26,6 +26,10 @@ unbounded integers, the interval must be specified (e.g. `rand(big.(1:6))`). Additionally, normal and exponential distributions are implemented for some `AbstractFloat` and `Complex` types, see [`randn`](@ref) and [`randexp`](@ref) for details. +## Random numbers module +```@docs +Random.Random +``` ## Random generation functions @@ -57,6 +61,7 @@ Random.shuffle! ```@docs Random.seed! +Random.AbstractRNG Random.MersenneTwister Random.RandomDevice ``` diff --git a/codex/stdlib/SharedArrays.md b/codex/stdlib/SharedArrays.md index bac1cd0..7b23ec1 100644 --- a/codex/stdlib/SharedArrays.md +++ b/codex/stdlib/SharedArrays.md @@ -2,6 +2,8 @@ ```@docs SharedArrays.SharedArray +SharedArrays.SharedVector +SharedArrays.SharedMatrix SharedArrays.procs(::SharedArray) SharedArrays.sdata SharedArrays.indexpids diff --git a/src/NEWS.md b/src/NEWS.md index ea8778d..17cfa45 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -43,6 +43,7 @@ Standard library changes * `hasmethod` can now check for matching keyword argument names ([#30712](https://github.com/JuliaLang/julia/issues/30712)). * `startswith` and `endswith` now accept a `Regex` for the second argument ([#29790](https://github.com/JuliaLang/julia/issues/29790)). * `retry` supports arbitrary callable objects ([#30382](https://github.com/JuliaLang/julia/issues/30382)). +* `filter` now supports `SkipMissing`-wrapped arrays ([#31235](https://github.com/JuliaLang/julia/issues/31235)). * A no-argument construct to `Ptr{T}` has been added which constructs a null pointer ([#30919](https://github.com/JuliaLang/julia/issues/30919)) * `strip` now accepts a function argument in the same manner as `lstrip` and `rstrip` ([#31211](https://github.com/JuliaLang/julia/issues/31211)) diff --git a/src/stdlib/Distributed.md b/src/stdlib/Distributed.md index 3ecbd51..eea3dbb 100644 --- a/src/stdlib/Distributed.md +++ b/src/stdlib/Distributed.md @@ -60,6 +60,8 @@ same host, and `SSHManager`, for launching on remote hosts via `ssh`. TCP/IP soc and transport messages between processes. It is possible for Cluster Managers to provide a different transport. ```@docs +Distributed.ClusterManager +Distributed.WorkerConfig Distributed.launch Distributed.manage Distributed.kill(::ClusterManager, ::Int, ::WorkerConfig) diff --git a/src/stdlib/LinearAlgebra.md b/src/stdlib/LinearAlgebra.md index afe31b5..e929bbe 100644 --- a/src/stdlib/LinearAlgebra.md +++ b/src/stdlib/LinearAlgebra.md @@ -304,6 +304,8 @@ Linear algebra functions in Julia are largely implemented by calling functions f ```@docs Base.:*(::AbstractMatrix, ::AbstractMatrix) Base.:\(::AbstractMatrix, ::AbstractVecOrMat) +LinearAlgebra.SingularException +LinearAlgebra.PosDefException LinearAlgebra.dot LinearAlgebra.cross LinearAlgebra.factorize diff --git a/src/stdlib/Pkg.md b/src/stdlib/Pkg.md index e5c14ac..354235c 100644 --- a/src/stdlib/Pkg.md +++ b/src/stdlib/Pkg.md @@ -13,5 +13,7 @@ import Markdown file = joinpath(Sys.STDLIB, "Pkg", "docs", "src", "getting-started.md") str = read(file, String) str = replace(str, r"^#.*$"m => "") +str = replace(str, "[API Reference](@ref)" => + "[API Reference](https://julialang.github.io/Pkg.jl/v1/api/)") Markdown.parse(str) ``` diff --git a/src/stdlib/Random.md b/src/stdlib/Random.md index d150b53..f321901 100644 --- a/src/stdlib/Random.md +++ b/src/stdlib/Random.md @@ -26,6 +26,10 @@ unbounded integers, the interval must be specified (e.g. `rand(big.(1:6))`). Additionally, normal and exponential distributions are implemented for some `AbstractFloat` and `Complex` types, see [`randn`](@ref) and [`randexp`](@ref) for details. +## Random numbers module +```@docs +Random.Random +``` ## Random generation functions @@ -57,6 +61,7 @@ Random.shuffle! ```@docs Random.seed! +Random.AbstractRNG Random.MersenneTwister Random.RandomDevice ``` diff --git a/src/stdlib/SharedArrays.md b/src/stdlib/SharedArrays.md index bac1cd0..7b23ec1 100644 --- a/src/stdlib/SharedArrays.md +++ b/src/stdlib/SharedArrays.md @@ -2,6 +2,8 @@ ```@docs SharedArrays.SharedArray +SharedArrays.SharedVector +SharedArrays.SharedMatrix SharedArrays.procs(::SharedArray) SharedArrays.sdata SharedArrays.indexpids From 3e88bf3ac82bf239723d63fce5171bf27b196b1e Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Wed, 13 Mar 2019 23:35:43 +0900 Subject: [PATCH 104/153] update Julia 1.2.0-DEV.462 (2019-03-13) Commit 4e2c90c2a5 --- codex/base/base.md | 2 ++ codex/devdocs/ast.md | 5 +++-- codex/stdlib/LinearAlgebra.md | 3 +++ src/base/base.md | 2 ++ src/devdocs/ast.md | 5 +++-- src/stdlib/LinearAlgebra.md | 3 +++ 6 files changed, 16 insertions(+), 4 deletions(-) diff --git a/codex/base/base.md b/codex/base/base.md index ed75d27..1e91082 100644 --- a/codex/base/base.md +++ b/codex/base/base.md @@ -306,6 +306,8 @@ Base.Sys.isnetbsd Base.Sys.isdragonfly Base.Sys.iswindows Base.Sys.windows_version +Base.Sys.free_memory +Base.Sys.total_memory Base.@static ``` diff --git a/codex/devdocs/ast.md b/codex/devdocs/ast.md index b2593f9..ef8860e 100644 --- a/codex/devdocs/ast.md +++ b/codex/devdocs/ast.md @@ -452,9 +452,10 @@ These symbols appear in the `head` field of [`Expr`](@ref)s in lowered form. Has the value `false` if inlined into a section of code marked with `@inbounds`, otherwise has the value `true`. - * `simdloop` + * `loopinfo` - Marks the end of the inner loop of a `@simd` expression. + Marks the end of the a loop. Contains metadata that is passed to `LowerSimdLoop` to either mark + the inner loop of `@simd` expression, or to propagate information to LLVM loop passes. * `copyast` diff --git a/codex/stdlib/LinearAlgebra.md b/codex/stdlib/LinearAlgebra.md index e929bbe..81faa64 100644 --- a/codex/stdlib/LinearAlgebra.md +++ b/codex/stdlib/LinearAlgebra.md @@ -422,8 +422,10 @@ LinearAlgebra.isdiag LinearAlgebra.ishermitian Base.transpose LinearAlgebra.transpose! +LinearAlgebra.Transpose Base.adjoint LinearAlgebra.adjoint! +LinearAlgebra.Adjoint Base.copy(::Union{Transpose,Adjoint}) LinearAlgebra.stride1 LinearAlgebra.checksquare @@ -499,6 +501,7 @@ LinearAlgebra.BLAS.asum LinearAlgebra.axpy! LinearAlgebra.BLAS.scal! LinearAlgebra.BLAS.scal +LinearAlgebra.BLAS.iamax LinearAlgebra.BLAS.ger! LinearAlgebra.BLAS.syr! LinearAlgebra.BLAS.syrk! diff --git a/src/base/base.md b/src/base/base.md index ed75d27..1e91082 100644 --- a/src/base/base.md +++ b/src/base/base.md @@ -306,6 +306,8 @@ Base.Sys.isnetbsd Base.Sys.isdragonfly Base.Sys.iswindows Base.Sys.windows_version +Base.Sys.free_memory +Base.Sys.total_memory Base.@static ``` diff --git a/src/devdocs/ast.md b/src/devdocs/ast.md index b2593f9..ef8860e 100644 --- a/src/devdocs/ast.md +++ b/src/devdocs/ast.md @@ -452,9 +452,10 @@ These symbols appear in the `head` field of [`Expr`](@ref)s in lowered form. Has the value `false` if inlined into a section of code marked with `@inbounds`, otherwise has the value `true`. - * `simdloop` + * `loopinfo` - Marks the end of the inner loop of a `@simd` expression. + Marks the end of the a loop. Contains metadata that is passed to `LowerSimdLoop` to either mark + the inner loop of `@simd` expression, or to propagate information to LLVM loop passes. * `copyast` diff --git a/src/stdlib/LinearAlgebra.md b/src/stdlib/LinearAlgebra.md index e929bbe..81faa64 100644 --- a/src/stdlib/LinearAlgebra.md +++ b/src/stdlib/LinearAlgebra.md @@ -422,8 +422,10 @@ LinearAlgebra.isdiag LinearAlgebra.ishermitian Base.transpose LinearAlgebra.transpose! +LinearAlgebra.Transpose Base.adjoint LinearAlgebra.adjoint! +LinearAlgebra.Adjoint Base.copy(::Union{Transpose,Adjoint}) LinearAlgebra.stride1 LinearAlgebra.checksquare @@ -499,6 +501,7 @@ LinearAlgebra.BLAS.asum LinearAlgebra.axpy! LinearAlgebra.BLAS.scal! LinearAlgebra.BLAS.scal +LinearAlgebra.BLAS.iamax LinearAlgebra.BLAS.ger! LinearAlgebra.BLAS.syr! LinearAlgebra.BLAS.syrk! From cda0b6fc61051efdb788b89a5ba3d42eac334698 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Thu, 21 Mar 2019 11:43:15 +0900 Subject: [PATCH 105/153] fix contrib/html_writer.jl, update Julia 1.2.0-DEV.515 (2019-03-19) Commit b207c01563 --- codex/base/base.md | 1 + codex/base/collections.md | 2 ++ codex/devdocs/boundscheck.md | 5 ++-- codex/manual/control-flow.md | 4 +-- codex/manual/noteworthy-differences.md | 9 ++++-- codex/stdlib/Base64.md | 1 + contrib/html_writer.jl | 3 +- make.jl | 39 +++++++++++++++++++------- src/base/base.md | 1 + src/base/collections.md | 2 ++ src/devdocs/boundscheck.md | 5 ++-- src/manual/control-flow.md | 8 ++---- src/manual/noteworthy-differences.md | 9 ++++-- src/stdlib/Base64.md | 1 + 14 files changed, 60 insertions(+), 30 deletions(-) diff --git a/codex/base/base.md b/codex/base/base.md index 1e91082..027fe21 100644 --- a/codex/base/base.md +++ b/codex/base/base.md @@ -243,6 +243,7 @@ Base.evalfile Base.esc Base.@inbounds Base.@boundscheck +Base.@propagate_inbounds Base.@inline Base.@noinline Base.@nospecialize diff --git a/codex/base/collections.md b/codex/base/collections.md index 2e5ad94..d947786 100644 --- a/codex/base/collections.md +++ b/codex/base/collections.md @@ -128,6 +128,8 @@ Base.mapfoldl(::Any, ::Any, ::Any) Base.mapfoldr(::Any, ::Any, ::Any) Base.first Base.last +Base.front +Base.tail Base.step Base.collect(::Any) Base.collect(::Type, ::Any) diff --git a/codex/devdocs/boundscheck.md b/codex/devdocs/boundscheck.md index 669cb52..a9fb3ba 100644 --- a/codex/devdocs/boundscheck.md +++ b/codex/devdocs/boundscheck.md @@ -43,8 +43,9 @@ between the `@inbounds` and `@boundscheck` declarations. For instance, the defau methods have the chain `getindex(A::AbstractArray, i::Real)` calls `getindex(IndexStyle(A), A, i)` calls `_getindex(::IndexLinear, A, i)`. -To override the "one layer of inlining" rule, a function may be marked with `@propagate_inbounds` -to propagate an inbounds context (or out of bounds context) through one additional layer of inlining. +To override the "one layer of inlining" rule, a function may be marked with +[`Base.@propagate_inbounds`](@ref) to propagate an inbounds context (or out of bounds +context) through one additional layer of inlining. ## The bounds checking call hierarchy diff --git a/codex/manual/control-flow.md b/codex/manual/control-flow.md index a8611b4..13dc4ac 100644 --- a/codex/manual/control-flow.md +++ b/codex/manual/control-flow.md @@ -981,8 +981,6 @@ symbols: | Symbol | Meaning | |:----------- |:-------------------------------------------------- | -| `:runnable` | Currently running, or available to be switched to | -| `:waiting` | Blocked waiting for a specific event | -| `:queued` | In the scheduler's run queue about to be restarted | +| `:runnable` | Currently running, or able to run | | `:done` | Successfully finished executing | | `:failed` | Finished with an uncaught exception | diff --git a/codex/manual/noteworthy-differences.md b/codex/manual/noteworthy-differences.md index bd24907..fe53689 100644 --- a/codex/manual/noteworthy-differences.md +++ b/codex/manual/noteworthy-differences.md @@ -18,9 +18,9 @@ may trip up Julia users accustomed to MATLAB: which grow `Vector`s much more efficiently than MATLAB's `a(end+1) = val`. * The imaginary unit `sqrt(-1)` is represented in Julia as [`im`](@ref), not `i` or `j` as in MATLAB. * In Julia, literal numbers without a decimal point (such as `42`) create integers instead of floating - point numbers. Arbitrarily large integer literals are supported. As a result, some operations - such as `2^-1` will throw a domain error as the result is not an integer (see [the FAQ entry on domain errors](@ref faq-domain-errors) - for details). + point numbers. As a result, some operations can throw + a domain error if they expect a float; for example, `julia> a = -1; 2^a` throws a domain error, as the + result is not an integer (see [the FAQ entry on domain errors](@ref faq-domain-errors) for details). * In Julia, multiple values are returned and assigned as tuples, e.g. `(a, b) = (1, 2)` or `a, b = 1, 2`. MATLAB's `nargout`, which is often used in MATLAB to do optional work based on the number of returned values, does not exist in Julia. Instead, users can use optional and keyword arguments to achieve @@ -220,6 +220,9 @@ For users coming to Julia from R, these are some noteworthy differences: On the other hand, the function `g(x=[1,2]) = push!(x,3)` returns `[1,2,3]` every time it is called as `g()`. * In Julia `%` is the remainder operator, whereas in Python it is the modulus. + * The commonly used `Int` type corresponds to the machine integer type (`Int32` or `Int64`). + This means it will overflow, such that `2^64 == 0`. If you need larger values use another appropriate type, + such as `Int128`, [`BigInt`](@ref) or a floating point type like `Float64`. ## Noteworthy differences from C/C++ diff --git a/codex/stdlib/Base64.md b/codex/stdlib/Base64.md index b179de0..163be19 100644 --- a/codex/stdlib/Base64.md +++ b/codex/stdlib/Base64.md @@ -5,6 +5,7 @@ DocTestSetup = :(using Base64) ``` ```@docs +Base64.Base64 Base64.Base64EncodePipe Base64.base64encode Base64.Base64DecodePipe diff --git a/contrib/html_writer.jl b/contrib/html_writer.jl index 5de607c..e1c316f 100644 --- a/contrib/html_writer.jl +++ b/contrib/html_writer.jl @@ -27,14 +27,13 @@ function Documenter.Writers.HTMLWriter.render_head(ctx, navnode) meta[:name => "viewport", :content => "width=device-width, initial-scale=1.0"], title(page_title), - analytics_script(ctx.doc.user.analytics), + analytics_script(ctx.settings.analytics), canonical_link_element(ctx.settings.canonical, src), # Stylesheets. map(css_links) do each link[:href => each, :rel => "stylesheet", :type => "text/css"] - end, script("documenterBaseURL=\"$(relhref(src, "."))\""), diff --git a/make.jl b/make.jl index bdfac97..124a6bf 100644 --- a/make.jl +++ b/make.jl @@ -12,21 +12,40 @@ if !isdir(joinpath(@__DIR__, "deps", "packages", "Documenter")) || "deps" in ARG end using Documenter -include("contrib/html_writer.jl") +include("contrib/html_writer.jl") # Korean customize baremodule GenStdLib end -# make links for stdlib package docs, this is needed until #522 in Documenter.jl is finished +# Documenter Setup. + +symlink_q(tgt, link) = isfile(link) || symlink(tgt, link) +cp_q(src, dest) = isfile(dest) || cp(src, dest) + +# make links for stdlib package docs, this is needed until #552 in Documenter.jl is finished +const STDLIB_DOCS = [] const STDLIB_DIR = Sys.STDLIB -const STDLIB_DOCS = filter(!ismissing, map(readdir(STDLIB_DIR)) do dir - sourcefile = joinpath(STDLIB_DIR, dir, "docs", "src", "index.md") - if isfile(sourcefile) - targetfile = joinpath("stdlib", dir * ".md") - (stdlib = Symbol(dir), targetfile = targetfile,) - else - missing +const EXT_STDLIB_DOCS = ["Pkg"] +cd(joinpath(@__DIR__, "src")) do + # Base.rm("stdlib"; recursive=true, force=true) + # mkdir("stdlib") + for dir in readdir(STDLIB_DIR) + sourcefile = joinpath(STDLIB_DIR, dir, "docs", "src") + if dir in EXT_STDLIB_DOCS + sourcefile = joinpath(sourcefile, "basedocs.md") + else + sourcefile = joinpath(sourcefile, "index.md") + end + if isfile(sourcefile) + targetfile = joinpath("stdlib", dir * ".md") + push!(STDLIB_DOCS, (stdlib = Symbol(dir), targetfile = targetfile)) + # if Sys.iswindows() + # cp_q(sourcefile, targetfile) + # else + # symlink_q(sourcefile, targetfile) + # end + end end -end) +end # Korean text in PAGES const t_Home = "홈" diff --git a/src/base/base.md b/src/base/base.md index 1e91082..027fe21 100644 --- a/src/base/base.md +++ b/src/base/base.md @@ -243,6 +243,7 @@ Base.evalfile Base.esc Base.@inbounds Base.@boundscheck +Base.@propagate_inbounds Base.@inline Base.@noinline Base.@nospecialize diff --git a/src/base/collections.md b/src/base/collections.md index 2e5ad94..d947786 100644 --- a/src/base/collections.md +++ b/src/base/collections.md @@ -128,6 +128,8 @@ Base.mapfoldl(::Any, ::Any, ::Any) Base.mapfoldr(::Any, ::Any, ::Any) Base.first Base.last +Base.front +Base.tail Base.step Base.collect(::Any) Base.collect(::Type, ::Any) diff --git a/src/devdocs/boundscheck.md b/src/devdocs/boundscheck.md index 669cb52..a9fb3ba 100644 --- a/src/devdocs/boundscheck.md +++ b/src/devdocs/boundscheck.md @@ -43,8 +43,9 @@ between the `@inbounds` and `@boundscheck` declarations. For instance, the defau methods have the chain `getindex(A::AbstractArray, i::Real)` calls `getindex(IndexStyle(A), A, i)` calls `_getindex(::IndexLinear, A, i)`. -To override the "one layer of inlining" rule, a function may be marked with `@propagate_inbounds` -to propagate an inbounds context (or out of bounds context) through one additional layer of inlining. +To override the "one layer of inlining" rule, a function may be marked with +[`Base.@propagate_inbounds`](@ref) to propagate an inbounds context (or out of bounds +context) through one additional layer of inlining. ## The bounds checking call hierarchy diff --git a/src/manual/control-flow.md b/src/manual/control-flow.md index f86478c..1cc82f5 100644 --- a/src/manual/control-flow.md +++ b/src/manual/control-flow.md @@ -819,8 +819,6 @@ taskHdl = @task mytask(7) | 상태 | 의미 | |:----------- |:----------------------------------------------- | -| `:runnable` | 현재 실행 중이거나 전환할 수 있는 상태 | -| `:waiting` | 특정 이벤트를 기다리고 있어 블록된 상태 | -| `:queued` | 스케줄러의 실행 대기열에 있어 곧 다시 시작될 상태 | -| `:done` | 실행을 성공적으로 완료한 상태 | -| `:failed` | 알 수 없는 예외로 종료된 상태 | +| `:runnable` | 현재 실행 중이거나 실행 가능한 상태 | +| `:done` | 실행을 성공적으로 완료한 상태 | +| `:failed` | 알 수 없는 예외로 종료된 상태 | diff --git a/src/manual/noteworthy-differences.md b/src/manual/noteworthy-differences.md index bd24907..fe53689 100644 --- a/src/manual/noteworthy-differences.md +++ b/src/manual/noteworthy-differences.md @@ -18,9 +18,9 @@ may trip up Julia users accustomed to MATLAB: which grow `Vector`s much more efficiently than MATLAB's `a(end+1) = val`. * The imaginary unit `sqrt(-1)` is represented in Julia as [`im`](@ref), not `i` or `j` as in MATLAB. * In Julia, literal numbers without a decimal point (such as `42`) create integers instead of floating - point numbers. Arbitrarily large integer literals are supported. As a result, some operations - such as `2^-1` will throw a domain error as the result is not an integer (see [the FAQ entry on domain errors](@ref faq-domain-errors) - for details). + point numbers. As a result, some operations can throw + a domain error if they expect a float; for example, `julia> a = -1; 2^a` throws a domain error, as the + result is not an integer (see [the FAQ entry on domain errors](@ref faq-domain-errors) for details). * In Julia, multiple values are returned and assigned as tuples, e.g. `(a, b) = (1, 2)` or `a, b = 1, 2`. MATLAB's `nargout`, which is often used in MATLAB to do optional work based on the number of returned values, does not exist in Julia. Instead, users can use optional and keyword arguments to achieve @@ -220,6 +220,9 @@ For users coming to Julia from R, these are some noteworthy differences: On the other hand, the function `g(x=[1,2]) = push!(x,3)` returns `[1,2,3]` every time it is called as `g()`. * In Julia `%` is the remainder operator, whereas in Python it is the modulus. + * The commonly used `Int` type corresponds to the machine integer type (`Int32` or `Int64`). + This means it will overflow, such that `2^64 == 0`. If you need larger values use another appropriate type, + such as `Int128`, [`BigInt`](@ref) or a floating point type like `Float64`. ## Noteworthy differences from C/C++ diff --git a/src/stdlib/Base64.md b/src/stdlib/Base64.md index b179de0..163be19 100644 --- a/src/stdlib/Base64.md +++ b/src/stdlib/Base64.md @@ -5,6 +5,7 @@ DocTestSetup = :(using Base64) ``` ```@docs +Base64.Base64 Base64.Base64EncodePipe Base64.base64encode Base64.Base64DecodePipe From 374b025044a3985c15de561522d350b14a4e3199 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Mon, 25 Mar 2019 17:25:59 +0900 Subject: [PATCH 106/153] comment deps --- make.jl | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/make.jl b/make.jl index 124a6bf..4092e3c 100644 --- a/make.jl +++ b/make.jl @@ -1,17 +1,16 @@ # code from https://github.com/JuliaLang/julia/blob/master/doc/make.jl # Install dependencies needed to build the documentation. -#empty!(LOAD_PATH) -push!(LOAD_PATH, @__DIR__, "@stdlib") -#empty!(DEPOT_PATH) -pushfirst!(DEPOT_PATH, joinpath(@__DIR__, "deps")) - -if !isdir(joinpath(@__DIR__, "deps", "packages", "Documenter")) || "deps" in ARGS - using Pkg - Pkg.instantiate() -end +# empty!(LOAD_PATH) +# push!(LOAD_PATH, @__DIR__, "@stdlib") +# empty!(DEPOT_PATH) +# pushfirst!(DEPOT_PATH, joinpath(@__DIR__, "deps")) +# using Pkg +# Pkg.instantiate() +# using Documenter, DocumenterLaTeX using Documenter + include("contrib/html_writer.jl") # Korean customize baremodule GenStdLib end From f6137046a3545c0902011487cad52498c4ce2e5f Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Mon, 25 Mar 2019 17:44:53 +0900 Subject: [PATCH 107/153] add buildroot --- make.jl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/make.jl b/make.jl index 4092e3c..287b71c 100644 --- a/make.jl +++ b/make.jl @@ -151,6 +151,11 @@ for stdlib in STDLIB_DOCS @eval using $(stdlib.stdlib) end +const render_pdf = "pdf" in ARGS +let r = r"buildroot=(.+)", i = findfirst(x -> occursin(r, x), ARGS) + global const buildroot = i === nothing ? (@__DIR__) : first(match(r, ARGS[i]).captures) +end + # Korean text for makedocs const t_sitename = "줄리아 언어" const t_analytics = "UA-110655381-2" # juliakorea analytic ID From 66062ef5a7094734de733893d3ecd6bd6cefa34f Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Mon, 25 Mar 2019 17:52:03 +0900 Subject: [PATCH 108/153] move analytics, assets --- make.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/make.jl b/make.jl index 287b71c..9fcbe8f 100644 --- a/make.jl +++ b/make.jl @@ -173,10 +173,10 @@ makedocs( format = Documenter.HTML( prettyurls = !("local" in ARGS), canonical = t_html_canonical, + analytics = t_analytics, + assets = ["assets/julia-manual.css", ], ), sitename = t_sitename, authors = "The Julia Project", - analytics = t_analytics, pages = PAGES, - assets = ["assets/julia-manual.css", ] ) From abd81b53298404eb63b561aad1273c25885e68ae Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Mon, 25 Mar 2019 17:59:03 +0900 Subject: [PATCH 109/153] strict=false --- make.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/make.jl b/make.jl index 9fcbe8f..8c309fb 100644 --- a/make.jl +++ b/make.jl @@ -168,7 +168,7 @@ makedocs( doctest = ("doctest=fix" in ARGS) ? (:fix) : ("doctest=true" in ARGS) ? true : false, linkcheck = "linkcheck=true" in ARGS, linkcheck_ignore = ["https://bugs.kde.org/show_bug.cgi?id=136779"], # fails to load from nanosoldier? - strict = true, + strict = false, # true, checkdocs = :none, format = Documenter.HTML( prettyurls = !("local" in ARGS), From 641748998ae9835fc7dd18b344fbc9ccaf319f34 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Sat, 30 Mar 2019 13:32:07 +0900 Subject: [PATCH 110/153] update Julia 1.2.0-DEV.578 (2019-03-29) Commit c2144276fb --- codex/NEWS.md | 3 ++ codex/base/libc.md | 1 + codex/devdocs/ast.md | 76 +++++++++++++++++++++++++------- codex/manual/methods.md | 2 +- codex/manual/performance-tips.md | 2 +- codex/manual/strings.md | 2 +- codex/stdlib/SparseArrays.md | 8 ++-- src/NEWS.md | 3 ++ src/base/libc.md | 1 + src/devdocs/ast.md | 76 +++++++++++++++++++++++++------- src/manual/methods.md | 2 +- src/manual/performance-tips.md | 2 +- src/manual/strings.md | 2 +- src/stdlib/SparseArrays.md | 8 ++-- 14 files changed, 144 insertions(+), 44 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index 17cfa45..ebf45cb 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -12,6 +12,8 @@ New language features `findall`, `findfirst`, `argmin`/`argmax` and `findmin`/`findmax` to work with these objects, returning the index of matching non-missing elements in the parent ([#31008](https://github.com/JuliaLang/julia/issues/31008)). + * `inv(::Missing)` has now been added and returns `missing` ([#31408](https://github.com/JuliaLang/julia/issues/31408)). + Multi-threading changes ----------------------- @@ -46,6 +48,7 @@ Standard library changes * `filter` now supports `SkipMissing`-wrapped arrays ([#31235](https://github.com/JuliaLang/julia/issues/31235)). * A no-argument construct to `Ptr{T}` has been added which constructs a null pointer ([#30919](https://github.com/JuliaLang/julia/issues/30919)) * `strip` now accepts a function argument in the same manner as `lstrip` and `rstrip` ([#31211](https://github.com/JuliaLang/julia/issues/31211)) +* `mktempdir` now accepts a `prefix` keyword argument to customize the file name ([#31230](https://github.com/JuliaLang/julia/issues/31230), [#22922](https://github.com/JuliaLang/julia/issues/22922)) #### LinearAlgebra diff --git a/codex/base/libc.md b/codex/base/libc.md index 65bdb3d..0af1b74 100644 --- a/codex/base/libc.md +++ b/codex/base/libc.md @@ -14,4 +14,5 @@ Base.Libc.strftime Base.Libc.strptime Base.Libc.TmStruct Base.Libc.flush_cstdio +Base.Libc.systemsleep ``` diff --git a/codex/devdocs/ast.md b/codex/devdocs/ast.md index ef8860e..4c79de3 100644 --- a/codex/devdocs/ast.md +++ b/codex/devdocs/ast.md @@ -260,7 +260,7 @@ types exist in lowered form: * `CodeInfo` - Wraps the IR of a method. Its `code` field is an array of expressions to execute. + Wraps the IR of a group of statements. Its `code` field is an array of expressions to execute. * `GotoNode` @@ -490,7 +490,11 @@ A unique'd container describing the shared metadata for a single method. * `source` - The original source code (usually compressed). + The original source code (if available, usually compressed). + + * `generator` + + A callable object which can be executed to get specialized source for a specific method signature. * `roots` @@ -501,9 +505,9 @@ A unique'd container describing the shared metadata for a single method. Descriptive bit-fields for the source code of this Method. - * `min_world` / `max_world` + * `primary_world` - The range of world ages for which this method is visible to dispatch. + The world age that "owns" this Method. ### MethodInstance @@ -528,16 +532,38 @@ for important details on how to modify these fields safely. runtime `MethodInstance` from the `MethodTable` cache, this will always be defined and indexable. - * `rettype` + * `uninferred` + + The uncompressed source code for a toplevel thunk. Additionally, for a generated function, + this is one of many places that the source code might be found. + + * `backedges` + + We store the reverse-list of cache dependencies for efficient tracking of incremental reanalysis/recompilation work that may be needed after a new method definitions. + This works by keeping a list of the other `MethodInstance` that have been inferred or optimized to contain a possible call to this `MethodInstance`. + Those optimization results might be stored somewhere in the `cache`, or it might have been the result of something we didn't want to cache, such as constant propagation. + Thus we merge all of those backedges to various cache entries here (there's almost always only the one applicable cache entry with a sentinal value for max_world anyways). + + * `cache` + + Cache of `CodeInstance` objects that share this template instantiation. + +### CodeInstance + + * `def` + + The `MethodInstance` that this cache entry is derived from. + + + * `rettype`/`rettype_const` The inferred return type for the `specFunctionObject` field, which (in most cases) is also the computed return type for the function in general. * `inferred` - May contain a cache of the inferred source for this function, or other information about - the inference result such as a constant return value may be put here (if `jlcall_api == - 2`), or it could be set to `nothing` to just indicate `rettype` is inferred. + May contain a cache of the inferred source for this function, + or it could be set to `nothing` to just indicate `rettype` is inferred. * `ftpr` @@ -549,18 +575,20 @@ for important details on how to modify these fields safely. * 0 - Not compiled yet * 1 - JL_CALLABLE `jl_value_t *(*)(jl_function_t *f, jl_value_t *args[nargs], uint32_t nargs)` - * 2 - Constant (value stored in `inferred`) + * 2 - Constant (value stored in `rettype_const`) * 3 - With Static-parameters forwarded `jl_value_t *(*)(jl_svec_t *sparams, jl_function_t *f, jl_value_t *args[nargs], uint32_t nargs)` * 4 - Run in interpreter `jl_value_t *(*)(jl_method_instance_t *meth, jl_function_t *f, jl_value_t *args[nargs], uint32_t nargs)` * `min_world` / `max_world` The range of world ages for which this method instance is valid to be called. + If max_world is the special token value `-1`, the value is not yet known. + It may continue to be used until we encounter a backedge that requires us to reconsider. ### CodeInfo -A temporary container for holding lowered source code. +A (usually temporary) container for holding lowered source code. * `code` @@ -568,11 +596,11 @@ A temporary container for holding lowered source code. * `slotnames` - An array of symbols giving the name of each slot (argument or local variable). + An array of symbols giving names for each slot (argument or local variable). * `slottypes` - An array of types for the slots. + An array of types for the slots (e.g. variables). * `slotflags` @@ -588,7 +616,17 @@ A temporary container for holding lowered source code. Either an array or an `Int`. If an `Int`, it gives the number of compiler-inserted temporary locations in the - function. If an array, specifies a type for each location. + function (the length of `code` array). If an array, specifies a type for each location. + + * `ssaflags` + + Statement-level flags for each expression in the function. Many of these are reserved, but not yet implemented: + + * 0 = inbounds + * 1,2 = inlinehint,always-inline,noinline + * 3 = strict-ieee (strictfp) + * 4-6 = + * 7 = has out-of-band info * `linetable` @@ -599,6 +637,14 @@ A temporary container for holding lowered source code. An array of integer indices into the `linetable`, giving the location associated with each statement. + * `parent` + + The `MethodInstance` that "owns" this object (if applicable). + + * `min_world`/`max_world` + + The range of world ages for which this code was valid at the time when it had been inferred. + Boolean properties: * `inferred` @@ -607,11 +653,11 @@ Boolean properties: * `inlineable` - Whether this should be inlined. + Whether this should be eligible for inlining. * `propagate_inbounds` - Whether this should should propagate `@inbounds` when inlined for the purpose of eliding + Whether this should should propagate `@inbounds` when inlined, for the purpose of eliding `@boundscheck` blocks. * `pure` diff --git a/codex/manual/methods.md b/codex/manual/methods.md index 31dea86..07f0c99 100644 --- a/codex/manual/methods.md +++ b/codex/manual/methods.md @@ -727,7 +727,7 @@ function matmul(a::AbstractMatrix, b::AbstractMatrix) output = similar(b, R, (size(a, 1), size(b, 2))) if size(a, 2) > 0 for j in 1:size(b, 2) - for i in 1:size(b, 1) + for i in 1:size(a, 1) ## here we don't use `ab = zero(R)`, ## since `R` might be `Any` and `zero(Any)` is not defined ## we also must declare `ab::R` to make the type of `ab` constant in the loop, diff --git a/codex/manual/performance-tips.md b/codex/manual/performance-tips.md index 71a5234..e043055 100644 --- a/codex/manual/performance-tips.md +++ b/codex/manual/performance-tips.md @@ -830,7 +830,7 @@ julia> x = randn(10000); julia> fmt(f) = println(rpad(string(f)*": ", 14, ' '), @elapsed f(x)) -julia> map(fmt, Any[copy_cols, copy_rows, copy_col_row, copy_row_col]); +julia> map(fmt, [copy_cols, copy_rows, copy_col_row, copy_row_col]); copy_cols: 0.331706323 copy_rows: 1.799009911 copy_col_row: 0.415630047 diff --git a/codex/manual/strings.md b/codex/manual/strings.md index d77486b..1010baa 100644 --- a/codex/manual/strings.md +++ b/codex/manual/strings.md @@ -747,7 +747,7 @@ are given in the [Metaprogramming](@ref) section. ## Regular Expressions Julia has Perl-compatible regular expressions (regexes), as provided by the [PCRE](http://www.pcre.org/) -library. Regular expressions are related to strings in two ways: the obvious connection is that +library (a description of the syntax can be found [here](http://www.pcre.org/current/doc/html/pcre2syntax.html)). Regular expressions are related to strings in two ways: the obvious connection is that regular expressions are used to find regular patterns in strings; the other connection is that regular expressions are themselves input as strings, which are parsed into a state machine that can be used to efficiently search for patterns in strings. In Julia, regular expressions are input diff --git a/codex/stdlib/SparseArrays.md b/codex/stdlib/SparseArrays.md index af1be79..d4eaebd 100644 --- a/codex/stdlib/SparseArrays.md +++ b/codex/stdlib/SparseArrays.md @@ -104,10 +104,10 @@ julia> I = [1, 4, 3, 5]; J = [4, 7, 18, 9]; V = [1, 2, -5, 3]; julia> S = sparse(I,J,V) 5×18 SparseMatrixCSC{Int64,Int64} with 4 stored entries: - [1 , 4] = 1 - [4 , 7] = 2 - [5 , 9] = 3 - [3 , 18] = -5 + [1, 4] = 1 + [4, 7] = 2 + [5, 9] = 3 + [3, 18] = -5 julia> R = sparsevec(I,V) 5-element SparseVector{Int64,Int64} with 4 stored entries: diff --git a/src/NEWS.md b/src/NEWS.md index 17cfa45..ebf45cb 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -12,6 +12,8 @@ New language features `findall`, `findfirst`, `argmin`/`argmax` and `findmin`/`findmax` to work with these objects, returning the index of matching non-missing elements in the parent ([#31008](https://github.com/JuliaLang/julia/issues/31008)). + * `inv(::Missing)` has now been added and returns `missing` ([#31408](https://github.com/JuliaLang/julia/issues/31408)). + Multi-threading changes ----------------------- @@ -46,6 +48,7 @@ Standard library changes * `filter` now supports `SkipMissing`-wrapped arrays ([#31235](https://github.com/JuliaLang/julia/issues/31235)). * A no-argument construct to `Ptr{T}` has been added which constructs a null pointer ([#30919](https://github.com/JuliaLang/julia/issues/30919)) * `strip` now accepts a function argument in the same manner as `lstrip` and `rstrip` ([#31211](https://github.com/JuliaLang/julia/issues/31211)) +* `mktempdir` now accepts a `prefix` keyword argument to customize the file name ([#31230](https://github.com/JuliaLang/julia/issues/31230), [#22922](https://github.com/JuliaLang/julia/issues/22922)) #### LinearAlgebra diff --git a/src/base/libc.md b/src/base/libc.md index 65bdb3d..0af1b74 100644 --- a/src/base/libc.md +++ b/src/base/libc.md @@ -14,4 +14,5 @@ Base.Libc.strftime Base.Libc.strptime Base.Libc.TmStruct Base.Libc.flush_cstdio +Base.Libc.systemsleep ``` diff --git a/src/devdocs/ast.md b/src/devdocs/ast.md index ef8860e..4c79de3 100644 --- a/src/devdocs/ast.md +++ b/src/devdocs/ast.md @@ -260,7 +260,7 @@ types exist in lowered form: * `CodeInfo` - Wraps the IR of a method. Its `code` field is an array of expressions to execute. + Wraps the IR of a group of statements. Its `code` field is an array of expressions to execute. * `GotoNode` @@ -490,7 +490,11 @@ A unique'd container describing the shared metadata for a single method. * `source` - The original source code (usually compressed). + The original source code (if available, usually compressed). + + * `generator` + + A callable object which can be executed to get specialized source for a specific method signature. * `roots` @@ -501,9 +505,9 @@ A unique'd container describing the shared metadata for a single method. Descriptive bit-fields for the source code of this Method. - * `min_world` / `max_world` + * `primary_world` - The range of world ages for which this method is visible to dispatch. + The world age that "owns" this Method. ### MethodInstance @@ -528,16 +532,38 @@ for important details on how to modify these fields safely. runtime `MethodInstance` from the `MethodTable` cache, this will always be defined and indexable. - * `rettype` + * `uninferred` + + The uncompressed source code for a toplevel thunk. Additionally, for a generated function, + this is one of many places that the source code might be found. + + * `backedges` + + We store the reverse-list of cache dependencies for efficient tracking of incremental reanalysis/recompilation work that may be needed after a new method definitions. + This works by keeping a list of the other `MethodInstance` that have been inferred or optimized to contain a possible call to this `MethodInstance`. + Those optimization results might be stored somewhere in the `cache`, or it might have been the result of something we didn't want to cache, such as constant propagation. + Thus we merge all of those backedges to various cache entries here (there's almost always only the one applicable cache entry with a sentinal value for max_world anyways). + + * `cache` + + Cache of `CodeInstance` objects that share this template instantiation. + +### CodeInstance + + * `def` + + The `MethodInstance` that this cache entry is derived from. + + + * `rettype`/`rettype_const` The inferred return type for the `specFunctionObject` field, which (in most cases) is also the computed return type for the function in general. * `inferred` - May contain a cache of the inferred source for this function, or other information about - the inference result such as a constant return value may be put here (if `jlcall_api == - 2`), or it could be set to `nothing` to just indicate `rettype` is inferred. + May contain a cache of the inferred source for this function, + or it could be set to `nothing` to just indicate `rettype` is inferred. * `ftpr` @@ -549,18 +575,20 @@ for important details on how to modify these fields safely. * 0 - Not compiled yet * 1 - JL_CALLABLE `jl_value_t *(*)(jl_function_t *f, jl_value_t *args[nargs], uint32_t nargs)` - * 2 - Constant (value stored in `inferred`) + * 2 - Constant (value stored in `rettype_const`) * 3 - With Static-parameters forwarded `jl_value_t *(*)(jl_svec_t *sparams, jl_function_t *f, jl_value_t *args[nargs], uint32_t nargs)` * 4 - Run in interpreter `jl_value_t *(*)(jl_method_instance_t *meth, jl_function_t *f, jl_value_t *args[nargs], uint32_t nargs)` * `min_world` / `max_world` The range of world ages for which this method instance is valid to be called. + If max_world is the special token value `-1`, the value is not yet known. + It may continue to be used until we encounter a backedge that requires us to reconsider. ### CodeInfo -A temporary container for holding lowered source code. +A (usually temporary) container for holding lowered source code. * `code` @@ -568,11 +596,11 @@ A temporary container for holding lowered source code. * `slotnames` - An array of symbols giving the name of each slot (argument or local variable). + An array of symbols giving names for each slot (argument or local variable). * `slottypes` - An array of types for the slots. + An array of types for the slots (e.g. variables). * `slotflags` @@ -588,7 +616,17 @@ A temporary container for holding lowered source code. Either an array or an `Int`. If an `Int`, it gives the number of compiler-inserted temporary locations in the - function. If an array, specifies a type for each location. + function (the length of `code` array). If an array, specifies a type for each location. + + * `ssaflags` + + Statement-level flags for each expression in the function. Many of these are reserved, but not yet implemented: + + * 0 = inbounds + * 1,2 = inlinehint,always-inline,noinline + * 3 = strict-ieee (strictfp) + * 4-6 = + * 7 = has out-of-band info * `linetable` @@ -599,6 +637,14 @@ A temporary container for holding lowered source code. An array of integer indices into the `linetable`, giving the location associated with each statement. + * `parent` + + The `MethodInstance` that "owns" this object (if applicable). + + * `min_world`/`max_world` + + The range of world ages for which this code was valid at the time when it had been inferred. + Boolean properties: * `inferred` @@ -607,11 +653,11 @@ Boolean properties: * `inlineable` - Whether this should be inlined. + Whether this should be eligible for inlining. * `propagate_inbounds` - Whether this should should propagate `@inbounds` when inlined for the purpose of eliding + Whether this should should propagate `@inbounds` when inlined, for the purpose of eliding `@boundscheck` blocks. * `pure` diff --git a/src/manual/methods.md b/src/manual/methods.md index 824694b..5fa1494 100644 --- a/src/manual/methods.md +++ b/src/manual/methods.md @@ -634,7 +634,7 @@ function matmul(a::AbstractMatrix, b::AbstractMatrix) output = similar(b, R, (size(a, 1), size(b, 2))) if size(a, 2) > 0 for j in 1:size(b, 2) - for i in 1:size(b, 1) + for i in 1:size(a, 1) ## 여기서 `R` 는 `Any`, `zero(Any)` 는 정의되지 않았기 때문에 `ab = zero(R)` 을 사용하지 않습니다. ## 우리는 또한 typeof (a * b)! = typeof (a * b + a * b) == R이 가능하기 때문에 `ab::R` 을 선언하여 루프에서 `ab` 의 타입을 상수로 만들어야합니다. ab::R = a[i, 1] * b[1, j] diff --git a/src/manual/performance-tips.md b/src/manual/performance-tips.md index 71a5234..e043055 100644 --- a/src/manual/performance-tips.md +++ b/src/manual/performance-tips.md @@ -830,7 +830,7 @@ julia> x = randn(10000); julia> fmt(f) = println(rpad(string(f)*": ", 14, ' '), @elapsed f(x)) -julia> map(fmt, Any[copy_cols, copy_rows, copy_col_row, copy_row_col]); +julia> map(fmt, [copy_cols, copy_rows, copy_col_row, copy_row_col]); copy_cols: 0.331706323 copy_rows: 1.799009911 copy_col_row: 0.415630047 diff --git a/src/manual/strings.md b/src/manual/strings.md index d77486b..1010baa 100644 --- a/src/manual/strings.md +++ b/src/manual/strings.md @@ -747,7 +747,7 @@ are given in the [Metaprogramming](@ref) section. ## Regular Expressions Julia has Perl-compatible regular expressions (regexes), as provided by the [PCRE](http://www.pcre.org/) -library. Regular expressions are related to strings in two ways: the obvious connection is that +library (a description of the syntax can be found [here](http://www.pcre.org/current/doc/html/pcre2syntax.html)). Regular expressions are related to strings in two ways: the obvious connection is that regular expressions are used to find regular patterns in strings; the other connection is that regular expressions are themselves input as strings, which are parsed into a state machine that can be used to efficiently search for patterns in strings. In Julia, regular expressions are input diff --git a/src/stdlib/SparseArrays.md b/src/stdlib/SparseArrays.md index af1be79..d4eaebd 100644 --- a/src/stdlib/SparseArrays.md +++ b/src/stdlib/SparseArrays.md @@ -104,10 +104,10 @@ julia> I = [1, 4, 3, 5]; J = [4, 7, 18, 9]; V = [1, 2, -5, 3]; julia> S = sparse(I,J,V) 5×18 SparseMatrixCSC{Int64,Int64} with 4 stored entries: - [1 , 4] = 1 - [4 , 7] = 2 - [5 , 9] = 3 - [3 , 18] = -5 + [1, 4] = 1 + [4, 7] = 2 + [5, 9] = 3 + [3, 18] = -5 julia> R = sparsevec(I,V) 5-element SparseVector{Int64,Int64} with 4 stored entries: From f55349ec96ada52e9155b50982514b516b9ac018 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Fri, 5 Apr 2019 21:20:53 +0900 Subject: [PATCH 111/153] update Julia 1.2.0-DEV.656 (2019-04-05) Commit 31b0d5bed8 --- codex/NEWS.md | 30 +++++++++++++++++++++++++++--- codex/base/base.md | 1 + codex/devdocs/ast.md | 22 +++++++++++++++++----- codex/devdocs/inference.md | 2 +- codex/manual/faq.md | 24 ++++++++++++++++++++++++ codex/stdlib/SparseArrays.md | 4 ++++ src/NEWS.md | 30 +++++++++++++++++++++++++++--- src/base/base.md | 1 + src/devdocs/ast.md | 22 +++++++++++++++++----- src/devdocs/inference.md | 2 +- src/manual/faq.md | 24 ++++++++++++++++++++++++ src/stdlib/SparseArrays.md | 4 ++++ 12 files changed, 148 insertions(+), 18 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index ebf45cb..9a0447c 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -12,18 +12,28 @@ New language features `findall`, `findfirst`, `argmin`/`argmax` and `findmin`/`findmax` to work with these objects, returning the index of matching non-missing elements in the parent ([#31008](https://github.com/JuliaLang/julia/issues/31008)). - * `inv(::Missing)` has now been added and returns `missing` ([#31408](https://github.com/JuliaLang/julia/issues/31408)). + * `inv(::Missing)` has now been added and returns `missing` ([#31451](https://github.com/JuliaLang/julia/issues/31451)). + + * `nextfloat(::BigFloat, n::Integer)` and `prevfloat(::BigFloat, n::Integer)` methods + have been added ([#31310](https://github.com/JuliaLang/julia/issues/31310)). Multi-threading changes ----------------------- - * The `Condition` type now has a thread-safe replacement, accessed as `Threads.Condition`. +* The `Condition` type now has a thread-safe replacement, accessed as `Threads.Condition`. With that addition, task scheduling primitives such as `ReentrantLock` are now thread-safe ([#30061](https://github.com/JuliaLang/julia/issues/30061)). + * It is possible to schedule and switch Tasks during `@threads` loops, and perform limited I/O ([#31438](https://github.com/JuliaLang/julia/issues/31438)). + Language changes ---------------- * Empty entries in `JULIA_DEPOT_PATH` are now expanded to default depot entries ([#31009](https://github.com/JuliaLang/julia/issues/31009)). * `Enum` now behaves like a scalar when used in broadcasting ([#30670](https://github.com/JuliaLang/julia/issues/30670)). +* If a `pipeline` is specified with `append=true` set, but no redirection, an `ArgumentError` +is thrown, rather than a `ErrorException` ([#27900](https://github.com/JuliaLang/julia/issues/27900)). +* Functions that invoke commands (e.g. `run(::Cmd)`) now throw a `ProcessFailedException` +rather than an `ErrorException`, if those commands exit with non-zero exit code. +([#27900](https://github.com/JuliaLang/julia/issues/27900)). Command-line option changes --------------------------- @@ -32,7 +42,8 @@ Command-line option changes New library functions --------------------- -* `getipaddrs()` function returns all the IP addresses of the local machine ([#30349](https://github.com/JuliaLang/julia/issues/30349)) +* `getipaddrs()` function returns all the IP addresses of the local machine, with IPv4 addresses sorting before IPv6 addresses ([#30349, #30604]) +* `getipaddr(addr_type)` and `getipaddrs(addr_type)` functions returns an IP address(es) of the desired type of the local machine ([#30604](https://github.com/JuliaLang/julia/issues/30604)) * Added `Base.hasproperty` and `Base.hasfield` ([#28850](https://github.com/JuliaLang/julia/issues/28850)). * One argument `!=(x)`, `>(x)`, `>=(x)`, `<(x)`, `<=(x)` has been added for currying, similar to the existing `==(x)` and `isequal(x)` methods ([#30915](https://github.com/JuliaLang/julia/issues/30915)). @@ -49,6 +60,12 @@ Standard library changes * A no-argument construct to `Ptr{T}` has been added which constructs a null pointer ([#30919](https://github.com/JuliaLang/julia/issues/30919)) * `strip` now accepts a function argument in the same manner as `lstrip` and `rstrip` ([#31211](https://github.com/JuliaLang/julia/issues/31211)) * `mktempdir` now accepts a `prefix` keyword argument to customize the file name ([#31230](https://github.com/JuliaLang/julia/issues/31230), [#22922](https://github.com/JuliaLang/julia/issues/22922)) +* `keytype` and `valtype` now work on `AbstractArray`, and return the `eltype` of `keys(...)` and + `values(...)` respectively ([#27749](https://github.com/JuliaLang/julia/issues/27749)). +* `nextfloat(::BigFloat)` and `prevfloat(::BigFloat)` now returns a value with the same precision + as their argument, which means that (in particular) `nextfloat(prevfloat(x)) == x` whereas + previously this could result in a completely different value with a different precision ([#31310](https://github.com/JuliaLang/julia/issues/31310)) +* `mapreduce` now accept multiple iterators, similar to `map` ([#31532](https://github.com/JuliaLang/julia/issues/31532)). #### LinearAlgebra @@ -70,11 +87,18 @@ Standard library changes * Fixed `repr` such that it displays `DateTime` as it would be entered in Julia ([#30200](https://github.com/JuliaLang/julia/issues/30200)). +#### Statistics + +* `quantile` now accepts in all cases collections whose `eltype` is not a subtype of `Number` ([#30938](https://github.com/JuliaLang/julia/issues/30938)). + #### Miscellaneous * Since environment variables on Windows are case-insensitive, `ENV` now converts its keys to uppercase for display, iteration, and copying ([#30593](https://github.com/JuliaLang/julia/issues/30593)). +* Build system now prefers downloading prebuilt binary tarballs for most dependencies on + supported systems, disable by setting `USE_BINARYBUILDER=0` at `make` time ([#31441](https://github.com/JuliaLang/julia/issues/31441)). + External dependencies --------------------- diff --git a/codex/base/base.md b/codex/base/base.md index 027fe21..e7fe19d 100644 --- a/codex/base/base.md +++ b/codex/base/base.md @@ -347,6 +347,7 @@ Base.MissingException Core.OutOfMemoryError Core.ReadOnlyMemoryError Core.OverflowError +Base.ProcessFailedException Core.StackOverflowError Base.SystemError Core.TypeError diff --git a/codex/devdocs/ast.md b/codex/devdocs/ast.md index 4c79de3..e234880 100644 --- a/codex/devdocs/ast.md +++ b/codex/devdocs/ast.md @@ -598,10 +598,6 @@ A (usually temporary) container for holding lowered source code. An array of symbols giving names for each slot (argument or local variable). - * `slottypes` - - An array of types for the slots (e.g. variables). - * `slotflags` A `UInt8` array of slot properties, represented as bit flags: @@ -637,6 +633,21 @@ A (usually temporary) container for holding lowered source code. An array of integer indices into the `linetable`, giving the location associated with each statement. +Optional Fields: + + * `slottypes` + + An array of types for the slots. + + * `rettype` + + The inferred return type of the lowered form (IR). Default value is `Any`. + + * `method_for_inference_limit_heuristics` + + The `method_for_inference_heuristics` will expand the given method's generator if + necessary during inference. + * `parent` The `MethodInstance` that "owns" this object (if applicable). @@ -645,6 +656,7 @@ A (usually temporary) container for holding lowered source code. The range of world ages for which this code was valid at the time when it had been inferred. + Boolean properties: * `inferred` @@ -657,7 +669,7 @@ Boolean properties: * `propagate_inbounds` - Whether this should should propagate `@inbounds` when inlined, for the purpose of eliding + Whether this should propagate `@inbounds` when inlined for the purpose of eliding `@boundscheck` blocks. * `pure` diff --git a/codex/devdocs/inference.md b/codex/devdocs/inference.md index 0603c1d..6683486 100644 --- a/codex/devdocs/inference.md +++ b/codex/devdocs/inference.md @@ -36,7 +36,7 @@ Core.Compiler.typeinf_code(m, atypes, sparams, optimize, cached, params) ``` If your debugging adventures require a `MethodInstance`, you can look it up by -calling `Core.Compiler.code_for_method` using many of the variables above. +calling `Core.Compiler.specialize_method` using many of the variables above. A `CodeInfo` object may be obtained with ```julia # Returns the CodeInfo object for `convert(Int, ::UInt)`: diff --git a/codex/manual/faq.md b/codex/manual/faq.md index 46be5bf..498e478 100644 --- a/codex/manual/faq.md +++ b/codex/manual/faq.md @@ -833,6 +833,30 @@ a scalar can participate in linear algebra operations such as `2 * rand(2,2)`, but the analogous operation with a zero-dimensional array `fill(2) * rand(2,2)` is an error. +### Why are my Julia benchmarks for linear algebra operations different from other languages? + +You may find that simple benchmarks of linear algebra building blocks like + +```julia +using BenchmarkTools +A = randn(1000, 1000) +B = randn(1000, 1000) +@btime $A \ $B +@btime $A * $B +``` + +can be different when compared to other languages like Matlab or R. + +Since operations like this are very thin wrappers over the relevant BLAS functions, the reason for the discrepancy is very likely to be + +1. the BLAS library each language is using, + +2. the number of concurrent threads. + +Julia compiles and uses its own copy of OpenBLAS, with threads currently capped at `8` (or the number of your cores). + +Modifying OpenBLAS settings or compiling Julia with a different BLAS library, eg [Intel MKL](https://software.intel.com/en-us/mkl), may provide performance improvements. You can use [MKL.jl](https://github.com/JuliaComputing/MKL.jl), a package that makes Julia's linear algebra use Intel MKL BLAS and LAPACK instead of OpenBLAS, or search the discussion forum for suggestions on how to set this up manually. Note that Intel MKL cannot be bundled with Julia, as it is not open source. + ## Julia Releases ### Do I want to use a release, beta, or nightly version of Julia? diff --git a/codex/stdlib/SparseArrays.md b/codex/stdlib/SparseArrays.md index d4eaebd..d44aa5e 100644 --- a/codex/stdlib/SparseArrays.md +++ b/codex/stdlib/SparseArrays.md @@ -202,6 +202,9 @@ section of the standard library reference. # [Sparse Arrays](@id stdlib-sparse-arrays) ```@docs +SparseArrays.AbstractSparseArray +SparseArrays.AbstractSparseVector +SparseArrays.AbstractSparseMatrix SparseArrays.SparseVector SparseArrays.SparseMatrixCSC SparseArrays.sparse @@ -217,6 +220,7 @@ SparseArrays.sprandn SparseArrays.nonzeros SparseArrays.rowvals SparseArrays.nzrange +SparseArrays.droptol! SparseArrays.dropzeros! SparseArrays.dropzeros SparseArrays.permute diff --git a/src/NEWS.md b/src/NEWS.md index ebf45cb..9a0447c 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -12,18 +12,28 @@ New language features `findall`, `findfirst`, `argmin`/`argmax` and `findmin`/`findmax` to work with these objects, returning the index of matching non-missing elements in the parent ([#31008](https://github.com/JuliaLang/julia/issues/31008)). - * `inv(::Missing)` has now been added and returns `missing` ([#31408](https://github.com/JuliaLang/julia/issues/31408)). + * `inv(::Missing)` has now been added and returns `missing` ([#31451](https://github.com/JuliaLang/julia/issues/31451)). + + * `nextfloat(::BigFloat, n::Integer)` and `prevfloat(::BigFloat, n::Integer)` methods + have been added ([#31310](https://github.com/JuliaLang/julia/issues/31310)). Multi-threading changes ----------------------- - * The `Condition` type now has a thread-safe replacement, accessed as `Threads.Condition`. +* The `Condition` type now has a thread-safe replacement, accessed as `Threads.Condition`. With that addition, task scheduling primitives such as `ReentrantLock` are now thread-safe ([#30061](https://github.com/JuliaLang/julia/issues/30061)). + * It is possible to schedule and switch Tasks during `@threads` loops, and perform limited I/O ([#31438](https://github.com/JuliaLang/julia/issues/31438)). + Language changes ---------------- * Empty entries in `JULIA_DEPOT_PATH` are now expanded to default depot entries ([#31009](https://github.com/JuliaLang/julia/issues/31009)). * `Enum` now behaves like a scalar when used in broadcasting ([#30670](https://github.com/JuliaLang/julia/issues/30670)). +* If a `pipeline` is specified with `append=true` set, but no redirection, an `ArgumentError` +is thrown, rather than a `ErrorException` ([#27900](https://github.com/JuliaLang/julia/issues/27900)). +* Functions that invoke commands (e.g. `run(::Cmd)`) now throw a `ProcessFailedException` +rather than an `ErrorException`, if those commands exit with non-zero exit code. +([#27900](https://github.com/JuliaLang/julia/issues/27900)). Command-line option changes --------------------------- @@ -32,7 +42,8 @@ Command-line option changes New library functions --------------------- -* `getipaddrs()` function returns all the IP addresses of the local machine ([#30349](https://github.com/JuliaLang/julia/issues/30349)) +* `getipaddrs()` function returns all the IP addresses of the local machine, with IPv4 addresses sorting before IPv6 addresses ([#30349, #30604]) +* `getipaddr(addr_type)` and `getipaddrs(addr_type)` functions returns an IP address(es) of the desired type of the local machine ([#30604](https://github.com/JuliaLang/julia/issues/30604)) * Added `Base.hasproperty` and `Base.hasfield` ([#28850](https://github.com/JuliaLang/julia/issues/28850)). * One argument `!=(x)`, `>(x)`, `>=(x)`, `<(x)`, `<=(x)` has been added for currying, similar to the existing `==(x)` and `isequal(x)` methods ([#30915](https://github.com/JuliaLang/julia/issues/30915)). @@ -49,6 +60,12 @@ Standard library changes * A no-argument construct to `Ptr{T}` has been added which constructs a null pointer ([#30919](https://github.com/JuliaLang/julia/issues/30919)) * `strip` now accepts a function argument in the same manner as `lstrip` and `rstrip` ([#31211](https://github.com/JuliaLang/julia/issues/31211)) * `mktempdir` now accepts a `prefix` keyword argument to customize the file name ([#31230](https://github.com/JuliaLang/julia/issues/31230), [#22922](https://github.com/JuliaLang/julia/issues/22922)) +* `keytype` and `valtype` now work on `AbstractArray`, and return the `eltype` of `keys(...)` and + `values(...)` respectively ([#27749](https://github.com/JuliaLang/julia/issues/27749)). +* `nextfloat(::BigFloat)` and `prevfloat(::BigFloat)` now returns a value with the same precision + as their argument, which means that (in particular) `nextfloat(prevfloat(x)) == x` whereas + previously this could result in a completely different value with a different precision ([#31310](https://github.com/JuliaLang/julia/issues/31310)) +* `mapreduce` now accept multiple iterators, similar to `map` ([#31532](https://github.com/JuliaLang/julia/issues/31532)). #### LinearAlgebra @@ -70,11 +87,18 @@ Standard library changes * Fixed `repr` such that it displays `DateTime` as it would be entered in Julia ([#30200](https://github.com/JuliaLang/julia/issues/30200)). +#### Statistics + +* `quantile` now accepts in all cases collections whose `eltype` is not a subtype of `Number` ([#30938](https://github.com/JuliaLang/julia/issues/30938)). + #### Miscellaneous * Since environment variables on Windows are case-insensitive, `ENV` now converts its keys to uppercase for display, iteration, and copying ([#30593](https://github.com/JuliaLang/julia/issues/30593)). +* Build system now prefers downloading prebuilt binary tarballs for most dependencies on + supported systems, disable by setting `USE_BINARYBUILDER=0` at `make` time ([#31441](https://github.com/JuliaLang/julia/issues/31441)). + External dependencies --------------------- diff --git a/src/base/base.md b/src/base/base.md index 027fe21..e7fe19d 100644 --- a/src/base/base.md +++ b/src/base/base.md @@ -347,6 +347,7 @@ Base.MissingException Core.OutOfMemoryError Core.ReadOnlyMemoryError Core.OverflowError +Base.ProcessFailedException Core.StackOverflowError Base.SystemError Core.TypeError diff --git a/src/devdocs/ast.md b/src/devdocs/ast.md index 4c79de3..e234880 100644 --- a/src/devdocs/ast.md +++ b/src/devdocs/ast.md @@ -598,10 +598,6 @@ A (usually temporary) container for holding lowered source code. An array of symbols giving names for each slot (argument or local variable). - * `slottypes` - - An array of types for the slots (e.g. variables). - * `slotflags` A `UInt8` array of slot properties, represented as bit flags: @@ -637,6 +633,21 @@ A (usually temporary) container for holding lowered source code. An array of integer indices into the `linetable`, giving the location associated with each statement. +Optional Fields: + + * `slottypes` + + An array of types for the slots. + + * `rettype` + + The inferred return type of the lowered form (IR). Default value is `Any`. + + * `method_for_inference_limit_heuristics` + + The `method_for_inference_heuristics` will expand the given method's generator if + necessary during inference. + * `parent` The `MethodInstance` that "owns" this object (if applicable). @@ -645,6 +656,7 @@ A (usually temporary) container for holding lowered source code. The range of world ages for which this code was valid at the time when it had been inferred. + Boolean properties: * `inferred` @@ -657,7 +669,7 @@ Boolean properties: * `propagate_inbounds` - Whether this should should propagate `@inbounds` when inlined, for the purpose of eliding + Whether this should propagate `@inbounds` when inlined for the purpose of eliding `@boundscheck` blocks. * `pure` diff --git a/src/devdocs/inference.md b/src/devdocs/inference.md index 0603c1d..6683486 100644 --- a/src/devdocs/inference.md +++ b/src/devdocs/inference.md @@ -36,7 +36,7 @@ Core.Compiler.typeinf_code(m, atypes, sparams, optimize, cached, params) ``` If your debugging adventures require a `MethodInstance`, you can look it up by -calling `Core.Compiler.code_for_method` using many of the variables above. +calling `Core.Compiler.specialize_method` using many of the variables above. A `CodeInfo` object may be obtained with ```julia # Returns the CodeInfo object for `convert(Int, ::UInt)`: diff --git a/src/manual/faq.md b/src/manual/faq.md index 46be5bf..498e478 100644 --- a/src/manual/faq.md +++ b/src/manual/faq.md @@ -833,6 +833,30 @@ a scalar can participate in linear algebra operations such as `2 * rand(2,2)`, but the analogous operation with a zero-dimensional array `fill(2) * rand(2,2)` is an error. +### Why are my Julia benchmarks for linear algebra operations different from other languages? + +You may find that simple benchmarks of linear algebra building blocks like + +```julia +using BenchmarkTools +A = randn(1000, 1000) +B = randn(1000, 1000) +@btime $A \ $B +@btime $A * $B +``` + +can be different when compared to other languages like Matlab or R. + +Since operations like this are very thin wrappers over the relevant BLAS functions, the reason for the discrepancy is very likely to be + +1. the BLAS library each language is using, + +2. the number of concurrent threads. + +Julia compiles and uses its own copy of OpenBLAS, with threads currently capped at `8` (or the number of your cores). + +Modifying OpenBLAS settings or compiling Julia with a different BLAS library, eg [Intel MKL](https://software.intel.com/en-us/mkl), may provide performance improvements. You can use [MKL.jl](https://github.com/JuliaComputing/MKL.jl), a package that makes Julia's linear algebra use Intel MKL BLAS and LAPACK instead of OpenBLAS, or search the discussion forum for suggestions on how to set this up manually. Note that Intel MKL cannot be bundled with Julia, as it is not open source. + ## Julia Releases ### Do I want to use a release, beta, or nightly version of Julia? diff --git a/src/stdlib/SparseArrays.md b/src/stdlib/SparseArrays.md index d4eaebd..d44aa5e 100644 --- a/src/stdlib/SparseArrays.md +++ b/src/stdlib/SparseArrays.md @@ -202,6 +202,9 @@ section of the standard library reference. # [Sparse Arrays](@id stdlib-sparse-arrays) ```@docs +SparseArrays.AbstractSparseArray +SparseArrays.AbstractSparseVector +SparseArrays.AbstractSparseMatrix SparseArrays.SparseVector SparseArrays.SparseMatrixCSC SparseArrays.sparse @@ -217,6 +220,7 @@ SparseArrays.sprandn SparseArrays.nonzeros SparseArrays.rowvals SparseArrays.nzrange +SparseArrays.droptol! SparseArrays.dropzeros! SparseArrays.dropzeros SparseArrays.permute From a9da7898275f8c604ba94743fa4c85f98aa0276b Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Sat, 13 Apr 2019 17:57:07 +0900 Subject: [PATCH 112/153] update Julia 1.3.0-DEV.20 (2019-04-12) Commit 63ab10104c --- codex/NEWS.md | 76 +++-------------------------------- codex/manual/workflow-tips.md | 66 ++++++++++++++++++++++++++++++ codex/stdlib/Distributed.md | 1 + src/NEWS.md | 76 +++-------------------------------- src/manual/workflow-tips.md | 66 ++++++++++++++++++++++++++++++ src/stdlib/Distributed.md | 1 + 6 files changed, 144 insertions(+), 142 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index 9a0447c..cd6dbbf 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -1,113 +1,47 @@ -Julia v1.2 Release Notes +Julia v1.3 Release Notes ======================== New language features --------------------- - * Argument splatting (`x...`) can now be used in calls to the `new` pseudo-function in - constructors ([#30577](https://github.com/JuliaLang/julia/issues/30577)). - * Objects created by calling `skipmissing` on an array can now be indexed using indices - from the parent at non-missing positions. This allows functions such as - `findall`, `findfirst`, `argmin`/`argmax` and `findmin`/`findmax` to work with these - objects, returning the index of matching non-missing elements in the parent ([#31008](https://github.com/JuliaLang/julia/issues/31008)). - - * `inv(::Missing)` has now been added and returns `missing` ([#31451](https://github.com/JuliaLang/julia/issues/31451)). +Language changes +---------------- - * `nextfloat(::BigFloat, n::Integer)` and `prevfloat(::BigFloat, n::Integer)` methods - have been added ([#31310](https://github.com/JuliaLang/julia/issues/31310)). Multi-threading changes ----------------------- -* The `Condition` type now has a thread-safe replacement, accessed as `Threads.Condition`. - With that addition, task scheduling primitives such as `ReentrantLock` are now thread-safe ([#30061](https://github.com/JuliaLang/julia/issues/30061)). - - * It is possible to schedule and switch Tasks during `@threads` loops, and perform limited I/O ([#31438](https://github.com/JuliaLang/julia/issues/31438)). - -Language changes ----------------- -* Empty entries in `JULIA_DEPOT_PATH` are now expanded to default depot entries ([#31009](https://github.com/JuliaLang/julia/issues/31009)). -* `Enum` now behaves like a scalar when used in broadcasting ([#30670](https://github.com/JuliaLang/julia/issues/30670)). -* If a `pipeline` is specified with `append=true` set, but no redirection, an `ArgumentError` -is thrown, rather than a `ErrorException` ([#27900](https://github.com/JuliaLang/julia/issues/27900)). -* Functions that invoke commands (e.g. `run(::Cmd)`) now throw a `ProcessFailedException` -rather than an `ErrorException`, if those commands exit with non-zero exit code. -([#27900](https://github.com/JuliaLang/julia/issues/27900)). -Command-line option changes ---------------------------- +Build system changes +-------------------- New library functions --------------------- -* `getipaddrs()` function returns all the IP addresses of the local machine, with IPv4 addresses sorting before IPv6 addresses ([#30349, #30604]) -* `getipaddr(addr_type)` and `getipaddrs(addr_type)` functions returns an IP address(es) of the desired type of the local machine ([#30604](https://github.com/JuliaLang/julia/issues/30604)) -* Added `Base.hasproperty` and `Base.hasfield` ([#28850](https://github.com/JuliaLang/julia/issues/28850)). -* One argument `!=(x)`, `>(x)`, `>=(x)`, `<(x)`, `<=(x)` has been added for currying, - similar to the existing `==(x)` and `isequal(x)` methods ([#30915](https://github.com/JuliaLang/julia/issues/30915)). Standard library changes ------------------------ -* The `extrema` function now accepts a function argument in the same manner as `minimum` and - `maximum` ([#30323](https://github.com/JuliaLang/julia/issues/30323)). -* `hasmethod` can now check for matching keyword argument names ([#30712](https://github.com/JuliaLang/julia/issues/30712)). -* `startswith` and `endswith` now accept a `Regex` for the second argument ([#29790](https://github.com/JuliaLang/julia/issues/29790)). -* `retry` supports arbitrary callable objects ([#30382](https://github.com/JuliaLang/julia/issues/30382)). -* `filter` now supports `SkipMissing`-wrapped arrays ([#31235](https://github.com/JuliaLang/julia/issues/31235)). -* A no-argument construct to `Ptr{T}` has been added which constructs a null pointer ([#30919](https://github.com/JuliaLang/julia/issues/30919)) -* `strip` now accepts a function argument in the same manner as `lstrip` and `rstrip` ([#31211](https://github.com/JuliaLang/julia/issues/31211)) -* `mktempdir` now accepts a `prefix` keyword argument to customize the file name ([#31230](https://github.com/JuliaLang/julia/issues/31230), [#22922](https://github.com/JuliaLang/julia/issues/22922)) -* `keytype` and `valtype` now work on `AbstractArray`, and return the `eltype` of `keys(...)` and - `values(...)` respectively ([#27749](https://github.com/JuliaLang/julia/issues/27749)). -* `nextfloat(::BigFloat)` and `prevfloat(::BigFloat)` now returns a value with the same precision - as their argument, which means that (in particular) `nextfloat(prevfloat(x)) == x` whereas - previously this could result in a completely different value with a different precision ([#31310](https://github.com/JuliaLang/julia/issues/31310)) -* `mapreduce` now accept multiple iterators, similar to `map` ([#31532](https://github.com/JuliaLang/julia/issues/31532)). #### LinearAlgebra -* Added keyword arguments `rtol`, `atol` to `pinv` and `nullspace` ([#29998](https://github.com/JuliaLang/julia/issues/29998)). -* `UniformScaling` instances are now callable such that e.g. `I(3)` will produce a `Diagonal` matrix ([#30298](https://github.com/JuliaLang/julia/issues/30298)). -* Eigenvalues λ of general matrices are now sorted lexicographically by (Re λ, Im λ) ([#21598](https://github.com/JuliaLang/julia/issues/21598)). -* `one` for structured matrices (`Diagonal`, `Bidiagonal`, `Tridiagonal`, `Symtridiagonal`) now preserves - structure and type. ([#29777](https://github.com/JuliaLang/julia/issues/29777)) -* `diagm(v)` is now a shorthand for `diagm(0 => v)`. ([#31125](https://github.com/JuliaLang/julia/issues/31125)). #### SparseArrays -* performance improvements for sparse matrix-matrix multiplication ([#30372](https://github.com/JuliaLang/julia/issues/30372)). -* Sparse vector outer products are more performant and maintain sparsity in products of the - form `kron(u, v')`, `u * v'`, and `u .* v'` where `u` and `v` are sparse vectors or column - views. ([#24980](https://github.com/JuliaLang/julia/issues/24980)) #### Dates -* Fixed `repr` such that it displays `DateTime` as it would be entered in Julia ([#30200](https://github.com/JuliaLang/julia/issues/30200)). #### Statistics -* `quantile` now accepts in all cases collections whose `eltype` is not a subtype of `Number` ([#30938](https://github.com/JuliaLang/julia/issues/30938)). #### Miscellaneous -* Since environment variables on Windows are case-insensitive, `ENV` now converts its keys - to uppercase for display, iteration, and copying ([#30593](https://github.com/JuliaLang/julia/issues/30593)). -* Build system now prefers downloading prebuilt binary tarballs for most dependencies on - supported systems, disable by setting `USE_BINARYBUILDER=0` at `make` time ([#31441](https://github.com/JuliaLang/julia/issues/31441)). External dependencies --------------------- -* libgit2 has been updated to v0.27.7 ([#30584](https://github.com/JuliaLang/julia/issues/30584)). -* OpenBLAS has been updated to v0.3.5 ([#30583](https://github.com/JuliaLang/julia/issues/30583)). -* MbedTLS has been updated to v2.16.0 ([#30618](https://github.com/JuliaLang/julia/issues/30618)). -* libunwind has been updated to v1.3.1 ([#30724](https://github.com/JuliaLang/julia/issues/30724)). - -Deprecated or removed ---------------------- - diff --git a/codex/manual/workflow-tips.md b/codex/manual/workflow-tips.md index cdc74a4..9a36d27 100644 --- a/codex/manual/workflow-tips.md +++ b/codex/manual/workflow-tips.md @@ -66,3 +66,69 @@ line. A common pattern includes the following elements: It is also possible to interact with a Julia REPL in the browser via [IJulia](https://github.com/JuliaLang/IJulia.jl). See the package home for details. + +## Revise-based workflows + +Whether you're at the REPL or in IJulia, you can typically improve +your development experience with +[Revise](https://github.com/timholy/Revise.jl). +It is common to configure Revise to start whenever julia is started, +as per the instructions in the [Revise documentation](https://timholy.github.io/Revise.jl/stable/). +Once configured, Revise will track changes to files in any loaded modules, +and to any files loaded in to the REPL with `includet` (but not with plain `include`); +you can then edit the files and the changes take effect without restarting your julia session. +A standard workflow is similar to the REPL-based workflow above, with +the following modifications: + +1. Put your code in a module somewhere on your load path. There are + several options for achieving this, of which two recommended choices are: + + a. For long-term projects, use + [PkgTemplates](https://github.com/invenia/PkgTemplates.jl): + + ```julia + using PkgTemplates + t = Template() + generate("MyPkg", t) + ``` + This will create a blank package, `"MyPkg"`, in your `.julia/dev` directory. + Note that PkgTemplates allows you to control many different options + through its `Template` constructor. + + In step 2 below, edit `MyPkg/src/MyPkg.jl` to change the source code, and + `MyPkg/test/runtests.jl` for the tests. + + b. For "throw-away" projects, you can avoid any need for cleanup + by doing your work in your temporary directory (e.g., `/tmp`). + + Navigate to your temporary directory and launch Julia, then do the following: + + ```julia + pkg> generate MyPkg # type ] to enter pkg mode + julia> push!(LOAD_PATH, pwd()) # hit backspace to exit pkg mode + ``` + If you restart your Julia session you'll have to re-issue that command + modifying `LOAD_PATH`. + + In step 2 below, edit `MyPkg/src/MyPkg.jl` to change the source code, and create any + test file of your choosing. + +2. Develop your package + + *Before* loading any code, make sure you're running Revise: say + `using Revise` or follow its documentation on configuring it to run + automatically. + + Then navigate to the directory containing your test file (here + assumed to be `"runtests.jl"`) and do the following: + + ```julia + julia> using MyPkg + + julia> include("runtests.jl") + ``` + + You can iteratively modify the code in MyPkg in your editor and re-run the + tests with `include("runtests.jl")`. You generally should not need to restart + your Julia session to see the changes take effect (subject to a few limitations, + see https://timholy.github.io/Revise.jl/stable/limitations/). diff --git a/codex/stdlib/Distributed.md b/codex/stdlib/Distributed.md index eea3dbb..bddc2a3 100644 --- a/codex/stdlib/Distributed.md +++ b/codex/stdlib/Distributed.md @@ -29,6 +29,7 @@ Distributed.put!(::Future, ::Any) Distributed.take!(::RemoteChannel, ::Any...) Distributed.isready(::RemoteChannel, ::Any...) Distributed.isready(::Future) +Distributed.AbstractWorkerPool Distributed.WorkerPool Distributed.CachingPool Distributed.default_worker_pool diff --git a/src/NEWS.md b/src/NEWS.md index 9a0447c..cd6dbbf 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -1,113 +1,47 @@ -Julia v1.2 Release Notes +Julia v1.3 Release Notes ======================== New language features --------------------- - * Argument splatting (`x...`) can now be used in calls to the `new` pseudo-function in - constructors ([#30577](https://github.com/JuliaLang/julia/issues/30577)). - * Objects created by calling `skipmissing` on an array can now be indexed using indices - from the parent at non-missing positions. This allows functions such as - `findall`, `findfirst`, `argmin`/`argmax` and `findmin`/`findmax` to work with these - objects, returning the index of matching non-missing elements in the parent ([#31008](https://github.com/JuliaLang/julia/issues/31008)). - - * `inv(::Missing)` has now been added and returns `missing` ([#31451](https://github.com/JuliaLang/julia/issues/31451)). +Language changes +---------------- - * `nextfloat(::BigFloat, n::Integer)` and `prevfloat(::BigFloat, n::Integer)` methods - have been added ([#31310](https://github.com/JuliaLang/julia/issues/31310)). Multi-threading changes ----------------------- -* The `Condition` type now has a thread-safe replacement, accessed as `Threads.Condition`. - With that addition, task scheduling primitives such as `ReentrantLock` are now thread-safe ([#30061](https://github.com/JuliaLang/julia/issues/30061)). - - * It is possible to schedule and switch Tasks during `@threads` loops, and perform limited I/O ([#31438](https://github.com/JuliaLang/julia/issues/31438)). - -Language changes ----------------- -* Empty entries in `JULIA_DEPOT_PATH` are now expanded to default depot entries ([#31009](https://github.com/JuliaLang/julia/issues/31009)). -* `Enum` now behaves like a scalar when used in broadcasting ([#30670](https://github.com/JuliaLang/julia/issues/30670)). -* If a `pipeline` is specified with `append=true` set, but no redirection, an `ArgumentError` -is thrown, rather than a `ErrorException` ([#27900](https://github.com/JuliaLang/julia/issues/27900)). -* Functions that invoke commands (e.g. `run(::Cmd)`) now throw a `ProcessFailedException` -rather than an `ErrorException`, if those commands exit with non-zero exit code. -([#27900](https://github.com/JuliaLang/julia/issues/27900)). -Command-line option changes ---------------------------- +Build system changes +-------------------- New library functions --------------------- -* `getipaddrs()` function returns all the IP addresses of the local machine, with IPv4 addresses sorting before IPv6 addresses ([#30349, #30604]) -* `getipaddr(addr_type)` and `getipaddrs(addr_type)` functions returns an IP address(es) of the desired type of the local machine ([#30604](https://github.com/JuliaLang/julia/issues/30604)) -* Added `Base.hasproperty` and `Base.hasfield` ([#28850](https://github.com/JuliaLang/julia/issues/28850)). -* One argument `!=(x)`, `>(x)`, `>=(x)`, `<(x)`, `<=(x)` has been added for currying, - similar to the existing `==(x)` and `isequal(x)` methods ([#30915](https://github.com/JuliaLang/julia/issues/30915)). Standard library changes ------------------------ -* The `extrema` function now accepts a function argument in the same manner as `minimum` and - `maximum` ([#30323](https://github.com/JuliaLang/julia/issues/30323)). -* `hasmethod` can now check for matching keyword argument names ([#30712](https://github.com/JuliaLang/julia/issues/30712)). -* `startswith` and `endswith` now accept a `Regex` for the second argument ([#29790](https://github.com/JuliaLang/julia/issues/29790)). -* `retry` supports arbitrary callable objects ([#30382](https://github.com/JuliaLang/julia/issues/30382)). -* `filter` now supports `SkipMissing`-wrapped arrays ([#31235](https://github.com/JuliaLang/julia/issues/31235)). -* A no-argument construct to `Ptr{T}` has been added which constructs a null pointer ([#30919](https://github.com/JuliaLang/julia/issues/30919)) -* `strip` now accepts a function argument in the same manner as `lstrip` and `rstrip` ([#31211](https://github.com/JuliaLang/julia/issues/31211)) -* `mktempdir` now accepts a `prefix` keyword argument to customize the file name ([#31230](https://github.com/JuliaLang/julia/issues/31230), [#22922](https://github.com/JuliaLang/julia/issues/22922)) -* `keytype` and `valtype` now work on `AbstractArray`, and return the `eltype` of `keys(...)` and - `values(...)` respectively ([#27749](https://github.com/JuliaLang/julia/issues/27749)). -* `nextfloat(::BigFloat)` and `prevfloat(::BigFloat)` now returns a value with the same precision - as their argument, which means that (in particular) `nextfloat(prevfloat(x)) == x` whereas - previously this could result in a completely different value with a different precision ([#31310](https://github.com/JuliaLang/julia/issues/31310)) -* `mapreduce` now accept multiple iterators, similar to `map` ([#31532](https://github.com/JuliaLang/julia/issues/31532)). #### LinearAlgebra -* Added keyword arguments `rtol`, `atol` to `pinv` and `nullspace` ([#29998](https://github.com/JuliaLang/julia/issues/29998)). -* `UniformScaling` instances are now callable such that e.g. `I(3)` will produce a `Diagonal` matrix ([#30298](https://github.com/JuliaLang/julia/issues/30298)). -* Eigenvalues λ of general matrices are now sorted lexicographically by (Re λ, Im λ) ([#21598](https://github.com/JuliaLang/julia/issues/21598)). -* `one` for structured matrices (`Diagonal`, `Bidiagonal`, `Tridiagonal`, `Symtridiagonal`) now preserves - structure and type. ([#29777](https://github.com/JuliaLang/julia/issues/29777)) -* `diagm(v)` is now a shorthand for `diagm(0 => v)`. ([#31125](https://github.com/JuliaLang/julia/issues/31125)). #### SparseArrays -* performance improvements for sparse matrix-matrix multiplication ([#30372](https://github.com/JuliaLang/julia/issues/30372)). -* Sparse vector outer products are more performant and maintain sparsity in products of the - form `kron(u, v')`, `u * v'`, and `u .* v'` where `u` and `v` are sparse vectors or column - views. ([#24980](https://github.com/JuliaLang/julia/issues/24980)) #### Dates -* Fixed `repr` such that it displays `DateTime` as it would be entered in Julia ([#30200](https://github.com/JuliaLang/julia/issues/30200)). #### Statistics -* `quantile` now accepts in all cases collections whose `eltype` is not a subtype of `Number` ([#30938](https://github.com/JuliaLang/julia/issues/30938)). #### Miscellaneous -* Since environment variables on Windows are case-insensitive, `ENV` now converts its keys - to uppercase for display, iteration, and copying ([#30593](https://github.com/JuliaLang/julia/issues/30593)). -* Build system now prefers downloading prebuilt binary tarballs for most dependencies on - supported systems, disable by setting `USE_BINARYBUILDER=0` at `make` time ([#31441](https://github.com/JuliaLang/julia/issues/31441)). External dependencies --------------------- -* libgit2 has been updated to v0.27.7 ([#30584](https://github.com/JuliaLang/julia/issues/30584)). -* OpenBLAS has been updated to v0.3.5 ([#30583](https://github.com/JuliaLang/julia/issues/30583)). -* MbedTLS has been updated to v2.16.0 ([#30618](https://github.com/JuliaLang/julia/issues/30618)). -* libunwind has been updated to v1.3.1 ([#30724](https://github.com/JuliaLang/julia/issues/30724)). - -Deprecated or removed ---------------------- - diff --git a/src/manual/workflow-tips.md b/src/manual/workflow-tips.md index cdc74a4..9a36d27 100644 --- a/src/manual/workflow-tips.md +++ b/src/manual/workflow-tips.md @@ -66,3 +66,69 @@ line. A common pattern includes the following elements: It is also possible to interact with a Julia REPL in the browser via [IJulia](https://github.com/JuliaLang/IJulia.jl). See the package home for details. + +## Revise-based workflows + +Whether you're at the REPL or in IJulia, you can typically improve +your development experience with +[Revise](https://github.com/timholy/Revise.jl). +It is common to configure Revise to start whenever julia is started, +as per the instructions in the [Revise documentation](https://timholy.github.io/Revise.jl/stable/). +Once configured, Revise will track changes to files in any loaded modules, +and to any files loaded in to the REPL with `includet` (but not with plain `include`); +you can then edit the files and the changes take effect without restarting your julia session. +A standard workflow is similar to the REPL-based workflow above, with +the following modifications: + +1. Put your code in a module somewhere on your load path. There are + several options for achieving this, of which two recommended choices are: + + a. For long-term projects, use + [PkgTemplates](https://github.com/invenia/PkgTemplates.jl): + + ```julia + using PkgTemplates + t = Template() + generate("MyPkg", t) + ``` + This will create a blank package, `"MyPkg"`, in your `.julia/dev` directory. + Note that PkgTemplates allows you to control many different options + through its `Template` constructor. + + In step 2 below, edit `MyPkg/src/MyPkg.jl` to change the source code, and + `MyPkg/test/runtests.jl` for the tests. + + b. For "throw-away" projects, you can avoid any need for cleanup + by doing your work in your temporary directory (e.g., `/tmp`). + + Navigate to your temporary directory and launch Julia, then do the following: + + ```julia + pkg> generate MyPkg # type ] to enter pkg mode + julia> push!(LOAD_PATH, pwd()) # hit backspace to exit pkg mode + ``` + If you restart your Julia session you'll have to re-issue that command + modifying `LOAD_PATH`. + + In step 2 below, edit `MyPkg/src/MyPkg.jl` to change the source code, and create any + test file of your choosing. + +2. Develop your package + + *Before* loading any code, make sure you're running Revise: say + `using Revise` or follow its documentation on configuring it to run + automatically. + + Then navigate to the directory containing your test file (here + assumed to be `"runtests.jl"`) and do the following: + + ```julia + julia> using MyPkg + + julia> include("runtests.jl") + ``` + + You can iteratively modify the code in MyPkg in your editor and re-run the + tests with `include("runtests.jl")`. You generally should not need to restart + your Julia session to see the changes take effect (subject to a few limitations, + see https://timholy.github.io/Revise.jl/stable/limitations/). diff --git a/src/stdlib/Distributed.md b/src/stdlib/Distributed.md index eea3dbb..bddc2a3 100644 --- a/src/stdlib/Distributed.md +++ b/src/stdlib/Distributed.md @@ -29,6 +29,7 @@ Distributed.put!(::Future, ::Any) Distributed.take!(::RemoteChannel, ::Any...) Distributed.isready(::RemoteChannel, ::Any...) Distributed.isready(::Future) +Distributed.AbstractWorkerPool Distributed.WorkerPool Distributed.CachingPool Distributed.default_worker_pool From e126de40c7810442fc56656d7f9c2353497bfccc Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Tue, 30 Apr 2019 14:54:44 +0900 Subject: [PATCH 113/153] update Julia 1.3.0-DEV.134 (2019-04-30) Commit 24ee8067dc --- codex/NEWS.md | 4 + codex/manual/calling-c-and-fortran-code.md | 287 +++++++++++---------- codex/manual/environment-variables.md | 2 +- src/NEWS.md | 4 + src/manual/calling-c-and-fortran-code.md | 287 +++++++++++---------- src/manual/environment-variables.md | 2 +- 6 files changed, 312 insertions(+), 274 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index cd6dbbf..f94915a 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -20,13 +20,16 @@ Build system changes New library functions --------------------- +* New `findall(pattern, string)` method where `pattern` is a string or regex ([#31834](https://github.com/JuliaLang/julia/issues/31834)). Standard library changes ------------------------ +* `Regex` can now be multiplied (`*`) and exponentiated (`^`), like strings ([#23422](https://github.com/JuliaLang/julia/issues/23422)). #### LinearAlgebra +* `diagm` and `spdiagm` now accept optional `m,n` initial arguments to specify a size ([#31654](https://github.com/JuliaLang/julia/issues/31654)). #### SparseArrays @@ -36,6 +39,7 @@ Standard library changes #### Statistics +* `mean` now accepts both a function argument and a `dims` keyword ([#31576](https://github.com/JuliaLang/julia/issues/31576)). #### Miscellaneous diff --git a/codex/manual/calling-c-and-fortran-code.md b/codex/manual/calling-c-and-fortran-code.md index a73f746..54c069a 100644 --- a/codex/manual/calling-c-and-fortran-code.md +++ b/codex/manual/calling-c-and-fortran-code.md @@ -11,16 +11,12 @@ The code to be called must be available as a shared library. Most C and Fortran compiled as shared libraries already, but if you are compiling the code yourself using GCC (or Clang), you will need to use the `-shared` and `-fPIC` options. The machine instructions generated by Julia's JIT are the same as a native C call would be, so the resulting overhead is the same -as calling a library function from C code. (Non-library function calls in both C and Julia can -be inlined and thus may have even less overhead than calls to shared library functions. When both -libraries and executables are generated by LLVM, it is possible to perform whole-program optimizations -that can even optimize across this boundary, but Julia does not yet support that. In the future, -however, it may do so, yielding even greater performance gains.) +as calling a library function from C code. [^1] Shared libraries and functions are referenced by a tuple of the form `(:function, "library")` -or `("function", "library")` where `function` is the C-exported function name. `library` refers -to the shared library name: shared libraries available in the (platform-specific) load path will -be resolved by name, and if necessary a direct path may be specified. +or `("function", "library")` where `function` is the C-exported function name, and `library` refers +to the shared library name. Shared libraries available in the (platform-specific) load path will +be resolved by name. The full path to the library may also be specified. A function name may be used alone in place of the tuple (just `:function` or `"function"`). In this case the name is resolved within the current process. This form can be used to call C library @@ -37,36 +33,39 @@ arrays and other mutable objects which are normally heap-allocated, but also to scalar values such as integers and floats which are normally stack-allocated and commonly passed in registers when using C or Julia calling conventions. -Finally, you can use [`ccall`](@ref) to actually generate a call to the library function. Arguments -to [`ccall`](@ref) are as follows: +Finally, you can use [`ccall`](@ref) to actually generate a call to the library function. The arguments +to [`ccall`](@ref) are: -1. A `(:function, "library")` pair, which must be written as a literal constant, +1. A `(:function, "library")` pair (most common), OR - a `:function` name symbol or `"function"` name string, which is resolved in the - current process, + a `:function` name symbol or `"function"` name string (for symbols in the current process or libc), OR a function pointer (for example, from `dlsym`). -2. Return type (see below for mapping the declared C type to Julia) +2. The function's return type - * This argument will be evaluated at compile-time, when the containing method is defined. +3. A tuple of input types, corresponding to the function signature -3. A tuple of input types. The input types must be written as a literal tuple, not a tuple-valued - variable or expression. +4. The actual argument values to be passed to the function, if any; each is a separate parameter. - * This argument will be evaluated at compile-time, when the containing method is defined. +!!! note + The `(:function, "library")` pair, return type, and input types must be literal constants + (i.e., they can't be variables, but see [Non-constant Function Specifications](@ref) below). + + The remaining parameters are evaluated at compile time, when the containing method is defined. -4. The following arguments, if any, are the actual argument values passed to the function. +!!! note + See below for how to [map C types to Julia types](@ref mapping-c-types-to-julia). As a complete but simple example, the following calls the `clock` function from the standard C -library: +library on most Unix-derived systems: ```julia-repl -julia> t = ccall((:clock, "libc"), Int32, ()) +julia> t = ccall(:clock, Int32, ()) 2292761 julia> t @@ -76,12 +75,12 @@ julia> typeof(ans) Int32 ``` -`clock` takes no arguments and returns an [`Int32`](@ref). One common gotcha is that a 1-tuple must be -written with a trailing comma. For example, to call the `getenv` function to get a pointer to -the value of an environment variable, one makes a call like this: +`clock` takes no arguments and returns an [`Int32`](@ref). One common gotcha is that a 1-tuple of +argument types must be written with a trailing comma. For example, to call the `getenv` function +to get a pointer to the value of an environment variable, one makes a call like this: ```julia-repl -julia> path = ccall((:getenv, "libc"), Cstring, (Cstring,), "SHELL") +julia> path = ccall(:getenv, Cstring, (Cstring,), "SHELL") Cstring(@0x00007fff5fbffc45) julia> unsafe_string(path) @@ -109,12 +108,11 @@ which is a simplified version of the actual definition from [`env.jl`](https://g ```julia function getenv(var::AbstractString) - val = ccall((:getenv, "libc"), - Cstring, (Cstring,), var) + val = ccall(:getenv, Cstring, (Cstring,), var) if val == C_NULL error("getenv: undefined variable: ", var) end - unsafe_string(val) + return unsafe_string(val) end ``` @@ -131,15 +129,19 @@ julia> getenv("FOOBAR") getenv: undefined variable: FOOBAR ``` -Here is a slightly more complex example that discovers the local machine's hostname: +Here is a slightly more complex example that discovers the local machine's hostname. +In this example, the networking library code is assumed to be in a shared library named "libc". +In practice, this function is usually part of the C standard library, and so the "libc" +portion should be omitted, but we wish to show here the usage of this syntax. ```julia function gethostname() - hostname = Vector{UInt8}(undef, 128) - ccall((:gethostname, "libc"), Int32, - (Ptr{UInt8}, Csize_t), - hostname, sizeof(hostname)) - hostname[end] = 0; # ensure null-termination + hostname = Vector{UInt8}(undef, 256) # MAXHOSTNAMELEN + err = ccall((:gethostname, "libc"), Int32, + (Ptr{UInt8}, Csize_t), + hostname, sizeof(hostname)) + Base.systemerror("gethostname", err != 0) + hostname[end] = 0 # ensure null-termination return unsafe_string(pointer(hostname)) end ``` @@ -164,18 +166,20 @@ typedef returntype (*functiontype)(argumenttype, ...) ``` The macro [`@cfunction`](@ref) generates the C-compatible function pointer for a call to a -Julia function. Arguments to [`@cfunction`](@ref) are as follows: +Julia function. The arguments to [`@cfunction`](@ref) are: -1. A Julia Function -2. Return type -3. A literal tuple of input types +1. A Julia function +2. The function's return type +3. A tuple of input types, corresponding to the function signature -Like ccall, all of these arguments will be evaluated at compile-time, when the containing method is defined. +!!! note + As with `ccall`, the return type and tuple of input types must be literal constants. -Currently, only the platform-default C calling convention is supported. This means that -`@cfunction`-generated pointers cannot be used in calls where WINAPI expects `stdcall` -function on 32-bit windows, but can be used on WIN64 (where `stdcall` is unified with the -C calling convention). +!!! note + Currently, only the platform-default C calling convention is supported. This means that + `@cfunction`-generated pointers cannot be used in calls where WINAPI expects `stdcall` + function on 32-bit windows, but can be used on WIN64 (where `stdcall` is unified with the + C calling convention). A classic example is the standard C library `qsort` function, declared as: @@ -187,10 +191,11 @@ void qsort(void *base, size_t nmemb, size_t size, The `base` argument is a pointer to an array of length `nmemb`, with elements of `size` bytes each. `compare` is a callback function which takes pointers to two elements `a` and `b` and returns an integer less/greater than zero if `a` should appear before/after `b` (or zero if any order -is permitted). Now, suppose that we have a 1d array `A` of values in Julia that we want to sort +is permitted). + +Now, suppose that we have a 1d array `A` of values in Julia that we want to sort using the `qsort` function (rather than Julia's built-in `sort` function). Before we worry about -calling `qsort` and passing arguments, we need to write a comparison function that works for some -arbitrary objects (which define `<`): +calling `qsort` and passing arguments, we need to write a comparison function: ```jldoctest mycompare julia> function mycompare(a, b)::Cint @@ -199,8 +204,8 @@ julia> function mycompare(a, b)::Cint mycompare (generic function with 1 method) ``` -Notice that we have to be careful about the return type: `qsort` expects a function returning -a C `int`, so we annotate the return type of the function to be sure it returns a `Cint`. +``qsort`` expects a comparison function that return a C ``int``, so we annotate the return type +to be ``Cint``. In order to pass this function to C, we obtain its address using the macro `@cfunction`: @@ -234,12 +239,14 @@ julia> A ``` As can be seen, `A` is changed to the sorted array `[-2.7, 1.3, 3.1, 4.4]`. Note that Julia -knows how to convert an array into a `Ptr{Cdouble}`, how to compute the size of a type in bytes -(identical to C's `sizeof` operator), and so on. For fun, try inserting a `println("mycompare($a, $b)")` -line into `mycompare`, which will allow you to see the comparisons that `qsort` is performing -(and to verify that it is really calling the Julia function that you passed to it). +[takes care of converting the array to a `Ptr{Cdouble}`](@ref automatic-type-conversion)), computing +the size of the element type in bytes, and so on. + +For fun, try inserting a `println("mycompare($a, $b)")` line into `mycompare`, which will allow +you to see the comparisons that `qsort` is performing (and to verify that it is really calling +the Julia function that you passed to it). -## Mapping C Types to Julia +## [Mapping C Types to Julia](@id mapping-c-types-to-julia) It is critical to exactly match the declared C type with its declaration in Julia. Inconsistencies can cause code that works correctly on one system to fail or produce indeterminate results on @@ -247,10 +254,9 @@ a different system. Note that no C header files are used anywhere in the process of calling C functions: you are responsible for making sure that your Julia types and call signatures accurately reflect those in the C header -file. (The [Clang package](https://github.com/ihnorton/Clang.jl) can be used to auto-generate -Julia code from a C header file.) +file.[^2] -### Auto-conversion: +### [Automatic Type Conversion](@id automatic-type-conversion) Julia automatically inserts calls to the [`Base.cconvert`](@ref) function to convert each argument to the specified type. For example, the following call: @@ -276,9 +282,9 @@ For example, this is used to convert an `Array` of objects (e.g. strings) to an converting an object to a native pointer can hide the object from the garbage collector, causing it to be freed prematurely. -### Type Correspondences: +### Type Correspondences -First, a review of some relevant Julia type terminology: +First, let's review some relevant Julia type terminology: | Syntax / Keyword | Example | Description | |:----------------------------- |:------------------------------------------- |:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | @@ -347,7 +353,7 @@ This can help for writing portable code (and remembering that an `int` in C is n an `Int` in Julia). -**System Independent:** +**System Independent Types** | C name | Fortran name | Standard Julia Alias | Julia Base Type | |:------------------------------------------------------- |:------------------------ |:-------------------- |:-------------------------------------------------------------------------------------------------------------- | @@ -388,7 +394,7 @@ to skip the check, you can use `Ptr{UInt8}` as the argument type. `Cstring` can the [`ccall`](@ref) return type, but in that case it obviously does not introduce any extra checks and is only meant to improve readability of the call. -**System-dependent:** +**System Dependent Types** | C name | Standard Julia Alias | Julia Base Type | |:--------------- |:-------------------- |:-------------------------------------------- | @@ -418,11 +424,11 @@ checks and is only meant to improve readability of the call. (`void`) but do return, use `Cvoid` instead. !!! note - For `wchar_t*` arguments, the Julia type should be [`Cwstring`](@ref) (if the C routine expects a NUL-terminated - string) or `Ptr{Cwchar_t}` otherwise. Note also that UTF-8 string data in Julia is internally - NUL-terminated, so it can be passed to C functions expecting NUL-terminated data without making - a copy (but using the `Cwstring` type will cause an error to be thrown if the string itself contains - NUL characters). + For `wchar_t*` arguments, the Julia type should be [`Cwstring`](@ref) (if the C routine expects a + NUL-terminated string) or `Ptr{Cwchar_t}` otherwise. Note also that UTF-8 string data in Julia is + internally NUL-terminated, so it can be passed to C functions expecting NUL-terminated data without + making a copy (but using the `Cwstring` type will cause an error to be thrown if the string itself + contains NUL characters). !!! note C functions that take an argument of the type `char**` can be called by using a `Ptr{Ptr{UInt8}}` @@ -471,7 +477,7 @@ checks and is only meant to improve readability of the call. !!! note A C function declared to return `Cvoid` will return the value `nothing` in Julia. -### Struct Type correspondences +### Struct Type Correspondences Composite types, aka `struct` in C or `TYPE` in Fortran90 (or `STRUCTURE` / `RECORD` in some variants of F77), can be mirrored in Julia by creating a `struct` definition with the same @@ -485,29 +491,32 @@ are not possible in the translation to Julia. Packed structs and union declarations are not supported by Julia. -You can get a near approximation of a `union` if you know, a priori, the field that will have +You can get an approximation of a `union` if you know, a priori, the field that will have the greatest size (potentially including padding). When translating your fields to Julia, declare the Julia field to be only of that type. -Arrays of parameters can be expressed with `NTuple`: +Arrays of parameters can be expressed with `NTuple`. For example, the struct in C notation written as -in C: ```c struct B { int A[3]; }; + b_a_2 = B.A[2]; ``` -in Julia: + +can be written in Julia as + ```julia struct B A::NTuple{3, Cint} end + b_a_2 = B.A[3] # note the difference in indexing (1-based in Julia, 0-based in C) ``` -Arrays of unknown size (C99-compliant variable length structs specified by `[]` or `[0]`) are not directly supported. -Often the best way to deal with these is to deal with the byte offsets directly. +Arrays of unknown size (C99-compliant variable length structs specified by `[]` or `[0]`) are not directly +supported. Often the best way to deal with these is to deal with the byte offsets directly. For example, if a C library declared a proper string type and returned a pointer to it: ```c @@ -593,7 +602,7 @@ work on hosts without AVX support. Memory allocation and deallocation of such objects must be handled by calls to the appropriate cleanup routines in the libraries being used, just like in any C program. Do not try to free an object received from a C library with [`Libc.free`](@ref) in Julia, as this may result in the `free` function -being called via the wrong `libc` library and cause Julia to crash. The reverse (passing an object +being called via the wrong library and cause the process to abort. The reverse (passing an object allocated in Julia to be freed by an external library) is equally invalid. ### When to use T, Ptr{T} and Ref{T} @@ -602,7 +611,7 @@ In Julia code wrapping calls to external C routines, ordinary (non-pointer) data to be of type `T` inside the [`ccall`](@ref), as they are passed by value. For C code accepting pointers, [`Ref{T}`](@ref) should generally be used for the types of input arguments, allowing the use of pointers to memory managed by either Julia or C through the implicit call to [`Base.cconvert`](@ref). - In contrast, pointers returned by the C function called should be declared to be of output type +In contrast, pointers returned by the C function called should be declared to be of output type [`Ptr{T}`](@ref), reflecting that the memory pointed to is managed by C only. Pointers contained in C structs should be represented as fields of type `Ptr{T}` within the corresponding Julia struct types designed to mimic the internal structure of corresponding C structs. @@ -692,8 +701,8 @@ For translating a C return type to Julia: * If the memory is already owned by Julia, or is an `isbits` type, and is known to be non-null: * `Ref{T}`, where `T` is the Julia type corresponding to `T` - * a return type of `Ref{Any}` is invalid, it should either be `Any` (corresponding to `jl_value_t*`) - or `Ptr{Any}` (corresponding to `jl_value_t**`) + * a return type of `Ref{Any}` is invalid, it should either be `Any` (corresponding to + `jl_value_t*`) or `Ptr{Any}` (corresponding to `jl_value_t**`) * C **MUST NOT** modify the memory returned via `Ref{T}` if `T` is an `isbits` type * If the memory is owned by C: @@ -718,39 +727,9 @@ ccall(:foo, Cvoid, (Ref{Cint}, Ref{Cfloat}), width, range) Upon return, the contents of `width` and `range` can be retrieved (if they were changed by `foo`) by `width[]` and `range[]`; that is, they act like zero-dimensional arrays. -### Special Reference Syntax for ccall (deprecated): - -The `&` syntax is deprecated, use the `Ref{T}` argument type instead. +## C Wrapper Examples -A prefix `&` is used on an argument to [`ccall`](@ref) to indicate that a pointer to a scalar -argument should be passed instead of the scalar value itself (required for all Fortran function -arguments, as noted above). The following example computes a dot product using a BLAS function. - -```julia -function compute_dot(DX::Vector{Float64}, DY::Vector{Float64}) - @assert length(DX) == length(DY) - n = length(DX) - incx = incy = 1 - product = ccall((:ddot_, "libLAPACK"), - Float64, - (Ref{Int32}, Ptr{Float64}, Ref{Int32}, Ptr{Float64}, Ref{Int32}), - n, DX, incx, DY, incy) - return product -end -``` - -The meaning of prefix `&` is not quite the same as in C. In particular, any changes to the referenced -variables will not be visible in Julia unless the type is mutable (declared via `mutable struct`). However, -even for immutable structs it will not cause any harm for called functions to attempt such modifications -(that is, writing through the passed pointers). Moreover, `&` may be used with any expression, -such as `&0` or `&f(x)`. - -When a scalar value is passed with `&` as an argument of type `Ptr{T}`, the value will first be -converted to type `T`. - -## Some Examples of C Wrappers - -Here is a simple example of a C wrapper that returns a `Ptr` type: +Let's start with a simple example of a C wrapper that returns a `Ptr` type: ```julia mutable struct gsl_permutation @@ -778,12 +757,12 @@ function `gsl_permutation_alloc`. As user code never has to look inside the `gsl struct, the corresponding Julia wrapper simply needs a new type declaration, `gsl_permutation`, that has no internal fields and whose sole purpose is to be placed in the type parameter of a `Ptr` type. The return type of the [`ccall`](@ref) is declared as `Ptr{gsl_permutation}`, since -the memory allocated and pointed to by `output_ptr` is controlled by C (and not Julia). +the memory allocated and pointed to by `output_ptr` is controlled by C. The input `n` is passed by value, and so the function's input signature is simply declared as `(Csize_t,)` without any `Ref` or `Ptr` necessary. (If the wrapper was calling a Fortran function instead, the corresponding function input -signature should instead be `(Ref{Csize_t},)`, since Fortran variables are +signature would instead be `(Ref{Csize_t},)`, since Fortran variables are passed by pointers.) Furthermore, `n` can be any type that is convertible to a `Csize_t` integer; the [`ccall`](@ref) implicitly calls [`Base.cconvert(Csize_t, n)`](@ref). @@ -806,11 +785,12 @@ end Here, the input `p` is declared to be of type `Ref{gsl_permutation}`, meaning that the memory that `p` points to may be managed by Julia or by C. A pointer to memory allocated by C should be of type `Ptr{gsl_permutation}`, but it is convertible using [`Base.cconvert`](@ref) and therefore -can be used in the same (covariant) context of the input argument to a [`ccall`](@ref). A pointer -to memory allocated by Julia must be of type `Ref{gsl_permutation}`, to ensure that the memory -address pointed to is valid and that Julia's garbage collector manages the chunk of memory pointed -to correctly. Therefore, the `Ref{gsl_permutation}` declaration allows pointers managed by C or -Julia to be used. + +Now if you look closely enough at this example, you may notice that it is incorrect, given our explanation +above of preferred declaration types. Do you see it? The function we are calling is going to free the +memory. This type of operation cannot be given a Julia object (it will crash or cause memory corruption). +Therefore, it may be preferable to declare the `p` type as `Ptr{gsl_permutation }`, to make it harder for the +user to mistakenly pass another sort of object there than one obtained via `gsl_permutation_alloc`. If the C wrapper never expects the user to pass pointers to memory managed by Julia, then using `p::Ptr{gsl_permutation}` for the method signature of the wrapper and similarly in the [`ccall`](@ref) @@ -841,19 +821,33 @@ end ``` The C function wrapped returns an integer error code; the results of the actual evaluation of -the Bessel J function populate the Julia array `result_array`. This variable can only be used -with corresponding input type declaration `Ref{Cdouble}`, since its memory is allocated and managed -by Julia, not C. The implicit call to [`Base.cconvert(Ref{Cdouble}, result_array)`](@ref) unpacks +the Bessel J function populate the Julia array `result_array`. This variable is declared as a +`Ref{Cdouble}`, since its memory is allocated and managed by Julia. The implicit call to +[`Base.cconvert(Ref{Cdouble}, result_array)`](@ref) unpacks the Julia pointer to a Julia array data structure into a form understandable by C. -Note that for this code to work correctly, `result_array` must be declared to be of type `Ref{Cdouble}` -and not `Ptr{Cdouble}`. The memory is managed by Julia and the `Ref` signature alerts Julia's -garbage collector to keep managing the memory for `result_array` while the [`ccall`](@ref) executes. -If `Ptr{Cdouble}` were used instead, the [`ccall`](@ref) may still work, but Julia's garbage -collector would not be aware that the memory declared for `result_array` is being used by the -external C function. As a result, the code may produce a memory leak if `result_array` never gets -freed by the garbage collector, or if the garbage collector prematurely frees `result_array`, -the C function may end up throwing an invalid memory access exception. +## Fortran Wrapper Example + +The following example utilizes ccall to call a function in a common Fortran library (libBLAS) to +computes a dot product. Notice that the argument mapping is a bit different here than above, as +we need to map from Julia to Fortran. On every argument type, we specify `Ref` or `Ptr`. This +mangling convention may be specific to your fortran compiler and operating system, and is likely +undocumented. However, wrapping each in a `Ref` (or `Ptr`, where equivalent) is a frequent +requirement of Fortran compiler implementations: + +```julia +function compute_dot(DX::Vector{Float64}, DY::Vector{Float64}) + @assert length(DX) == length(DY) + n = length(DX) + incx = incy = 1 + product = ccall((:ddot_, "libLAPACK"), + Float64, + (Ref{Int32}, Ptr{Float64}, Ref{Int32}, Ptr{Float64}, Ref{Int32}), + n, DX, incx, DY, incy) + return product +end +``` + ## Garbage Collection Safety @@ -868,8 +862,9 @@ the C library notifies you that it is finished with them. Whenever you have created a pointer to Julia data, you must ensure the original data exists until you are done with using the pointer. Many methods in Julia such as [`unsafe_load`](@ref) and [`String`](@ref) make copies of data instead of taking ownership of the buffer, so that it is -safe to free (or alter) the original data without affecting Julia. A notable exception is [`unsafe_wrap`](@ref) -which, for performance reasons, shares (or can be told to take ownership of) the underlying buffer. +safe to free (or alter) the original data without affecting Julia. A notable exception is +[`unsafe_wrap`](@ref) which, for performance reasons, shares (or can be told to take ownership of) the +underlying buffer. The garbage collector does not guarantee any order of finalization. That is, if `a` contained a reference to `b` and both `a` and `b` are due for garbage collection, there is no guarantee @@ -892,8 +887,8 @@ with `$`). For this reason, `eval` is typically only used to form top-level defi when wrapping libraries that contain many similar functions. A similar example can be constructed for [`@cfunction`](@ref). -However, doing this will also be very slow and leak memory, so you should usually avoid this and instead keep reading. -The next section discusses how to use indirect calls to efficiently accomplish a similar effect. +However, doing this will also be very slow and leak memory, so you should usually avoid this and instead keep +reading. The next section discusses how to use indirect calls to efficiently accomplish a similar effect. ## Indirect Calls @@ -962,8 +957,8 @@ and load in the new changes. One can either restart Julia or use the ```julia lib = Libdl.dlopen("./my_lib.so") # Open the library explicitly. sym = Libdl.dlsym(lib, :my_fcn) # Get a symbol for the function to call. -ccall(sym, ...) # Use the pointer `sym` instead of the (symbol, library) tuple (remaining arguments are the same). -Libdl.dlclose(lib) # Close the library explicitly. +ccall(sym, ...) # Use the pointer `sym` instead of the (symbol, library) tuple (remaining arguments are the +same). Libdl.dlclose(lib) # Close the library explicitly. ``` Note that when using `ccall` with the tuple input @@ -974,8 +969,8 @@ and it may not be explicitly closed. The second argument to [`ccall`](@ref) can optionally be a calling convention specifier (immediately preceding return type). Without any specifier, the platform-default C calling convention is used. -Other supported conventions are: `stdcall`, `cdecl`, `fastcall`, and `thiscall` (no-op on 64-bit Windows). For example (from -`base/libc.jl`) we see the same `gethostname`[`ccall`](@ref) as above, but with the correct +Other supported conventions are: `stdcall`, `cdecl`, `fastcall`, and `thiscall` (no-op on 64-bit Windows). +For example (from `base/libc.jl`) we see the same `gethostname`[`ccall`](@ref) as above, but with the correct signature for Windows: ```julia @@ -1013,6 +1008,15 @@ Ptr{Int32} @0x00007f418d0816b8 The result is a pointer giving the address of the value. The value can be manipulated through this pointer using [`unsafe_load`](@ref) and [`unsafe_store!`](@ref). +!!! note + This `errno` symbol may not be found in a library named "libc", as this is an implementation detail of + your system compiler. Typically standard library symbols should be accessed just by name, + allowing the compiler to fill in the correct one. + Also, however, the `errno` symbol shown in this example is special in most compilers, and so the value + seen here is probably not what you expect or want. Compiling the equivalent code in C on any + multi-threaded-capable system would typically actually call a different function (via macro preprocessor + overloading), and may give a different result than the legacy value printed here. + ## Accessing Data through a Pointer The following methods are described as "unsafe" because a bad pointer or type declaration can @@ -1036,12 +1040,14 @@ back to a Julia object reference by [`unsafe_pointer_to_objref(ptr)`](@ref). (Ju can be converted to `jl_value_t*` pointers, as `Ptr{Cvoid}`, by calling [`pointer_from_objref(v)`](@ref).) The reverse operation (writing data to a `Ptr{T}`), can be performed using [`unsafe_store!(ptr, value, [index])`](@ref). -Currently, this is only supported for primitive types or other pointer-free (`isbits`) immutable struct types. +Currently, this is only supported for primitive types or other pointer-free (`isbits`) immutable struct +types. Any operation that throws an error is probably currently unimplemented and should be posted as a bug so that it can be resolved. -If the pointer of interest is a plain-data array (primitive type or immutable struct), the function [`unsafe_wrap(Array, ptr,dims, own = false)`](@ref) +If the pointer of interest is a plain-data array (primitive type or immutable struct), the function +[`unsafe_wrap(Array, ptr,dims, own = false)`](@ref) may be more useful. The final parameter should be true if Julia should "take ownership" of the underlying buffer and call `free(ptr)` when the returned `Array` object is finalized. If the `own` parameter is omitted or false, the caller must ensure the buffer remains in existence until @@ -1079,3 +1085,12 @@ For more details on how to pass callbacks to C libraries, see this [blog post](h For direct C++ interfacing, see the [Cxx](https://github.com/Keno/Cxx.jl) package. For tools to create C++ bindings, see the [CxxWrap](https://github.com/JuliaInterop/CxxWrap.jl) package. + + + +[^1]: Non-library function calls in both C and Julia can be inlined and thus may have + even less overhead than calls to shared library functions. + The point above is that the cost of actually doing foreign function call is about the same as doing a call in either native language. + +[^2]: The [Clang package](https://github.com/ihnorton/Clang.jl) can be used to auto-generate Julia code + from a C header file. diff --git a/codex/manual/environment-variables.md b/codex/manual/environment-variables.md index 0f84f78..551030f 100644 --- a/codex/manual/environment-variables.md +++ b/codex/manual/environment-variables.md @@ -20,7 +20,7 @@ those for which `JULIA` appears in the name. starts, therefore adding these to `~/.julia/config/startup.jl` is too late in the startup process. In Bash, environment variables can either be set manually by running, e.g., `export JULIA_NUM_THREADS=4` before starting Julia, or by adding the same command to - `-/.bashrc` or `~/.bash_profile` to set the variable each time Bash is started. + `~/.bashrc` or `~/.bash_profile` to set the variable each time Bash is started. ## File locations diff --git a/src/NEWS.md b/src/NEWS.md index cd6dbbf..f94915a 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -20,13 +20,16 @@ Build system changes New library functions --------------------- +* New `findall(pattern, string)` method where `pattern` is a string or regex ([#31834](https://github.com/JuliaLang/julia/issues/31834)). Standard library changes ------------------------ +* `Regex` can now be multiplied (`*`) and exponentiated (`^`), like strings ([#23422](https://github.com/JuliaLang/julia/issues/23422)). #### LinearAlgebra +* `diagm` and `spdiagm` now accept optional `m,n` initial arguments to specify a size ([#31654](https://github.com/JuliaLang/julia/issues/31654)). #### SparseArrays @@ -36,6 +39,7 @@ Standard library changes #### Statistics +* `mean` now accepts both a function argument and a `dims` keyword ([#31576](https://github.com/JuliaLang/julia/issues/31576)). #### Miscellaneous diff --git a/src/manual/calling-c-and-fortran-code.md b/src/manual/calling-c-and-fortran-code.md index a73f746..54c069a 100644 --- a/src/manual/calling-c-and-fortran-code.md +++ b/src/manual/calling-c-and-fortran-code.md @@ -11,16 +11,12 @@ The code to be called must be available as a shared library. Most C and Fortran compiled as shared libraries already, but if you are compiling the code yourself using GCC (or Clang), you will need to use the `-shared` and `-fPIC` options. The machine instructions generated by Julia's JIT are the same as a native C call would be, so the resulting overhead is the same -as calling a library function from C code. (Non-library function calls in both C and Julia can -be inlined and thus may have even less overhead than calls to shared library functions. When both -libraries and executables are generated by LLVM, it is possible to perform whole-program optimizations -that can even optimize across this boundary, but Julia does not yet support that. In the future, -however, it may do so, yielding even greater performance gains.) +as calling a library function from C code. [^1] Shared libraries and functions are referenced by a tuple of the form `(:function, "library")` -or `("function", "library")` where `function` is the C-exported function name. `library` refers -to the shared library name: shared libraries available in the (platform-specific) load path will -be resolved by name, and if necessary a direct path may be specified. +or `("function", "library")` where `function` is the C-exported function name, and `library` refers +to the shared library name. Shared libraries available in the (platform-specific) load path will +be resolved by name. The full path to the library may also be specified. A function name may be used alone in place of the tuple (just `:function` or `"function"`). In this case the name is resolved within the current process. This form can be used to call C library @@ -37,36 +33,39 @@ arrays and other mutable objects which are normally heap-allocated, but also to scalar values such as integers and floats which are normally stack-allocated and commonly passed in registers when using C or Julia calling conventions. -Finally, you can use [`ccall`](@ref) to actually generate a call to the library function. Arguments -to [`ccall`](@ref) are as follows: +Finally, you can use [`ccall`](@ref) to actually generate a call to the library function. The arguments +to [`ccall`](@ref) are: -1. A `(:function, "library")` pair, which must be written as a literal constant, +1. A `(:function, "library")` pair (most common), OR - a `:function` name symbol or `"function"` name string, which is resolved in the - current process, + a `:function` name symbol or `"function"` name string (for symbols in the current process or libc), OR a function pointer (for example, from `dlsym`). -2. Return type (see below for mapping the declared C type to Julia) +2. The function's return type - * This argument will be evaluated at compile-time, when the containing method is defined. +3. A tuple of input types, corresponding to the function signature -3. A tuple of input types. The input types must be written as a literal tuple, not a tuple-valued - variable or expression. +4. The actual argument values to be passed to the function, if any; each is a separate parameter. - * This argument will be evaluated at compile-time, when the containing method is defined. +!!! note + The `(:function, "library")` pair, return type, and input types must be literal constants + (i.e., they can't be variables, but see [Non-constant Function Specifications](@ref) below). + + The remaining parameters are evaluated at compile time, when the containing method is defined. -4. The following arguments, if any, are the actual argument values passed to the function. +!!! note + See below for how to [map C types to Julia types](@ref mapping-c-types-to-julia). As a complete but simple example, the following calls the `clock` function from the standard C -library: +library on most Unix-derived systems: ```julia-repl -julia> t = ccall((:clock, "libc"), Int32, ()) +julia> t = ccall(:clock, Int32, ()) 2292761 julia> t @@ -76,12 +75,12 @@ julia> typeof(ans) Int32 ``` -`clock` takes no arguments and returns an [`Int32`](@ref). One common gotcha is that a 1-tuple must be -written with a trailing comma. For example, to call the `getenv` function to get a pointer to -the value of an environment variable, one makes a call like this: +`clock` takes no arguments and returns an [`Int32`](@ref). One common gotcha is that a 1-tuple of +argument types must be written with a trailing comma. For example, to call the `getenv` function +to get a pointer to the value of an environment variable, one makes a call like this: ```julia-repl -julia> path = ccall((:getenv, "libc"), Cstring, (Cstring,), "SHELL") +julia> path = ccall(:getenv, Cstring, (Cstring,), "SHELL") Cstring(@0x00007fff5fbffc45) julia> unsafe_string(path) @@ -109,12 +108,11 @@ which is a simplified version of the actual definition from [`env.jl`](https://g ```julia function getenv(var::AbstractString) - val = ccall((:getenv, "libc"), - Cstring, (Cstring,), var) + val = ccall(:getenv, Cstring, (Cstring,), var) if val == C_NULL error("getenv: undefined variable: ", var) end - unsafe_string(val) + return unsafe_string(val) end ``` @@ -131,15 +129,19 @@ julia> getenv("FOOBAR") getenv: undefined variable: FOOBAR ``` -Here is a slightly more complex example that discovers the local machine's hostname: +Here is a slightly more complex example that discovers the local machine's hostname. +In this example, the networking library code is assumed to be in a shared library named "libc". +In practice, this function is usually part of the C standard library, and so the "libc" +portion should be omitted, but we wish to show here the usage of this syntax. ```julia function gethostname() - hostname = Vector{UInt8}(undef, 128) - ccall((:gethostname, "libc"), Int32, - (Ptr{UInt8}, Csize_t), - hostname, sizeof(hostname)) - hostname[end] = 0; # ensure null-termination + hostname = Vector{UInt8}(undef, 256) # MAXHOSTNAMELEN + err = ccall((:gethostname, "libc"), Int32, + (Ptr{UInt8}, Csize_t), + hostname, sizeof(hostname)) + Base.systemerror("gethostname", err != 0) + hostname[end] = 0 # ensure null-termination return unsafe_string(pointer(hostname)) end ``` @@ -164,18 +166,20 @@ typedef returntype (*functiontype)(argumenttype, ...) ``` The macro [`@cfunction`](@ref) generates the C-compatible function pointer for a call to a -Julia function. Arguments to [`@cfunction`](@ref) are as follows: +Julia function. The arguments to [`@cfunction`](@ref) are: -1. A Julia Function -2. Return type -3. A literal tuple of input types +1. A Julia function +2. The function's return type +3. A tuple of input types, corresponding to the function signature -Like ccall, all of these arguments will be evaluated at compile-time, when the containing method is defined. +!!! note + As with `ccall`, the return type and tuple of input types must be literal constants. -Currently, only the platform-default C calling convention is supported. This means that -`@cfunction`-generated pointers cannot be used in calls where WINAPI expects `stdcall` -function on 32-bit windows, but can be used on WIN64 (where `stdcall` is unified with the -C calling convention). +!!! note + Currently, only the platform-default C calling convention is supported. This means that + `@cfunction`-generated pointers cannot be used in calls where WINAPI expects `stdcall` + function on 32-bit windows, but can be used on WIN64 (where `stdcall` is unified with the + C calling convention). A classic example is the standard C library `qsort` function, declared as: @@ -187,10 +191,11 @@ void qsort(void *base, size_t nmemb, size_t size, The `base` argument is a pointer to an array of length `nmemb`, with elements of `size` bytes each. `compare` is a callback function which takes pointers to two elements `a` and `b` and returns an integer less/greater than zero if `a` should appear before/after `b` (or zero if any order -is permitted). Now, suppose that we have a 1d array `A` of values in Julia that we want to sort +is permitted). + +Now, suppose that we have a 1d array `A` of values in Julia that we want to sort using the `qsort` function (rather than Julia's built-in `sort` function). Before we worry about -calling `qsort` and passing arguments, we need to write a comparison function that works for some -arbitrary objects (which define `<`): +calling `qsort` and passing arguments, we need to write a comparison function: ```jldoctest mycompare julia> function mycompare(a, b)::Cint @@ -199,8 +204,8 @@ julia> function mycompare(a, b)::Cint mycompare (generic function with 1 method) ``` -Notice that we have to be careful about the return type: `qsort` expects a function returning -a C `int`, so we annotate the return type of the function to be sure it returns a `Cint`. +``qsort`` expects a comparison function that return a C ``int``, so we annotate the return type +to be ``Cint``. In order to pass this function to C, we obtain its address using the macro `@cfunction`: @@ -234,12 +239,14 @@ julia> A ``` As can be seen, `A` is changed to the sorted array `[-2.7, 1.3, 3.1, 4.4]`. Note that Julia -knows how to convert an array into a `Ptr{Cdouble}`, how to compute the size of a type in bytes -(identical to C's `sizeof` operator), and so on. For fun, try inserting a `println("mycompare($a, $b)")` -line into `mycompare`, which will allow you to see the comparisons that `qsort` is performing -(and to verify that it is really calling the Julia function that you passed to it). +[takes care of converting the array to a `Ptr{Cdouble}`](@ref automatic-type-conversion)), computing +the size of the element type in bytes, and so on. + +For fun, try inserting a `println("mycompare($a, $b)")` line into `mycompare`, which will allow +you to see the comparisons that `qsort` is performing (and to verify that it is really calling +the Julia function that you passed to it). -## Mapping C Types to Julia +## [Mapping C Types to Julia](@id mapping-c-types-to-julia) It is critical to exactly match the declared C type with its declaration in Julia. Inconsistencies can cause code that works correctly on one system to fail or produce indeterminate results on @@ -247,10 +254,9 @@ a different system. Note that no C header files are used anywhere in the process of calling C functions: you are responsible for making sure that your Julia types and call signatures accurately reflect those in the C header -file. (The [Clang package](https://github.com/ihnorton/Clang.jl) can be used to auto-generate -Julia code from a C header file.) +file.[^2] -### Auto-conversion: +### [Automatic Type Conversion](@id automatic-type-conversion) Julia automatically inserts calls to the [`Base.cconvert`](@ref) function to convert each argument to the specified type. For example, the following call: @@ -276,9 +282,9 @@ For example, this is used to convert an `Array` of objects (e.g. strings) to an converting an object to a native pointer can hide the object from the garbage collector, causing it to be freed prematurely. -### Type Correspondences: +### Type Correspondences -First, a review of some relevant Julia type terminology: +First, let's review some relevant Julia type terminology: | Syntax / Keyword | Example | Description | |:----------------------------- |:------------------------------------------- |:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | @@ -347,7 +353,7 @@ This can help for writing portable code (and remembering that an `int` in C is n an `Int` in Julia). -**System Independent:** +**System Independent Types** | C name | Fortran name | Standard Julia Alias | Julia Base Type | |:------------------------------------------------------- |:------------------------ |:-------------------- |:-------------------------------------------------------------------------------------------------------------- | @@ -388,7 +394,7 @@ to skip the check, you can use `Ptr{UInt8}` as the argument type. `Cstring` can the [`ccall`](@ref) return type, but in that case it obviously does not introduce any extra checks and is only meant to improve readability of the call. -**System-dependent:** +**System Dependent Types** | C name | Standard Julia Alias | Julia Base Type | |:--------------- |:-------------------- |:-------------------------------------------- | @@ -418,11 +424,11 @@ checks and is only meant to improve readability of the call. (`void`) but do return, use `Cvoid` instead. !!! note - For `wchar_t*` arguments, the Julia type should be [`Cwstring`](@ref) (if the C routine expects a NUL-terminated - string) or `Ptr{Cwchar_t}` otherwise. Note also that UTF-8 string data in Julia is internally - NUL-terminated, so it can be passed to C functions expecting NUL-terminated data without making - a copy (but using the `Cwstring` type will cause an error to be thrown if the string itself contains - NUL characters). + For `wchar_t*` arguments, the Julia type should be [`Cwstring`](@ref) (if the C routine expects a + NUL-terminated string) or `Ptr{Cwchar_t}` otherwise. Note also that UTF-8 string data in Julia is + internally NUL-terminated, so it can be passed to C functions expecting NUL-terminated data without + making a copy (but using the `Cwstring` type will cause an error to be thrown if the string itself + contains NUL characters). !!! note C functions that take an argument of the type `char**` can be called by using a `Ptr{Ptr{UInt8}}` @@ -471,7 +477,7 @@ checks and is only meant to improve readability of the call. !!! note A C function declared to return `Cvoid` will return the value `nothing` in Julia. -### Struct Type correspondences +### Struct Type Correspondences Composite types, aka `struct` in C or `TYPE` in Fortran90 (or `STRUCTURE` / `RECORD` in some variants of F77), can be mirrored in Julia by creating a `struct` definition with the same @@ -485,29 +491,32 @@ are not possible in the translation to Julia. Packed structs and union declarations are not supported by Julia. -You can get a near approximation of a `union` if you know, a priori, the field that will have +You can get an approximation of a `union` if you know, a priori, the field that will have the greatest size (potentially including padding). When translating your fields to Julia, declare the Julia field to be only of that type. -Arrays of parameters can be expressed with `NTuple`: +Arrays of parameters can be expressed with `NTuple`. For example, the struct in C notation written as -in C: ```c struct B { int A[3]; }; + b_a_2 = B.A[2]; ``` -in Julia: + +can be written in Julia as + ```julia struct B A::NTuple{3, Cint} end + b_a_2 = B.A[3] # note the difference in indexing (1-based in Julia, 0-based in C) ``` -Arrays of unknown size (C99-compliant variable length structs specified by `[]` or `[0]`) are not directly supported. -Often the best way to deal with these is to deal with the byte offsets directly. +Arrays of unknown size (C99-compliant variable length structs specified by `[]` or `[0]`) are not directly +supported. Often the best way to deal with these is to deal with the byte offsets directly. For example, if a C library declared a proper string type and returned a pointer to it: ```c @@ -593,7 +602,7 @@ work on hosts without AVX support. Memory allocation and deallocation of such objects must be handled by calls to the appropriate cleanup routines in the libraries being used, just like in any C program. Do not try to free an object received from a C library with [`Libc.free`](@ref) in Julia, as this may result in the `free` function -being called via the wrong `libc` library and cause Julia to crash. The reverse (passing an object +being called via the wrong library and cause the process to abort. The reverse (passing an object allocated in Julia to be freed by an external library) is equally invalid. ### When to use T, Ptr{T} and Ref{T} @@ -602,7 +611,7 @@ In Julia code wrapping calls to external C routines, ordinary (non-pointer) data to be of type `T` inside the [`ccall`](@ref), as they are passed by value. For C code accepting pointers, [`Ref{T}`](@ref) should generally be used for the types of input arguments, allowing the use of pointers to memory managed by either Julia or C through the implicit call to [`Base.cconvert`](@ref). - In contrast, pointers returned by the C function called should be declared to be of output type +In contrast, pointers returned by the C function called should be declared to be of output type [`Ptr{T}`](@ref), reflecting that the memory pointed to is managed by C only. Pointers contained in C structs should be represented as fields of type `Ptr{T}` within the corresponding Julia struct types designed to mimic the internal structure of corresponding C structs. @@ -692,8 +701,8 @@ For translating a C return type to Julia: * If the memory is already owned by Julia, or is an `isbits` type, and is known to be non-null: * `Ref{T}`, where `T` is the Julia type corresponding to `T` - * a return type of `Ref{Any}` is invalid, it should either be `Any` (corresponding to `jl_value_t*`) - or `Ptr{Any}` (corresponding to `jl_value_t**`) + * a return type of `Ref{Any}` is invalid, it should either be `Any` (corresponding to + `jl_value_t*`) or `Ptr{Any}` (corresponding to `jl_value_t**`) * C **MUST NOT** modify the memory returned via `Ref{T}` if `T` is an `isbits` type * If the memory is owned by C: @@ -718,39 +727,9 @@ ccall(:foo, Cvoid, (Ref{Cint}, Ref{Cfloat}), width, range) Upon return, the contents of `width` and `range` can be retrieved (if they were changed by `foo`) by `width[]` and `range[]`; that is, they act like zero-dimensional arrays. -### Special Reference Syntax for ccall (deprecated): - -The `&` syntax is deprecated, use the `Ref{T}` argument type instead. +## C Wrapper Examples -A prefix `&` is used on an argument to [`ccall`](@ref) to indicate that a pointer to a scalar -argument should be passed instead of the scalar value itself (required for all Fortran function -arguments, as noted above). The following example computes a dot product using a BLAS function. - -```julia -function compute_dot(DX::Vector{Float64}, DY::Vector{Float64}) - @assert length(DX) == length(DY) - n = length(DX) - incx = incy = 1 - product = ccall((:ddot_, "libLAPACK"), - Float64, - (Ref{Int32}, Ptr{Float64}, Ref{Int32}, Ptr{Float64}, Ref{Int32}), - n, DX, incx, DY, incy) - return product -end -``` - -The meaning of prefix `&` is not quite the same as in C. In particular, any changes to the referenced -variables will not be visible in Julia unless the type is mutable (declared via `mutable struct`). However, -even for immutable structs it will not cause any harm for called functions to attempt such modifications -(that is, writing through the passed pointers). Moreover, `&` may be used with any expression, -such as `&0` or `&f(x)`. - -When a scalar value is passed with `&` as an argument of type `Ptr{T}`, the value will first be -converted to type `T`. - -## Some Examples of C Wrappers - -Here is a simple example of a C wrapper that returns a `Ptr` type: +Let's start with a simple example of a C wrapper that returns a `Ptr` type: ```julia mutable struct gsl_permutation @@ -778,12 +757,12 @@ function `gsl_permutation_alloc`. As user code never has to look inside the `gsl struct, the corresponding Julia wrapper simply needs a new type declaration, `gsl_permutation`, that has no internal fields and whose sole purpose is to be placed in the type parameter of a `Ptr` type. The return type of the [`ccall`](@ref) is declared as `Ptr{gsl_permutation}`, since -the memory allocated and pointed to by `output_ptr` is controlled by C (and not Julia). +the memory allocated and pointed to by `output_ptr` is controlled by C. The input `n` is passed by value, and so the function's input signature is simply declared as `(Csize_t,)` without any `Ref` or `Ptr` necessary. (If the wrapper was calling a Fortran function instead, the corresponding function input -signature should instead be `(Ref{Csize_t},)`, since Fortran variables are +signature would instead be `(Ref{Csize_t},)`, since Fortran variables are passed by pointers.) Furthermore, `n` can be any type that is convertible to a `Csize_t` integer; the [`ccall`](@ref) implicitly calls [`Base.cconvert(Csize_t, n)`](@ref). @@ -806,11 +785,12 @@ end Here, the input `p` is declared to be of type `Ref{gsl_permutation}`, meaning that the memory that `p` points to may be managed by Julia or by C. A pointer to memory allocated by C should be of type `Ptr{gsl_permutation}`, but it is convertible using [`Base.cconvert`](@ref) and therefore -can be used in the same (covariant) context of the input argument to a [`ccall`](@ref). A pointer -to memory allocated by Julia must be of type `Ref{gsl_permutation}`, to ensure that the memory -address pointed to is valid and that Julia's garbage collector manages the chunk of memory pointed -to correctly. Therefore, the `Ref{gsl_permutation}` declaration allows pointers managed by C or -Julia to be used. + +Now if you look closely enough at this example, you may notice that it is incorrect, given our explanation +above of preferred declaration types. Do you see it? The function we are calling is going to free the +memory. This type of operation cannot be given a Julia object (it will crash or cause memory corruption). +Therefore, it may be preferable to declare the `p` type as `Ptr{gsl_permutation }`, to make it harder for the +user to mistakenly pass another sort of object there than one obtained via `gsl_permutation_alloc`. If the C wrapper never expects the user to pass pointers to memory managed by Julia, then using `p::Ptr{gsl_permutation}` for the method signature of the wrapper and similarly in the [`ccall`](@ref) @@ -841,19 +821,33 @@ end ``` The C function wrapped returns an integer error code; the results of the actual evaluation of -the Bessel J function populate the Julia array `result_array`. This variable can only be used -with corresponding input type declaration `Ref{Cdouble}`, since its memory is allocated and managed -by Julia, not C. The implicit call to [`Base.cconvert(Ref{Cdouble}, result_array)`](@ref) unpacks +the Bessel J function populate the Julia array `result_array`. This variable is declared as a +`Ref{Cdouble}`, since its memory is allocated and managed by Julia. The implicit call to +[`Base.cconvert(Ref{Cdouble}, result_array)`](@ref) unpacks the Julia pointer to a Julia array data structure into a form understandable by C. -Note that for this code to work correctly, `result_array` must be declared to be of type `Ref{Cdouble}` -and not `Ptr{Cdouble}`. The memory is managed by Julia and the `Ref` signature alerts Julia's -garbage collector to keep managing the memory for `result_array` while the [`ccall`](@ref) executes. -If `Ptr{Cdouble}` were used instead, the [`ccall`](@ref) may still work, but Julia's garbage -collector would not be aware that the memory declared for `result_array` is being used by the -external C function. As a result, the code may produce a memory leak if `result_array` never gets -freed by the garbage collector, or if the garbage collector prematurely frees `result_array`, -the C function may end up throwing an invalid memory access exception. +## Fortran Wrapper Example + +The following example utilizes ccall to call a function in a common Fortran library (libBLAS) to +computes a dot product. Notice that the argument mapping is a bit different here than above, as +we need to map from Julia to Fortran. On every argument type, we specify `Ref` or `Ptr`. This +mangling convention may be specific to your fortran compiler and operating system, and is likely +undocumented. However, wrapping each in a `Ref` (or `Ptr`, where equivalent) is a frequent +requirement of Fortran compiler implementations: + +```julia +function compute_dot(DX::Vector{Float64}, DY::Vector{Float64}) + @assert length(DX) == length(DY) + n = length(DX) + incx = incy = 1 + product = ccall((:ddot_, "libLAPACK"), + Float64, + (Ref{Int32}, Ptr{Float64}, Ref{Int32}, Ptr{Float64}, Ref{Int32}), + n, DX, incx, DY, incy) + return product +end +``` + ## Garbage Collection Safety @@ -868,8 +862,9 @@ the C library notifies you that it is finished with them. Whenever you have created a pointer to Julia data, you must ensure the original data exists until you are done with using the pointer. Many methods in Julia such as [`unsafe_load`](@ref) and [`String`](@ref) make copies of data instead of taking ownership of the buffer, so that it is -safe to free (or alter) the original data without affecting Julia. A notable exception is [`unsafe_wrap`](@ref) -which, for performance reasons, shares (or can be told to take ownership of) the underlying buffer. +safe to free (or alter) the original data without affecting Julia. A notable exception is +[`unsafe_wrap`](@ref) which, for performance reasons, shares (or can be told to take ownership of) the +underlying buffer. The garbage collector does not guarantee any order of finalization. That is, if `a` contained a reference to `b` and both `a` and `b` are due for garbage collection, there is no guarantee @@ -892,8 +887,8 @@ with `$`). For this reason, `eval` is typically only used to form top-level defi when wrapping libraries that contain many similar functions. A similar example can be constructed for [`@cfunction`](@ref). -However, doing this will also be very slow and leak memory, so you should usually avoid this and instead keep reading. -The next section discusses how to use indirect calls to efficiently accomplish a similar effect. +However, doing this will also be very slow and leak memory, so you should usually avoid this and instead keep +reading. The next section discusses how to use indirect calls to efficiently accomplish a similar effect. ## Indirect Calls @@ -962,8 +957,8 @@ and load in the new changes. One can either restart Julia or use the ```julia lib = Libdl.dlopen("./my_lib.so") # Open the library explicitly. sym = Libdl.dlsym(lib, :my_fcn) # Get a symbol for the function to call. -ccall(sym, ...) # Use the pointer `sym` instead of the (symbol, library) tuple (remaining arguments are the same). -Libdl.dlclose(lib) # Close the library explicitly. +ccall(sym, ...) # Use the pointer `sym` instead of the (symbol, library) tuple (remaining arguments are the +same). Libdl.dlclose(lib) # Close the library explicitly. ``` Note that when using `ccall` with the tuple input @@ -974,8 +969,8 @@ and it may not be explicitly closed. The second argument to [`ccall`](@ref) can optionally be a calling convention specifier (immediately preceding return type). Without any specifier, the platform-default C calling convention is used. -Other supported conventions are: `stdcall`, `cdecl`, `fastcall`, and `thiscall` (no-op on 64-bit Windows). For example (from -`base/libc.jl`) we see the same `gethostname`[`ccall`](@ref) as above, but with the correct +Other supported conventions are: `stdcall`, `cdecl`, `fastcall`, and `thiscall` (no-op on 64-bit Windows). +For example (from `base/libc.jl`) we see the same `gethostname`[`ccall`](@ref) as above, but with the correct signature for Windows: ```julia @@ -1013,6 +1008,15 @@ Ptr{Int32} @0x00007f418d0816b8 The result is a pointer giving the address of the value. The value can be manipulated through this pointer using [`unsafe_load`](@ref) and [`unsafe_store!`](@ref). +!!! note + This `errno` symbol may not be found in a library named "libc", as this is an implementation detail of + your system compiler. Typically standard library symbols should be accessed just by name, + allowing the compiler to fill in the correct one. + Also, however, the `errno` symbol shown in this example is special in most compilers, and so the value + seen here is probably not what you expect or want. Compiling the equivalent code in C on any + multi-threaded-capable system would typically actually call a different function (via macro preprocessor + overloading), and may give a different result than the legacy value printed here. + ## Accessing Data through a Pointer The following methods are described as "unsafe" because a bad pointer or type declaration can @@ -1036,12 +1040,14 @@ back to a Julia object reference by [`unsafe_pointer_to_objref(ptr)`](@ref). (Ju can be converted to `jl_value_t*` pointers, as `Ptr{Cvoid}`, by calling [`pointer_from_objref(v)`](@ref).) The reverse operation (writing data to a `Ptr{T}`), can be performed using [`unsafe_store!(ptr, value, [index])`](@ref). -Currently, this is only supported for primitive types or other pointer-free (`isbits`) immutable struct types. +Currently, this is only supported for primitive types or other pointer-free (`isbits`) immutable struct +types. Any operation that throws an error is probably currently unimplemented and should be posted as a bug so that it can be resolved. -If the pointer of interest is a plain-data array (primitive type or immutable struct), the function [`unsafe_wrap(Array, ptr,dims, own = false)`](@ref) +If the pointer of interest is a plain-data array (primitive type or immutable struct), the function +[`unsafe_wrap(Array, ptr,dims, own = false)`](@ref) may be more useful. The final parameter should be true if Julia should "take ownership" of the underlying buffer and call `free(ptr)` when the returned `Array` object is finalized. If the `own` parameter is omitted or false, the caller must ensure the buffer remains in existence until @@ -1079,3 +1085,12 @@ For more details on how to pass callbacks to C libraries, see this [blog post](h For direct C++ interfacing, see the [Cxx](https://github.com/Keno/Cxx.jl) package. For tools to create C++ bindings, see the [CxxWrap](https://github.com/JuliaInterop/CxxWrap.jl) package. + + + +[^1]: Non-library function calls in both C and Julia can be inlined and thus may have + even less overhead than calls to shared library functions. + The point above is that the cost of actually doing foreign function call is about the same as doing a call in either native language. + +[^2]: The [Clang package](https://github.com/ihnorton/Clang.jl) can be used to auto-generate Julia code + from a C header file. diff --git a/src/manual/environment-variables.md b/src/manual/environment-variables.md index 0f84f78..551030f 100644 --- a/src/manual/environment-variables.md +++ b/src/manual/environment-variables.md @@ -20,7 +20,7 @@ those for which `JULIA` appears in the name. starts, therefore adding these to `~/.julia/config/startup.jl` is too late in the startup process. In Bash, environment variables can either be set manually by running, e.g., `export JULIA_NUM_THREADS=4` before starting Julia, or by adding the same command to - `-/.bashrc` or `~/.bash_profile` to set the variable each time Bash is started. + `~/.bashrc` or `~/.bash_profile` to set the variable each time Bash is started. ## File locations From e0fb965da437ac9c89ef56608fe9f4407f974baf Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Tue, 7 May 2019 12:05:30 +0900 Subject: [PATCH 114/153] update Julia 1.3.0-DEV.181 (2019-05-06) Commit a6c7c1bdd6 --- codex/NEWS.md | 6 +++++- codex/base/base.md | 8 ++++++++ codex/manual/metaprogramming.md | 12 +++++++++--- src/NEWS.md | 6 +++++- src/base/base.md | 8 ++++++++ src/manual/metaprogramming.md | 12 +++++++++--- 6 files changed, 44 insertions(+), 8 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index f94915a..cef8ab9 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -26,9 +26,13 @@ Standard library changes ------------------------ * `Regex` can now be multiplied (`*`) and exponentiated (`^`), like strings ([#23422](https://github.com/JuliaLang/julia/issues/23422)). +* Cmd interpolation (`` `$(x::Cmd) a b c` `` where) now propagates `x`'s process flags + (environment, flags, working directory, etc) if `x` is the first interpolant and errors + otherwise ([#24353](https://github.com/JuliaLang/julia/issues/24353)). #### LinearAlgebra +* The BLAS submodule no longer exports `dot`, which conflicts with that in LinearAlgebra ([#31838](https://github.com/JuliaLang/julia/issues/31838)). * `diagm` and `spdiagm` now accept optional `m,n` initial arguments to specify a size ([#31654](https://github.com/JuliaLang/julia/issues/31654)). #### SparseArrays @@ -43,7 +47,7 @@ Standard library changes #### Miscellaneous - +* `foldr` and `mapfoldr` now work on any iterator that supports `Iterators.reverse`, not just arrays ([#31781](https://github.com/JuliaLang/julia/issues/31781)). External dependencies --------------------- diff --git a/codex/base/base.md b/codex/base/base.md index e7fe19d..a2b6a0a 100644 --- a/codex/base/base.md +++ b/codex/base/base.md @@ -397,6 +397,7 @@ Meta.@lower Meta.parse(::AbstractString, ::Int) Meta.parse(::AbstractString) Meta.ParseError +Core.QuoteNode Base.macroexpand Base.@macroexpand Base.@macroexpand1 @@ -404,3 +405,10 @@ Base.code_lowered Base.code_typed Base.precompile ``` + +## Meta +```@docs +Meta.quot +Meta.isexpr +Meta.show_sexpr +``` diff --git a/codex/manual/metaprogramming.md b/codex/manual/metaprogramming.md index fcfe422..ae11362 100644 --- a/codex/manual/metaprogramming.md +++ b/codex/manual/metaprogramming.md @@ -308,7 +308,7 @@ The intuition behind this behavior is that `x` is evaluated once for each `$`: one `$` works similarly to `eval(:x)`, giving `x`'s value, while two `$`s do the equivalent of `eval(eval(:x))`. -### QuoteNode +### [QuoteNode](@id man-quote-node) The usual representation of a `quote` form in an AST is an [`Expr`](@ref) with head `:quote`: @@ -328,9 +328,15 @@ Expr As we have seen, such expressions support interpolation with `$`. However, in some situations it is necessary to quote code *without* performing interpolation. This kind of quoting does not yet have syntax, but is represented internally -as an object of type `QuoteNode`. -The parser yields `QuoteNode`s for simple quoted items like symbols: +as an object of type `QuoteNode`: +```jldoctest interp1 +julia> eval(Meta.quot(Expr(:$, :(1+2)))) +3 +julia> eval(QuoteNode(Expr(:$, :(1+2)))) +:($(Expr(:$, :(1 + 2)))) +``` +The parser yields `QuoteNode`s for simple quoted items like symbols: ```jldoctest interp1 julia> dump(Meta.parse(":x")) QuoteNode diff --git a/src/NEWS.md b/src/NEWS.md index f94915a..cef8ab9 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -26,9 +26,13 @@ Standard library changes ------------------------ * `Regex` can now be multiplied (`*`) and exponentiated (`^`), like strings ([#23422](https://github.com/JuliaLang/julia/issues/23422)). +* Cmd interpolation (`` `$(x::Cmd) a b c` `` where) now propagates `x`'s process flags + (environment, flags, working directory, etc) if `x` is the first interpolant and errors + otherwise ([#24353](https://github.com/JuliaLang/julia/issues/24353)). #### LinearAlgebra +* The BLAS submodule no longer exports `dot`, which conflicts with that in LinearAlgebra ([#31838](https://github.com/JuliaLang/julia/issues/31838)). * `diagm` and `spdiagm` now accept optional `m,n` initial arguments to specify a size ([#31654](https://github.com/JuliaLang/julia/issues/31654)). #### SparseArrays @@ -43,7 +47,7 @@ Standard library changes #### Miscellaneous - +* `foldr` and `mapfoldr` now work on any iterator that supports `Iterators.reverse`, not just arrays ([#31781](https://github.com/JuliaLang/julia/issues/31781)). External dependencies --------------------- diff --git a/src/base/base.md b/src/base/base.md index e7fe19d..a2b6a0a 100644 --- a/src/base/base.md +++ b/src/base/base.md @@ -397,6 +397,7 @@ Meta.@lower Meta.parse(::AbstractString, ::Int) Meta.parse(::AbstractString) Meta.ParseError +Core.QuoteNode Base.macroexpand Base.@macroexpand Base.@macroexpand1 @@ -404,3 +405,10 @@ Base.code_lowered Base.code_typed Base.precompile ``` + +## Meta +```@docs +Meta.quot +Meta.isexpr +Meta.show_sexpr +``` diff --git a/src/manual/metaprogramming.md b/src/manual/metaprogramming.md index fcfe422..ae11362 100644 --- a/src/manual/metaprogramming.md +++ b/src/manual/metaprogramming.md @@ -308,7 +308,7 @@ The intuition behind this behavior is that `x` is evaluated once for each `$`: one `$` works similarly to `eval(:x)`, giving `x`'s value, while two `$`s do the equivalent of `eval(eval(:x))`. -### QuoteNode +### [QuoteNode](@id man-quote-node) The usual representation of a `quote` form in an AST is an [`Expr`](@ref) with head `:quote`: @@ -328,9 +328,15 @@ Expr As we have seen, such expressions support interpolation with `$`. However, in some situations it is necessary to quote code *without* performing interpolation. This kind of quoting does not yet have syntax, but is represented internally -as an object of type `QuoteNode`. -The parser yields `QuoteNode`s for simple quoted items like symbols: +as an object of type `QuoteNode`: +```jldoctest interp1 +julia> eval(Meta.quot(Expr(:$, :(1+2)))) +3 +julia> eval(QuoteNode(Expr(:$, :(1+2)))) +:($(Expr(:$, :(1 + 2)))) +``` +The parser yields `QuoteNode`s for simple quoted items like symbols: ```jldoctest interp1 julia> dump(Meta.parse(":x")) QuoteNode From de46b19f19ceff27ea8ea605fd4be7b8475ee7aa Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Thu, 16 May 2019 12:10:42 +0900 Subject: [PATCH 115/153] update Julia 1.3.0-DEV.227 (2019-05-16) Commit 507312d5bf --- codex/NEWS.md | 1 + codex/assets/logo.png | Bin 18351 -> 12311 bytes codex/manual/metaprogramming.md | 9 +-- codex/stdlib/Random.md | 114 +++++++++++++++++++++----------- src/NEWS.md | 1 + src/assets/logo.png | Bin 18351 -> 12311 bytes src/manual/metaprogramming.md | 9 +-- src/stdlib/Random.md | 114 +++++++++++++++++++++----------- 8 files changed, 162 insertions(+), 86 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index cef8ab9..96e12d2 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -4,6 +4,7 @@ Julia v1.3 Release Notes New language features --------------------- +* Support for Unicode 12.1.0 ([#32002](https://github.com/JuliaLang/julia/issues/32002)). Language changes ---------------- diff --git a/codex/assets/logo.png b/codex/assets/logo.png index b18f64c712821783ddf9e325ff45184fab1ac888..0e4f86abdddd6d9f3a2d87cb890024ef4181e793 100644 GIT binary patch literal 12311 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 literal 18351 zcmZ5|bzD^66ZWM;B%~V_rKJ`rDPciCLQz5*Nok}Tq!!7QTwp<3r6dGY8YCBx?vh5y zrSrY`{k`uWuOImUd(XY+oS8W@&pb1isHd8bZxb^R0|0PaRRyLE09YH~*JDC_@RRU~ zY9jC(uA74D3qtUpKcOWY{GG@}<)s?{2yondVR;wGd4eC(yDRCtKXV#wfGX_K3-8Rovp$(dI!L*z0XHX|!}RTvFn4VCA)Qg8 zSaTu<1%0Wm&uqN-2&G4z0MQ4ugb4I^nk)U`L%C-O_jBP6YENMlE;t4%glyd8jNnbG zY_}3*8phuYV9xUx|Gt>rF552q?B+a*32fN^{j+q_Pj>W)j7PuBn$cTw1;PQztJOR* z4l8lR9HJN@EOUH2qK~gW(8zNII|1i_!`;=}CF>7vZEh5mdrR7hHFVJ+N!h~4ArGUS z9`551*WoUZVWmOGFyvpTo0rm0=4=E_uSp0qeEOtdQkazBh*pxSH{I|z>}6^iiy`ncs2f3(!Km=3xs_F83} z6aUKUdQ0`1JGz=I=A86RWp|$seXo zZ>o7(IM18>)o>@7pXRJqSgQZpYwF18X7S4Cp9IXKon- zCxa8hM6>43<7nY`Y&bzV|8V5Fuju;HpECayGM`)QOsWVP1wuv5`pfmU2h#)1Ir4@* zt?W8b;fj(PGaso$ly{W{-}}GbecvOav;vOa9sVJvQBk?MhmvMaI4DIf+=B$I7F05$ z7bp23lKlfV-azsYkHe-vfqQRN()3{sl-Vw>;rM^94z zN|JlM`N+Y!3X0iobioj=luci9`9;5c$$N+lXd>JR1;wcbY%}kwk4=<_4=G7KbVBd} zrLeQ~HYUF#lE%}6A8UH_a2@R%-M~T|<|$95gY$;tSq)?;S9FmfFb+&2S)>l@?}K0F zv$F@~;r-9;Eb9yj*@?|sKI2`zLB#+cS^fRr24OSU{b6qE(5P{D{JGs2<1yk#4j(VS zG%_rTQZJDA1-17Ku#$467$O#Zw3tBTVT~O-6w^bm*|wJ`Nl`Zh%hG07G5{YNEU#C< znxQS+J)vDZxX*KIn77c9iR;&!k|cxog8Q-53UKL%dq;U>1YgW{g|Qbuyn7vSC$_Kp z-KVF>hK)AOw7?Nn&iy3p8*@R}7);X^u@)1lcl`;RIWxvb(E_%6!}7P#T*t}|p)`F26n7fBUP z-<|eKF^n3^Jf7P5;pC8b?gCBNl%M0*raQ}vwey?ut1O)A{Nn|f<{wS>z>|lCDxo@ZYW3bo6b_E4tsJ?n*vitbWMAVRUl$r`EsO$1@LboMy2_ z4Xsj^rnVy#*0}Nhn~kt5jnwf>H)+X=hn3q+Zv*}H<*S*0+G7z;aD8sAG#B{i9ywg( zoqKE)|IhyECLVANf%LQ=n29sjB>aDU1bQ_x-e~-rL{IAs%UTStN(W?|G`)h>mN1G4ETGf z;_~(59Jl{z?J-t<7G46Ae~I`g&U9X4XIe%f_*P@Gi(fIPqiMzvCs%@oQ%&e(TT{F*ltm{F0f?w|ZAqE%e_W zp^SA!*K*e*$$yo#dJHMM?np&lM#Wgo|GF&KS`PU)q{>6DvGR7a=}`R6-$`?}zKN~B zlSHU*pC;tSj8A*!K@<3=lw1J58+u^jM|nP&vH5_)X5_b2h_R;PYz*VA>_Yb&j{?Wm zcRMX^vRH85=&W^j6bHxDcsLSpSSX*R1U%pR0X~WPM!mV@geCIx>T)xQn=Ns3D9$@p zj#~33?sr9MS2rC(aJYZs~fq7Q(c&^s|r%l-p|9}ohaize2p`wju&b8g0uYiSPAuT5h z%KkJql&>hSM-N%$d9EGcUF5Z5l$DeeWJsoN)1RGiX&W>^)KDd~2fCP#n)B;z-i^cx3cql@+{zC;! zLDT25S|3;ex{6+-Z9c`XO$;l#l07BBMGsjt6%~)IwQUVzgr|K=;!NAsz2N(=)OVp! z=l2K!td2wba{t3?oY)IXgxrk@wOY~4dM>MD2W135A)c42ZPwK*ZP-j6YpuOM^lz7` z2JX`c8}8k4fWODjA}kf_tYeDL#D{ywF{(rr!P4^9O7M)YMBamKu~-#Xo4Il0$3sJ1 z0aaxGy)bU(&UvwGD(psJfgiYH%9`R_7+{;JT;10T;!>R6=1}r&&b6<7k#y|NRGy}Z zf8v7Qx_+&@fl{3M2nESZ~)dlCNn5{CWv!Vn3CM z7(M{JQ=(Xk^3Q%w6<=@1`dOuXd@nGx#_v~A8ObY4y70&vR2#LLs^ zlpod)9mhGs$R!8sD<@N>Z3ilVxL^gk7$L$3W+OsR73B$70a{tN@oWvf5ScCT{1I#_N`1784-9E5re zK>1MA@^$r$$HA8$c!caTf5H>zf(R#qI73qbTYMpo^YTJt^o1xzR^|PRtCJKDr3#)d zE!p!7qJV%iX^jJ-O;%r4`$!w{;37ir<~d65<@8RuyA2nQ)N)nIjk-5CYE2CBJ8A*- z{-Zx|AY17vZUVMGPI^dEpUd2or^-(7#(Z}D(ypI!hB2Xe$Me3vmE=z+r)>TV&3Bf! zBVd0B{o^%v13G1{{U68mzZ4P=+N{-hdenq-Km>f7D|QzQ_G>vhF8h96FaE~gNsIRk z5^zRc&XhECrXLjdWT0x0$45#6bug61GhoVg94u^V4%~M0G+r~*%2`a)zUIkyupKw@_&GuQFB^J2MWjj0f)G49J3;3Bx z2h3O9fXv$qFp~5xRamVu1VMf3kd5WL7^aj8oCL9{57-#K{@!vB%VN6V_r$=!sJ0%H zQczqh`LyQFf_=jDis|G!=R(Fq$|y!%S?|Wl3mz!+&_Pm-wXrjzR+i?wQ6!U@8P3Vtv<H-QHEI1npuj;9xyHVUQU;bjpV8*Yuh(v@zD)cObg0oyS|w5! zT6nka!mz^I79{~qJeN&*XP*AldMwbH|y^Htfd*LNh6 z2d#O-mm4ot{!ZSiiDa4N+|~L~x^Kl9(WED6?6^gO>twy~E+=bA5R>!fm1NK7j%%4y zE@e}jJ2L0z2@Jk*WT7sXI>&(rL2eUYim7!FCY2=~>{wc@i`&AKywsb8`1@0SEbmI` zr#(3bXV*@mYfbs2a#oJouAi+NDJ&Zp8yj1BcpUDn3-+u564H;0`d=f!gEXo4X{osR zq-2Q_PM#)BAHwroUYA97q)PeKF-yDG4%R^e-o~?HF4wCH!3NQb%e!v2qm?>Wmd6L@ zSpKaWu2vMEi(Y)FmkQ$3M}{=UNqj##3OP*3BNZ>L+nEu(^Krda_`Xr9$Uy&z(H~1} z-L@Qgt;~fsenmV6fL}>s`2%3b%iJ{kRSgr`*K62W*^o`%ffw3RXeQ)s%uRLnTt{b= z#rld8Y8p91y`K3>UZ?Q49OGwsL+X`}=`xH~1RA|sU_zr!sE&H~S+Z)enBfieaO74` zGsj?6Kf{0~{H29Z!FRInl!{dAmArDCtlEj=*tZW%-2GqpiHFpN(;Oh_9S;qua9?{3IX-RFLvl*=)=$q|ZzF_g3_*f*76L&tHV<>U$(rLz=Pr9r@A`p$$A8vTkt$LJ=O%D#IhvL z%r|`vtN|VJC2w7xUos?CmBo#A%tq-P%mAFk;5aMX41yKNHhRf?FDe3U{Op0=SV#C`fFhlchT;pmB z#*0SkIlFgY-NP&uf9ltG=>R%&)ypab|E&DkK<00+Gq`)2@#6X05S85azHGTBUMA9P z2GYnTO5$)6i&al+lb`4(=8f_=q{bfyyeLm=B!5Kl2<=vzK(Kjxlen&if-lVk@M24q`2#Uf;}XQb;jRXZE);=#@JsS75EXI-AvWn zA%f!yBYL%34#gl{CiFh&*H6^j3N)Ll$!!;xDVz0BQ6iL=%S%Ioez&6u=u+!lhW5Bt za$_?Dd`s|Sb}XxnopRp1Us8@O6EZir=YNG3*R;O6+AJt$wpsN>+C(1=6*%y8tPRI& zeX7VL&gMJiH`~XJoD*Fl4xW|N6?~^5>&&)D%#)!D*&3_1e92w@a6B_)* z-+Sx+ZergWU(tfm=)>QxU+3(|6;UCWGE=P5| zK6d{~W&Ru2*@KXC`~;QqAWYW#G-648nc`mOPv=eoy5R>KHW{>dM41)awL!P5f6Vi# zQ1n<^I@xG8|EAS6a^LsvZ?K!>NCtw0FTJfCft2}6)U%-Q0iTJClcu^ZDT%E6L+Cp0 zOMQ)GD~GoC6_qcpooqMKzAi~=vcry&`b_a%`2jZ!e>ldIcJTD~q>I&ye)Q zr^!ppVnb(la9sC05_L*X-;HMgOfHYQ*Eq%p)>+hakZ%kGXq>K6^*SydbHhFrtN)aX zsAlx#ZemU8wRVed|I8h!gBY}bVOgvdyW%e%c!p5K%GZ$Pcrj8JSXD=o+>adi!`d%M znpI-=?lkPcLdPo0pXZYBqf1vgKVPxmH1RWRzFd$| zm)C=HXzmEtW&#M0ykM`q=8`CbByj{^_fbWLLKk zEo80inf(#1EA}G1?e3>%aW#1UjWIjXf(ut3gKg|@ho`pF4Fv*5W`B%Yb{8w1HUIb; zTwissjXVkSo*c}Fcav^B?*q+zGfXi;`dTbGOevyQ73lZkrEyKx*?d){AmRo@JN zcLq0!#e3yqk)VmX{h8+sDcQpq$!#1)m5_!GzCGluBFdwNFY-miaP<^PmVBay(eAn~ z6Bjdn^=HG93xU1qogTCg^~_ddlsHM;(^WabI)$xb6c8(WS{T@eY8E1!nOAST(Z~U= za@~+enfMU;&)mw8hO;Hf58lGZ*O*GQUp)@)d&qrQ)8JLO&D^$*Pmn%s(jLQSAF7=t zbXT2_DT&h5CpF5JX(%3n_hDxh-=)0B$`&uGnt7knrXD;@x+1bi@5kl3aa>MHa#5tD z;e-wJHty?e-f?XMDb2H_0|!i6G_Ub~Wp5>}D5&|QEQM6)2e<1>6 zzB)qGw!e6OR;Dj^(`WF5l1dueW9YVisaojMmybr*zs%1uRh1hWUfYsu-uAW*ylr{2 zS}|MuGYZu15tk3MmNk=wS+8w>3k}HGOcFUad11@SuF+h**a zEBYZ8OZyLkZgmgm^j>00qNEkPQP?&yH9n0hT)*i%sk~q0IjZtu&flx~{^06MH@7*; zKMvYkTWhp{XqEX?s>r$a*3aVBOP!=yf2bPIXmVhltr^xSuo(}yPKZ%uQGg>V+U^O@ zE^Wzy@l|k%uByiy)%NYEEPe~;i{q}aqy2>H&QT#{08ddH2zL;Ipk#pNW@nH}+u659 z%*}5dJW+1C?@iABE^KJbZKG3LMkdRo__ddfrY>i=hlRwb=@8jnU*=mVuDhsrqIm@i zkM`TElnkcpXkT9rl*vxJVy9#rc0BN1qDMZT>TD81JSG%}K@aoQgk`-dqP3wGD)^1W98Q4hi|K zWa6qNWxD66stL+9xX!gT6%WsgFDS>;yAsJjpAIyu%_jtw~BVzA}z&?rvzT>kFf1>*R19~f)@!s*aN4k)8 zVol@2ER2cg_>-fvy!r2mduixvg+!-~Q1bo(uq z!z@C+)k=JB{fVu^bg~OW+z#8yxi}6YjN9N=wzs*syqua`) z!0+>KdT6;cFTDiP_4gJ|jbSHm&h{*&!?$I&QC_3psybgs3S0lS*DW*J7-C(YpjJZQ z2Xh6ER1-HhY;-2_bgb4=!WpynW@&940{KFc+V1m2os4nmGG7IU=qq@?9kXZ(AKm*i zwuQAQ2kocV`f%*%RpuVEGqY0XLzLFk;L>+X^2c8PzTZFtLG$oNr{7WM;Pgf#B4WEC zAg*l&UAMOBCpV^j0z1_cRbl`@@XZHU@^5QR#)!|U=Jx)o$zhgZaIU9}+`5p(z}TK1 zfhC^1FrL%q;Xm8BZXKVaMy^QPy|#rYUaNFBoF}+^x9&fA9AEBlG@d(50jHi$#p+7i zpZi)&Kt${KW@s8Ae{9mpa>YpFPtWn`XYR*$2dq1im47J3B2}UR9zZY$>3=t`8z)t+9-et|6arq*KZs*o|6cxb2+`V zq5bK|gQC&_rJln2VEgSpia7Fc*vw4pF)?Fp=iq2YCwMpx9+k_uTI!x`8){`#80S@g;u!H{&sG%aQ6#uFEd{E`{P)2`4b5jG(9+QD_<+# zqL#Z}=P>hsm}hS7{&)S+fGl+UBa+_uhwtFmUe|Bbgw?NpHn85`{DDVfd}9JPCiUfS zBAx!yf%h9T>~YWzzTF=qaX*-tIPk;<#gf4AdxYe|{LU6@hYYpLgy~+dXjs5%mI7g5@Vf1~^5W4ZhsCFq6^s(O~eBYBpf@F6O+>R^S zO00n|e!jn|UQ@n5XFBfb|Mo(U%U8@%;d7gh=^gAqml^0E5#PE~dA7N)j=xucZ7*Nx z!Nk_A`zRbk*Hve92>m8@)x!Vn1z4XPkCZW#Lc}}_GK2iOHgw(TY(&(O3n&!gP_^>( z8l+;^F*h$Gvg~<2RI2Cje<0tb@R!A=_#kfvq|14~~s-jJG_`=KpENl%ZF*e&2! zfGc*%*K2dqaG6Q*C%XFm1fje^UGhxl6Hpd}xo)VyQIm@a=LJt?HmqC;y4|HQ-(0 zGic;!@c?Isaofj|=Y&%|Smzm$sSb754&&ZTrdrGPM#$`NsO4kY36?$IV@^Dy-7A~1 z2BCMU3F6|$yBT@+pU5?T_@y$S6Bu4eEa#7POIN;SpNCtCZS-2KH$BHO0yXj_@gJ`^ zx2zI=YApCgo7N~`;IUXN=AMscH}!^Bz^>`oK%_Pwoj$RdHmO#_t!BZAN~gfhnr};U z-?iZW?;*20lSIkD4&pUsj%nyPz3uW*GWhbscuc!A3?{2glu} znfT&-@c#X>?;7K`pXlkG^j?fp40`}Qw`Tms>ENSf!-s-r;O7zmQ9Cufh#Fbet@{F$T`RV1nzUz48?6>Pc-RVbh4gyxUCr8uPL1?mNbmvNFPx-hRA2A0P!t z6X|&FXw#8>U#Zy3q4ZSo6RAC!5?GeJr~b}8WecZzJ74KB_X5=`Q5*?ud70ov>-g7z zGvIxDp(v-6YyM;L`S~fC?D`d>Sp3kJUz@mNuj5+q z!8wBMEK0MQ&eql}9hUg7RR5dhVB)LT13cfNQM5VZ1GBOU)lq|z<7o#Eo)2!?8XEiu zCrg!rO?0VE$%dnES0#$z}prxr1mB* zP$Z1mK>JfcpL0`5Ni)PYI!R@dw-OSED?G-Q2w0dW0(z>)=5cp*^14X~@k1ZLL=%xk zIBB1g(%aFA@b%g2Ghjrhimdr5tK}K|V=D3oa2M%Qt8GUcJd3W6hI<;Md|f#lH$6tD z;`rF*GF8tNXcaI?pVZWol8!1*dg#i>;7!Z=Vl!S>+ z%2&Tl6L+4Au@pI#EqDP(w!x^z3X^5F_cY*; zv6-2_)0I}e2yh8F3l7$@48aU#3$~@vzj3-VCEe`q_exPTD*&B z$ZTbO{(CjW$r?duWu-`%LXIQs00J$)m+KJ)`~9;oL;M&?NTh;bAuGmTPh z9S#4uFn-duxT_AZ4jbrEf8TmGK^Og#1$!Y%CVFik+jMkz7^4adtJ}~MQykt)>?RO% zo--P%-E+%xk&q^6{sd^w);Lbnt9?p$@Cz}~H8nM5A;e7qByKmWf|}e9deZBk){TZ@ zW%iip_zIlnznHhJ`ipWZoyjX+?S0d4b`N&oE~u}b8Q7A;cu@x_ zxkPnzbWEcC8LlMXi*>sfD%jiF>VHTwAYJf3m=Dwjz|BZa*ECTPhqDYD%umhDT@ft1 zVAqtf%0a2ol&MCDEV-aS9aGbJ$N}w&TiU71Ffxq1<5NULMBY5J5{?T5nu;W~ z>S>-M%~rj8XPk17y%6I~M8SM(0r8akfEIGr>dlp&tbmX;Bm7ZYdwkd160T3UmzAj% z&ysfFzAyhwmQmigYts@eh$mQ{u=r@xy}yf2%)Zr41I6 zs?TUPB;8g=&iorO$WwKosJTFK0?j{870%6cQ_2#dKxx2=a3osY*~E$PL!V$>nDX># z3Ifr{^3snVPo4_V)r-`NZ zCSV)Oqy1e)kQW-DmUO>e~2X@U|D& z)Yw&R)`A`M_;KeJ`r_sAOXURYT?PurUk0@}6I!qU*hul$8n`Wfup;u593q7;fTEMW zV=X(kb1cV1ft7?$%)PbLmd(vg-iK0Bx;Q5;WdkS<8T7>yAl|O@`itvQ z$K}gFl%1`ugaMC-Y%myqyG+~bC6MrKY!~*3lW$KDN3szPWIXS((ere9-@kwF`TY5F zCswAVRCK5SP-|D(G(I=iXhC9HK0Q5cioL7-{Q0n6V)t?p^7PNHZbc&-6X|0JqH8>p zCCPqB!SelEws);>@ort{=;)BOhU29pO)XdRatGHvEckyB*n(1pK@hBb1q{g3I3r7b zD(fpX3yY;!MV=~!A;K|0{PHu`#kNGb6Aq8+QZ8$sIs7-fGr$K6Mc!_JQ{AxN1Nv311{`u zOXs^Xm0o;y1^6AC$(l>bIu{HLtY=Y!jpN7ZyLylrWCebfFko=8#o7mb7#rNGO?QEf!f za*@%ah}(>wP>h%QS2?wJ$kc{oInG2dsCF@D4|v@V<|%ZOn0RSucn|DhJ&Fe%BhN9Yic}&F|(Y|nAQVt={b^r ztyQ^Sg08Qs7UobjCL+uL0AGJJOkY`$Bt@A3F(%0u7YGa1-sC8Rk|^14y@N2vDvx7N zI7&ShOFJcz|JO%_XDvJH9+9J;LM@Ck558@N+8}=^<-a}i?Kubs5X#nfZY6f?pVN{? z7GX==C3Aff@@I4N2uUj3g(<|bd}1F^cLN@FC9Gv<+#}50sqG>w_#2$0%FBBtFh(lsMeZ&ba zUkR3Yqg;?&t;%rjUjIBf!YJ-EL-t|ZJ&u1=?WRRF-eOf?m_A~$X3+_lcr7I_miF>y zH{K|1yQ&S6HWwW&-(W^L2??Hm5QimItpEa4Z!l@XyYAcP6a0ZPvl;&D7FxnDt7^29 zili*{DBd6;{SEF(kw-~8zdfOSGo{RH>y(=YtDo}r0rBAQ zu^UL>RDbm+3Ud2DX@=_aj}b2j7P^rr!l}*kx^X-BpF5jU_O%U$Adm+jY@WTF*oys$NvkB{D zVzn>BxS_q9FHy08>wefSZux=#OkqRAC6Bdi1Tvdn-mQrQ7n`f|mGJm{{ad)vxA4z6 zJVQ#&l-Y#g|Y`Riz?1md_ z(Dq<$(6$gB7#JG9nf%CxrP4wdp4T-4VeXsw%eXv8)Z%b9JsRoQ;>n>|xM{ z;Nia0EV$N>dZ=U{@OkVE29ZjEx1y!H7wtuZw*V8IT@h$G7zXX6g2QHEeT1QaPQ`L zv!8wa`qcw_T@=M(YCVt@kT$<_jSJ1Tl6vx=(QR0UDZ+pM8X0+kQs<1vap4Vqj`YE* zs=ccJXT#hyx)MyXEX|Q=r=cL2qXSYlo?0lu)Nag`a3KAGy{?jv&*>+ayBI}47?Mm3 z#q+OK-e^FvmWB%N7Z^x>j5Y_7i4a+=(ne)rgFmMg#Ka3 zRBQ>H;Cc7Ln-)M~A4@d0!Yo&h&uJ?!SLC6K>W7uK>~JbL8ne7^ET-Zk^Wu-11)vL)QQTT|Tl3*IauoZ<_b4!d5m#%}Ac(Qq z200ncQ5J-|I}aX*Q+Af){~c_25ST#OKr!+4b(!yw<02S6Fmz`#Ec(3bqVzBTEvS`J zdM|F%3a4Q$1IvHNJ!KG*n+jj=b#!#pO7DMfp`EY6+k#wIAfyEsZ6l1)in9H_!Jk(h z3U9m<1>45`P<06@pz^VNEDGvIVz=G2oZA48@qz74=fr&DrLXlBFCb{_r-@ZJTv>8G z1tR3_!N7{tvZ^OHO}%$So#*Q5r)wO~se_fkEe@H2p_ZSXCfKppgA~3ffZT~hW_iwXC#hfEtE1FxihZngzW9Vz(6Yr1U`b9Obub2(f+DD z2U){iaTZGQ%A{fBFG0GB_Re7W0t#%hf}AIWg8StjnNZHUUie#MNPB0O9gxrjO@1 z81d!4`e0TYrE8axr?}c?!P5}Kz{tooQFAF2Y%u(?@*oIQXYZixh&$S?49F6MG_Uz1^@T@jw||tVwhgJ6+Jj^8gzMoSP}?EQWiojpMWoR z`23zChWf3D`2;_1EK&fP>wPfR%{YGUl+VD3z5{`5s7AltYagP5q+3e0aeM#v_V7l;Bt7Jq?+0O4Y9h(MKeefV!yeqMPM<3 z0FpdUsM9@||C@ClHJNc@3UlW>`JxTrrIhtp$;-0soU!ro)ajZ_AUJq~U%^rpOJc+w z?jTfUzgpnE{yya(Ke}0W7_0Jy?z3lmfgmzi!kju`FC^zEvI~KSaKq&pnTG_-J?&=0 zxptrk?}0jn6yn6Rc7v$u9vz7Z43;g9QiKnhtrCF?jYcwpSS-H-T#%~P)E{`)6Qwil zy4_H7Fy(p-tIgOba{eB@3GnM(ZQRN-I-2n20xTuIxR#NR| zZeSR0MU&y|qIXldozy;+*i_n=&T1c2E*6)RNVmAd&(6-?0G;Xm2vC(QdU|@t;@&p< zbntavP@oU&$4ZDx51pg99i*bkEfz7S^_5A4fIO^2F8>@%E`b-we#AZc?W6B0DJfJG zr4LXXhG>6lAv)2<0hi~`pMS{B{r$)~Wkt8ODs7VQiO{@qBLKY71hYq>~1O)gcMM3SLq6_ z2+!K&Df}pm`-3NV6$Ik;S>+la`}REso(nXRknKRYmAaywT5!5g)kq>nkWaWPJ7;K!46Ds-@g6L z$oNr<*{)jYVKJcDx9Fqs-hN1F)ep4EHh=3tNjj3bnTZK~@hr-|^asTdCemvzXpb>&eAEEUo$sB41qd&c?lQz)F$AwgG~)Ac3;LDm(Cmqk z5mCuxHRgh^SA@aQSn9$Q`hZ;@oyt0^uL7x$ayubWCsOF6c4#Xv%` zjlcK1G(yFnrFjIqT{Jvjg%)Wm`dx~OIN)}0#RC6Mi{OjXT2KP)6)Y1Coo=b8j~KaEIFR63Baa6#a=bk zK6$lOPqp#e!oIZpg_=yr?~8j`(z{wo34@x2ybr*LwDOdDg!n_Zdx~p1=>i|@AQ=V; zagnG`McQL=mp*{2?TpKpsnX_vIYkkCU3OS9j67TsCZ67(V2_q2x@S_PcJ`ANS};P3 z^;Za`NcfD-;Li`NdJCz@E}oZfbxOn>CcZE>)7~(~F;i(B?iLmLnQ*5b4?6P{5P#Bu zd=}|KWT6}Qu3KJF(b_p620EKJkKef?GC)SD>CWKun``^dH$)TcfVI#KK7)Wb>dqDM z)>K#LCuu*ya_I3gR3OBFRD~T7B#Kg84g;O{r>DJYH!~aZc+doIh1+Tonp4@A3Wlgd z_=vUhZ@*f78*n`hVtf8x18klVj#J6tB8^C}pglD`?L|IlwYz}YYY)j+VSKTEn*n?d zIYL1up9*^YSd^h50q(0FNkOmXOdIVABF%UxMr~Nqs7H*M?TN^Y<9n-@c-L3X6JOYK zzsk}#+lM<%|E#eq)r$N1YW@K;jBt4uM-^;KKWj$iw98$>k*vbZ5HR(;&AaS!YzCgK z3VF6K%97O5NfYmF zsAgEck^4P1HdY2kRwC;wvV(b<;t}^dgDaqZ>qBBq@e^}&o{1V57-)n1i9rwAE2IC_ zFI|X~B#2Y(rMhfY5n^3JGTqCb#dz}(O`jLbK+pE3$s-;l69u~b)sHsUbjoFc^MD>bglDF6by3x2-XJ} zXsmS$XCQY7aj|nk=BoIgP~77K7Yx#&G|k0@Rm+2hK!22S-uR6vFtK>``R%BHI?Mm+ zIeRR3C#nRzgo#>*u3sx1f0x6N5ChAIAp19)*hgEpAOgOQHwp?Y1;loD2Csp2D2gjm zl;X0zX3GbZ*|TBuH;?9GNZz;#|3auNZ_BfhK@}xTp z`;0YawJ!jnVtJ3^0oDm>Lt1hd8=6fX1-r6Z>WDpm>|J({|Fdi6jfO8b4z#(6nh@6- z=R|~}!BOftP1cw}Hgyy%E><}&h@qD#NjvKlhvrp1D9H|R22u)CJ32n2ABrDD;9?@m zAR|B%T?%F9>|9Q-Ry9GIOFS*P9@sf%#a~dcHnEp_o(`Ht29j1OZ!i%|41(mc5{2C$ zdM*1Ue)U{zxpPLi-QtibMCh=$6_+FjhaR{wBv|WZze(X)0djE!#}hPKO9X=i1&{_B z61lSQco@81O}Yvq1zM8P+K7i(L9g1M^3r0|dZ?NP+LwOi{3(WI4JD2uu!PkcYnsoGmfOViE&mk0$i&oBS zEB!^+tq9B!uq9+z`k3Q*Pf*Hy8w863;ncN`0yqik~Ht)jR zN%pmcwiz7@bLUpR{!xfkO*uIKbu5TrmnqnzLLc3y z=%SE>ZRg-XGF=nEPr>{I=Js{W4gQhEVh33WIGC?$0AjoaCf2L8V9v~!A?_?tIJuU` zsWin_dicA=Pnov(hPVaA5b=Unhrmn$pS%_T2q}oLuYl9OGyv#H(oP0Ge4UHD%GwP)xNg`1QN;jz zBvYjg{1AN)e9`t1tlDK)*8|Mf+s#CNOtY1K^?yU9Kqw3rMXkFJb-<#a;(Lf=g0@}u z1_?N5287#>R#sO2Wv?V)B~r3m&osbe=AkkXNadJl=l3B@Zqjmd(7Qao;Wz%jpTdwb zUh&r8Q^P@cN)CCSp$JlGJfB+KZn4rDWA>$XhXwB z2+RnA9Y4MJ>^NMgv9rwU0Fpiw-+Z_AAA^v>ObUE9;c@SGm2nWhgMhUPD^n9z1lZDD z)IB#pIQ0i(bq1DnSxh|>8APc)8C3f202TGf|EMa?WZ5)M6yWnP!X37 z8PsCc-Lc^NMPRmi4}GBxzB$6XU!66%rIZf8GW&153;z&^%4||nQ=9P3=z*ZP>1x1V zhKl%7gpMR-k1%CQ}_8sqXl}Lpg z5Gd*5(Dz4yAX-#hJl;og!VLBzI~udh04G zL5^O0_4fS#az7)0nW$%XZc2( z#JJdA|Cxs&6%Y+C6Jy2&+3^lgs4W$N0U}5Tv{e?OFdRq&1`#t-EJ(k!I9 z0Fb3{vbClAlW^EAsgcO23fA?U|LJBQ~2CPA` za-1t%Ci}0_--4WZ8X8V}-oP#e??mjUHd5_E0=L5zn$o}m;HZlhxJX(k=36*%a)AcO zCxSHb&A?Rb1QF&}xY_Gl|0n$d0{!iMJ{Sxxa(XZr44zL!KPhym5oo20l22Uo;xM&U6SNgb?25W9Ib$ zyilYG!0AMEIx~Zaz|5vIIr&>45csO;5JCtcyiXC)v!+87kv+C;U(njxnlK$i2qA>` zsZ=U;ANq%q#rX6Q(YYHpZj71^B7_j4IQ;+Z-93vFQ5Xf_^G-s7Un`Py5!{3%tONr# z3$mq!osEUK*r=t7l|MiQ!C$dpqbPPtY**Hg%0d`$?o5Ix7Hd9mQ6a|Jc`epRnw3?P z+{x^DU|^Vm%bDshmzjH=R;%T!>Qmc6W?Tf|yfJ3Yb`T;WN{-=HmDdsfue{?b6p;(Q z??18~gouceB?SPzUay_c=QjbwZHdsh`wn2)_x<~}gAfr>^88-StK03a<#M@W0FGMB zGfUd4dO8S#hV39kM3hX<$hl@RnR5Uh+X^#7o{7luAP81%2O%P&han=OWRvY~R4SFL0PXb{du}@n5fSZfJ1*&=a=Dxpk!1iE z0WAH?7%}q+KtolZWV6|Z>$+cU2O=UO0{*jLi^bxRbUJ-jRZoe?5`gTOa!t}Z051W& zavbM{=XtNe>1-k*ilMQ+1=s8Kef@s_1b{^Vi>kT+U>m5M?}`6C~ButsZJP%@0-o$hY3Fy5fRbE{RELb839U+`S1V$002ov KPDHLkV1f#t;m^AO diff --git a/codex/manual/metaprogramming.md b/codex/manual/metaprogramming.md index ae11362..7faa0e5 100644 --- a/codex/manual/metaprogramming.md +++ b/codex/manual/metaprogramming.md @@ -1090,16 +1090,17 @@ To make this efficient, the result is usually cached. And to make this inferable subset of the language is usable. Thus, generated functions provide a flexible way to move work from run time to compile time, at the expense of greater restrictions on allowed constructs. -When defining generated functions, there are four main differences to ordinary functions: +When defining generated functions, there are five main differences to ordinary functions: 1. You annotate the function declaration with the `@generated` macro. This adds some information to the AST that lets the compiler know that this is a generated function. 2. In the body of the generated function you only have access to the *types* of the arguments – - not their values – and any function that was defined *before* the definition of the generated - function. + not their values. 3. Instead of calculating something or performing some action, you return a *quoted expression* which, when evaluated, does what you want. -4. Generated functions must not *mutate* or *observe* any non-constant global state (including, +4. Generated functions are only permitted to call functions that were defined *before* the definition of the generated + function. (Failure to follow this my result on getting `MethodErrors` referring to functions from a future world-age.) +5. Generated functions must not *mutate* or *observe* any non-constant global state (including, for example, IO, locks, non-local dictionaries, or using [`hasmethod`](@ref)). This means they can only read global constants, and cannot have any side effects. In other words, they must be completely pure. diff --git a/codex/stdlib/Random.md b/codex/stdlib/Random.md index f321901..6f23ea2 100644 --- a/codex/stdlib/Random.md +++ b/codex/stdlib/Random.md @@ -80,18 +80,52 @@ in order to support usual types of generated values. ### Generating random values of custom types -There are two categories: generating values from a type (e.g. `rand(Int)`), or from a collection (e.g. `rand(1:3)`). -The simple cases are explained first, and more advanced usage is presented later. -We assume here that the choice of algorithm is independent of the RNG, so we use `AbstractRNG` in our signatures. +Generating random values for some distributions may involve various trade-offs. *Pre-computed* values, such as an [alias table](https://en.wikipedia.org/wiki/Alias_method) for discrete distributions, or [“squeezing” functions](https://en.wikipedia.org/wiki/Rejection_sampling) for univariate distributions, can speed up sampling considerably. How much information should be pre-computed can depend on the number of values we plan to draw from a distribution. Also, some random number generators can have certain properties that various algorithms may want to exploit. + +The `Random` module defines a customizable framework for obtaining random values that can address these issues. Each invocation of `rand` generates a *sampler* which can be customized with the above trade-offs in mind, by adding methods to `Sampler`, which in turn can dispatch on the random number generator, the object that characterizes the distribution, and a suggestion for the number of repetitions. Currently, for the latter, `Val{1}` (for a single sample) and `Val{Inf}` (for an arbitrary number) are used, with `Random.Repetition` an alias for both. + +The object returned by `Sampler` is then used to generate the random values. When implementing the random generation interface for a value `X` that can be sampled from, the implementor should define the method + +```julia +rand(rng, sampler) +``` +for the particular `sampler` returned by `Sampler(rng, X, repetition)`. + +Samplers can be arbitrary values that implement `rand(rng, sampler)`, but for most applications the following predefined samplers may be sufficient: + +1. `SamplerType{T}()` can be used for implementing samplers that draw from type `T` (e.g. `rand(Int)`). This is the default returned by `Sampler` for *types*. + +2. `SamplerTrivial(self)` is a simple wrapper for `self`, which can be accessed with `[]`. This is the recommended sampler when no pre-computed information is needed (e.g. `rand(1:3)`), and is the default returned by `Sampler` for *values*. + +3. `SamplerSimple(self, data)` also contains the additional `data` field, which can be used to store arbitrary pre-computed values, which should be computed in a *custom method* of `Sampler`. + +We provide examples for each of these. We assume here that the choice of algorithm is independent of the RNG, so we use `AbstractRNG` in our signatures. + +```@docs +Random.Sampler +Random.SamplerType +Random.SamplerTrivial +Random.SamplerSimple +``` + +Decoupling pre-computation from actually generating the values is part of the API, and is also available to the user. As an example, assume that `rand(rng, 1:20)` has to be called repeatedly in a loop: the way to take advantage of this decoupling is as follows: + +```julia +rng = MersenneTwister() +sp = Random.Sampler(rng, 1:20) # or Random.Sampler(MersenneTwister, 1:20) +for x in X + n = rand(rng, sp) # similar to n = rand(rng, 1:20) + # use n +end +``` + +This is the mechanism that is also used in the standard library, e.g. by the default implementation of random array generation (like in `rand(1:20, 10)`). #### Generating values from a type -Given a type `T`, it's currently assumed that if `rand(T)` is defined, an object of type `T` will be produced. -In order to define random generation of values of type `T`, the following method can be defined: -`rand(rng::AbstractRNG, ::Random.SamplerType{T})` (this should return what `rand(rng, T)` is expected to return). +Given a type `T`, it's currently assumed that if `rand(T)` is defined, an object of type `T` will be produced. `SamplerType` is the *default sampler for types*. In order to define random generation of values of type `T`, the `rand(rng::AbstractRNG, ::Random.SamplerType{T})` method should be defined, and should return values what `rand(rng, T)` is expected to return. -Let's take the following example: we implement a `Die` type, with a variable number `n` of sides, numbered from `1` to `n`. -We want `rand(Die)` to produce a die with a random number of up to 20 sides (and at least 4): +Let's take the following example: we implement a `Die` type, with a variable number `n` of sides, numbered from `1` to `n`. We want `rand(Die)` to produce a `Die` with a random number of up to 20 sides (and at least 4): ```jldoctest Die struct Die @@ -126,12 +160,11 @@ julia> a = Vector{Die}(undef, 3); rand!(a) Die(8) ``` -#### Generating values from a collection +#### A simple sampler without pre-computed data + +Here we define a sampler for a collection. If no pre-computed data is required, it can be implemented with a `SamplerTrivial` sampler, which is in fact the *default fallback for values*. -Given a collection type `S`, it's currently assumed that if `rand(::S)` is defined, an object of type `eltype(S)` will be produced. -In order to define random generation out of objects of type `S`, the following method can be defined: -`rand(rng::AbstractRNG, sp::Random.SamplerTrivial{S})`. Here, `sp` simply wraps an object of type `S`, which can be accessed via `sp[]`. -Continuing the `Die` example, we want now to define `rand(d::Die)` to produce an `Int` corresponding to one of `d`'s sides: +In order to define random generation out of objects of type `S`, the following method should be defined: `rand(rng::AbstractRNG, sp::Random.SamplerTrivial{S})`. Here, `sp` simply wraps an object of type `S`, which can be accessed via `sp[]`. Continuing the `Die` example, we want now to define `rand(d::Die)` to produce an `Int` corresponding to one of `d`'s sides: ```jldoctest Die; setup = :(Random.seed!(1)) julia> Random.rand(rng::AbstractRNG, d::Random.SamplerTrivial{Die}) = rand(rng, 1:d[].nsides); @@ -146,38 +179,43 @@ julia> rand(Die(4), 3) 2 ``` -In the last example, a `Vector{Any}` is produced; the reason is that `eltype(Die) == Any`. The remedy is to define -`Base.eltype(::Type{Die}) = Int`. - +Given a collection type `S`, it's currently assumed that if `rand(::S)` is defined, an object of type `eltype(S)` will be produced. In the last example, a `Vector{Any}` is produced; the reason is that `eltype(Die) == Any`. The remedy is to define `Base.eltype(::Type{Die}) = Int`. #### Generating values for an `AbstractFloat` type -`AbstractFloat` types are special-cased, because by default random values are not produced in the whole type domain, but rather -in `[0,1)`. The following method should be implemented for `T <: AbstractFloat`: -`Random.rand(::AbstractRNG, ::Random.SamplerTrivial{Random.CloseOpen01{T}})` +`AbstractFloat` types are special-cased, because by default random values are not produced in the whole type domain, but rather in `[0,1)`. The following method should be implemented for `T <: AbstractFloat`: `Random.rand(::AbstractRNG, ::Random.SamplerTrivial{Random.CloseOpen01{T}})` +#### An optimized sampler with pre-computed data -#### Optimizing generation with cached computation between calls +Consider a discrete distribution, where numbers `1:n` are drawn with given probabilities that sum to one. When many values are needed from this distribution, the fastest method is using an [alias table](https://en.wikipedia.org/wiki/Alias_method). We don't provide the algorithm for building such a table here, but suppose it is available in `make_alias_table(probabilities)` instead, and `draw_number(rng, alias_table)` can be used to draw a random number from it. -When repeatedly generating random values (with the same `rand` parameters), it happens for some types -that the result of a computation is used for each call. In this case, the computation can be decoupled -from actually generating the values. This is the case for example with the default implementation for -`AbstractArray`. Assume that `rand(rng, 1:20)` has to be called repeatedly in a loop: the way to take advantage -of this decoupling is as follows: +Suppose that the distribution is described by +```julia +struct DiscreteDistribution{V <: AbstractVector} + probabilities::V +end +``` +and that we *always* want to build an a alias table, regardless of the number of values needed (we learn how to customize this below). The methods +```julia +Random.eltype(::Type{<:DiscreteDistribution}) = Int +function Random.Sampler(::AbstractRng, distribution::DiscreteDistribution, ::Repetition) + SamplerSimple(disribution, make_alias_table(distribution.probabilities)) +end +``` +should be defined to return a sampler with pre-computed data, then ```julia -rng = MersenneTwister() -sp = Random.Sampler(rng, 1:20) # or Random.Sampler(MersenneTwister,1:20) -for x in X - n = rand(rng, sp) # similar to n = rand(rng, 1:20) - # use n +function rand(rng::AbstractRNG, sp::SamplerSimple{<:DiscreteDistribution}) + draw_number(rng, sp.data) end ``` +will be used to draw the values. + +#### Custom sampler types + +The `SamplerSimple` type is sufficient for most use cases with precomputed data. However, in order to demonstrate how to use custom sampler types, here we implement something similar to `SamplerSimple`. -This mechanism is of course used by the default implementation of random array generation (like in `rand(1:20, 10)`). -In order to implement this decoupling for a custom type, a helper type can be used. -Going back to our `Die` example: `rand(::Die)` uses random generation from a range, so -there is an opportunity for this optimization: +Going back to our `Die` example: `rand(::Die)` uses random generation from a range, so there is an opportunity for this optimization. We call our custom sampler `SamplerDie`. ```julia import Random: Sampler, rand @@ -194,10 +232,9 @@ Sampler(RNG::Type{<:AbstractRNG}, die::Die, r::Random.Repetition) = rand(rng::AbstractRNG, sp::SamplerDie) = rand(rng, sp.sp) ``` -It's now possible to get a sampler with `sp = Sampler(rng, die)`, and use `sp` instead of `die` in any `rand` call involving `rng`. -In the simplistic example above, `die` doesn't need to be stored in `SamplerDie` but this is often the case in practice. +It's now possible to get a sampler with `sp = Sampler(rng, die)`, and use `sp` instead of `die` in any `rand` call involving `rng`. In the simplistic example above, `die` doesn't need to be stored in `SamplerDie` but this is often the case in practice. -This pattern is so frequent that a helper type named `Random.SamplerSimple` is available, +Of course, this pattern is so frequent that the helper type used above, namely `Random.SamplerSimple`, is available, saving us the definition of `SamplerDie`: we could have implemented our decoupling with: ```julia @@ -228,8 +265,7 @@ Sampler(RNG::Type{<:AbstractRNG}, die::Die, ::Val{1}) = SamplerDie1(...) Sampler(RNG::Type{<:AbstractRNG}, die::Die, ::Val{Inf}) = SamplerDieMany(...) ``` -Of course, `rand` must also be defined on those types (i.e. `rand(::AbstractRNG, ::SamplerDie1)` -and `rand(::AbstractRNG, ::SamplerDieMany)`). +Of course, `rand` must also be defined on those types (i.e. `rand(::AbstractRNG, ::SamplerDie1)` and `rand(::AbstractRNG, ::SamplerDieMany)`). Note that, as usual, `SamplerTrivial` and `SamplerSimple` can be used if custom types are not necessary. Note: `Sampler(rng, x)` is simply a shorthand for `Sampler(rng, x, Val(Inf))`, and `Random.Repetition` is an alias for `Union{Val{1}, Val{Inf}}`. diff --git a/src/NEWS.md b/src/NEWS.md index cef8ab9..96e12d2 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -4,6 +4,7 @@ Julia v1.3 Release Notes New language features --------------------- +* Support for Unicode 12.1.0 ([#32002](https://github.com/JuliaLang/julia/issues/32002)). Language changes ---------------- diff --git a/src/assets/logo.png b/src/assets/logo.png index b18f64c712821783ddf9e325ff45184fab1ac888..0e4f86abdddd6d9f3a2d87cb890024ef4181e793 100644 GIT binary patch literal 12311 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 literal 18351 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 KPDHLkV1f#t;m^AO diff --git a/src/manual/metaprogramming.md b/src/manual/metaprogramming.md index ae11362..7faa0e5 100644 --- a/src/manual/metaprogramming.md +++ b/src/manual/metaprogramming.md @@ -1090,16 +1090,17 @@ To make this efficient, the result is usually cached. And to make this inferable subset of the language is usable. Thus, generated functions provide a flexible way to move work from run time to compile time, at the expense of greater restrictions on allowed constructs. -When defining generated functions, there are four main differences to ordinary functions: +When defining generated functions, there are five main differences to ordinary functions: 1. You annotate the function declaration with the `@generated` macro. This adds some information to the AST that lets the compiler know that this is a generated function. 2. In the body of the generated function you only have access to the *types* of the arguments – - not their values – and any function that was defined *before* the definition of the generated - function. + not their values. 3. Instead of calculating something or performing some action, you return a *quoted expression* which, when evaluated, does what you want. -4. Generated functions must not *mutate* or *observe* any non-constant global state (including, +4. Generated functions are only permitted to call functions that were defined *before* the definition of the generated + function. (Failure to follow this my result on getting `MethodErrors` referring to functions from a future world-age.) +5. Generated functions must not *mutate* or *observe* any non-constant global state (including, for example, IO, locks, non-local dictionaries, or using [`hasmethod`](@ref)). This means they can only read global constants, and cannot have any side effects. In other words, they must be completely pure. diff --git a/src/stdlib/Random.md b/src/stdlib/Random.md index f321901..6f23ea2 100644 --- a/src/stdlib/Random.md +++ b/src/stdlib/Random.md @@ -80,18 +80,52 @@ in order to support usual types of generated values. ### Generating random values of custom types -There are two categories: generating values from a type (e.g. `rand(Int)`), or from a collection (e.g. `rand(1:3)`). -The simple cases are explained first, and more advanced usage is presented later. -We assume here that the choice of algorithm is independent of the RNG, so we use `AbstractRNG` in our signatures. +Generating random values for some distributions may involve various trade-offs. *Pre-computed* values, such as an [alias table](https://en.wikipedia.org/wiki/Alias_method) for discrete distributions, or [“squeezing” functions](https://en.wikipedia.org/wiki/Rejection_sampling) for univariate distributions, can speed up sampling considerably. How much information should be pre-computed can depend on the number of values we plan to draw from a distribution. Also, some random number generators can have certain properties that various algorithms may want to exploit. + +The `Random` module defines a customizable framework for obtaining random values that can address these issues. Each invocation of `rand` generates a *sampler* which can be customized with the above trade-offs in mind, by adding methods to `Sampler`, which in turn can dispatch on the random number generator, the object that characterizes the distribution, and a suggestion for the number of repetitions. Currently, for the latter, `Val{1}` (for a single sample) and `Val{Inf}` (for an arbitrary number) are used, with `Random.Repetition` an alias for both. + +The object returned by `Sampler` is then used to generate the random values. When implementing the random generation interface for a value `X` that can be sampled from, the implementor should define the method + +```julia +rand(rng, sampler) +``` +for the particular `sampler` returned by `Sampler(rng, X, repetition)`. + +Samplers can be arbitrary values that implement `rand(rng, sampler)`, but for most applications the following predefined samplers may be sufficient: + +1. `SamplerType{T}()` can be used for implementing samplers that draw from type `T` (e.g. `rand(Int)`). This is the default returned by `Sampler` for *types*. + +2. `SamplerTrivial(self)` is a simple wrapper for `self`, which can be accessed with `[]`. This is the recommended sampler when no pre-computed information is needed (e.g. `rand(1:3)`), and is the default returned by `Sampler` for *values*. + +3. `SamplerSimple(self, data)` also contains the additional `data` field, which can be used to store arbitrary pre-computed values, which should be computed in a *custom method* of `Sampler`. + +We provide examples for each of these. We assume here that the choice of algorithm is independent of the RNG, so we use `AbstractRNG` in our signatures. + +```@docs +Random.Sampler +Random.SamplerType +Random.SamplerTrivial +Random.SamplerSimple +``` + +Decoupling pre-computation from actually generating the values is part of the API, and is also available to the user. As an example, assume that `rand(rng, 1:20)` has to be called repeatedly in a loop: the way to take advantage of this decoupling is as follows: + +```julia +rng = MersenneTwister() +sp = Random.Sampler(rng, 1:20) # or Random.Sampler(MersenneTwister, 1:20) +for x in X + n = rand(rng, sp) # similar to n = rand(rng, 1:20) + # use n +end +``` + +This is the mechanism that is also used in the standard library, e.g. by the default implementation of random array generation (like in `rand(1:20, 10)`). #### Generating values from a type -Given a type `T`, it's currently assumed that if `rand(T)` is defined, an object of type `T` will be produced. -In order to define random generation of values of type `T`, the following method can be defined: -`rand(rng::AbstractRNG, ::Random.SamplerType{T})` (this should return what `rand(rng, T)` is expected to return). +Given a type `T`, it's currently assumed that if `rand(T)` is defined, an object of type `T` will be produced. `SamplerType` is the *default sampler for types*. In order to define random generation of values of type `T`, the `rand(rng::AbstractRNG, ::Random.SamplerType{T})` method should be defined, and should return values what `rand(rng, T)` is expected to return. -Let's take the following example: we implement a `Die` type, with a variable number `n` of sides, numbered from `1` to `n`. -We want `rand(Die)` to produce a die with a random number of up to 20 sides (and at least 4): +Let's take the following example: we implement a `Die` type, with a variable number `n` of sides, numbered from `1` to `n`. We want `rand(Die)` to produce a `Die` with a random number of up to 20 sides (and at least 4): ```jldoctest Die struct Die @@ -126,12 +160,11 @@ julia> a = Vector{Die}(undef, 3); rand!(a) Die(8) ``` -#### Generating values from a collection +#### A simple sampler without pre-computed data + +Here we define a sampler for a collection. If no pre-computed data is required, it can be implemented with a `SamplerTrivial` sampler, which is in fact the *default fallback for values*. -Given a collection type `S`, it's currently assumed that if `rand(::S)` is defined, an object of type `eltype(S)` will be produced. -In order to define random generation out of objects of type `S`, the following method can be defined: -`rand(rng::AbstractRNG, sp::Random.SamplerTrivial{S})`. Here, `sp` simply wraps an object of type `S`, which can be accessed via `sp[]`. -Continuing the `Die` example, we want now to define `rand(d::Die)` to produce an `Int` corresponding to one of `d`'s sides: +In order to define random generation out of objects of type `S`, the following method should be defined: `rand(rng::AbstractRNG, sp::Random.SamplerTrivial{S})`. Here, `sp` simply wraps an object of type `S`, which can be accessed via `sp[]`. Continuing the `Die` example, we want now to define `rand(d::Die)` to produce an `Int` corresponding to one of `d`'s sides: ```jldoctest Die; setup = :(Random.seed!(1)) julia> Random.rand(rng::AbstractRNG, d::Random.SamplerTrivial{Die}) = rand(rng, 1:d[].nsides); @@ -146,38 +179,43 @@ julia> rand(Die(4), 3) 2 ``` -In the last example, a `Vector{Any}` is produced; the reason is that `eltype(Die) == Any`. The remedy is to define -`Base.eltype(::Type{Die}) = Int`. - +Given a collection type `S`, it's currently assumed that if `rand(::S)` is defined, an object of type `eltype(S)` will be produced. In the last example, a `Vector{Any}` is produced; the reason is that `eltype(Die) == Any`. The remedy is to define `Base.eltype(::Type{Die}) = Int`. #### Generating values for an `AbstractFloat` type -`AbstractFloat` types are special-cased, because by default random values are not produced in the whole type domain, but rather -in `[0,1)`. The following method should be implemented for `T <: AbstractFloat`: -`Random.rand(::AbstractRNG, ::Random.SamplerTrivial{Random.CloseOpen01{T}})` +`AbstractFloat` types are special-cased, because by default random values are not produced in the whole type domain, but rather in `[0,1)`. The following method should be implemented for `T <: AbstractFloat`: `Random.rand(::AbstractRNG, ::Random.SamplerTrivial{Random.CloseOpen01{T}})` +#### An optimized sampler with pre-computed data -#### Optimizing generation with cached computation between calls +Consider a discrete distribution, where numbers `1:n` are drawn with given probabilities that sum to one. When many values are needed from this distribution, the fastest method is using an [alias table](https://en.wikipedia.org/wiki/Alias_method). We don't provide the algorithm for building such a table here, but suppose it is available in `make_alias_table(probabilities)` instead, and `draw_number(rng, alias_table)` can be used to draw a random number from it. -When repeatedly generating random values (with the same `rand` parameters), it happens for some types -that the result of a computation is used for each call. In this case, the computation can be decoupled -from actually generating the values. This is the case for example with the default implementation for -`AbstractArray`. Assume that `rand(rng, 1:20)` has to be called repeatedly in a loop: the way to take advantage -of this decoupling is as follows: +Suppose that the distribution is described by +```julia +struct DiscreteDistribution{V <: AbstractVector} + probabilities::V +end +``` +and that we *always* want to build an a alias table, regardless of the number of values needed (we learn how to customize this below). The methods +```julia +Random.eltype(::Type{<:DiscreteDistribution}) = Int +function Random.Sampler(::AbstractRng, distribution::DiscreteDistribution, ::Repetition) + SamplerSimple(disribution, make_alias_table(distribution.probabilities)) +end +``` +should be defined to return a sampler with pre-computed data, then ```julia -rng = MersenneTwister() -sp = Random.Sampler(rng, 1:20) # or Random.Sampler(MersenneTwister,1:20) -for x in X - n = rand(rng, sp) # similar to n = rand(rng, 1:20) - # use n +function rand(rng::AbstractRNG, sp::SamplerSimple{<:DiscreteDistribution}) + draw_number(rng, sp.data) end ``` +will be used to draw the values. + +#### Custom sampler types + +The `SamplerSimple` type is sufficient for most use cases with precomputed data. However, in order to demonstrate how to use custom sampler types, here we implement something similar to `SamplerSimple`. -This mechanism is of course used by the default implementation of random array generation (like in `rand(1:20, 10)`). -In order to implement this decoupling for a custom type, a helper type can be used. -Going back to our `Die` example: `rand(::Die)` uses random generation from a range, so -there is an opportunity for this optimization: +Going back to our `Die` example: `rand(::Die)` uses random generation from a range, so there is an opportunity for this optimization. We call our custom sampler `SamplerDie`. ```julia import Random: Sampler, rand @@ -194,10 +232,9 @@ Sampler(RNG::Type{<:AbstractRNG}, die::Die, r::Random.Repetition) = rand(rng::AbstractRNG, sp::SamplerDie) = rand(rng, sp.sp) ``` -It's now possible to get a sampler with `sp = Sampler(rng, die)`, and use `sp` instead of `die` in any `rand` call involving `rng`. -In the simplistic example above, `die` doesn't need to be stored in `SamplerDie` but this is often the case in practice. +It's now possible to get a sampler with `sp = Sampler(rng, die)`, and use `sp` instead of `die` in any `rand` call involving `rng`. In the simplistic example above, `die` doesn't need to be stored in `SamplerDie` but this is often the case in practice. -This pattern is so frequent that a helper type named `Random.SamplerSimple` is available, +Of course, this pattern is so frequent that the helper type used above, namely `Random.SamplerSimple`, is available, saving us the definition of `SamplerDie`: we could have implemented our decoupling with: ```julia @@ -228,8 +265,7 @@ Sampler(RNG::Type{<:AbstractRNG}, die::Die, ::Val{1}) = SamplerDie1(...) Sampler(RNG::Type{<:AbstractRNG}, die::Die, ::Val{Inf}) = SamplerDieMany(...) ``` -Of course, `rand` must also be defined on those types (i.e. `rand(::AbstractRNG, ::SamplerDie1)` -and `rand(::AbstractRNG, ::SamplerDieMany)`). +Of course, `rand` must also be defined on those types (i.e. `rand(::AbstractRNG, ::SamplerDie1)` and `rand(::AbstractRNG, ::SamplerDieMany)`). Note that, as usual, `SamplerTrivial` and `SamplerSimple` can be used if custom types are not necessary. Note: `Sampler(rng, x)` is simply a shorthand for `Sampler(rng, x, Val(Inf))`, and `Random.Repetition` is an alias for `Union{Val{1}, Val{Inf}}`. From ecd679a4a03e9c4b1eac66de3be0aa436cc37cdf Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Tue, 21 May 2019 19:51:37 +0900 Subject: [PATCH 116/153] update Julia 1.3.0-DEV.258 (2019-05-21) Commit a43c46b687 --- codex/NEWS.md | 8 ++++++++ codex/base/parallel.md | 2 +- codex/devdocs/cartesian.md | 8 ++------ codex/devdocs/gc-sa.md | 10 ++++++++++ codex/manual/environment-variables.md | 6 +++--- codex/manual/faq.md | 2 +- codex/manual/noteworthy-differences.md | 22 ++++++++++++++++++++++ codex/stdlib/LinearAlgebra.md | 11 ++++++++++- src/NEWS.md | 8 ++++++++ src/base/parallel.md | 2 +- src/devdocs/cartesian.md | 8 ++------ src/devdocs/gc-sa.md | 10 ++++++++++ src/manual/environment-variables.md | 6 +++--- src/manual/faq.md | 2 +- src/manual/noteworthy-differences.md | 22 ++++++++++++++++++++++ src/stdlib/LinearAlgebra.md | 11 ++++++++++- 16 files changed, 114 insertions(+), 24 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index 96e12d2..64b23fa 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -36,6 +36,8 @@ Standard library changes * The BLAS submodule no longer exports `dot`, which conflicts with that in LinearAlgebra ([#31838](https://github.com/JuliaLang/julia/issues/31838)). * `diagm` and `spdiagm` now accept optional `m,n` initial arguments to specify a size ([#31654](https://github.com/JuliaLang/julia/issues/31654)). +* `Hessenberg` factorizations `H` now support efficient shifted solves `(H+µI) \ b` and determinants, and use a specialized tridiagonal factorization for Hermitian matrices. There is also a new `UpperHessenberg` matrix type ([#31853](https://github.com/JuliaLang/julia/issues/31853)). + #### SparseArrays @@ -53,4 +55,10 @@ Standard library changes External dependencies --------------------- +Tooling Improvements +--------------------- + +* The `ClangSA.jl` static analysis package has been imported, which makes use of + the clang static analyzer to validate GC invariants in Julia's C code. The analysis + may be run using `make -C src analyzegc`. diff --git a/codex/base/parallel.md b/codex/base/parallel.md index 5a669b2..6b299eb 100644 --- a/codex/base/parallel.md +++ b/codex/base/parallel.md @@ -30,7 +30,7 @@ Base.Threads.Condition Base.notify Base.schedule -Base.Event +Base.Threads.Event Base.Semaphore Base.acquire diff --git a/codex/devdocs/cartesian.md b/codex/devdocs/cartesian.md index 4e548c5..6e115ea 100644 --- a/codex/devdocs/cartesian.md +++ b/codex/devdocs/cartesian.md @@ -1,8 +1,7 @@ # Base.Cartesian The (non-exported) Cartesian module provides macros that facilitate writing multidimensional algorithms. -It is hoped that Cartesian will not, in the long term, be necessary; however, at present it is -one of the few ways to write compact and performant multidimensional code. +Most often you can write such algorithms with [straightforward techniques](https://julialang.org/blog/2016/02/iteration); however, there are a few cases where `Base.Cartesian` is still useful or necessary. ## Principles of usage @@ -72,10 +71,7 @@ DocTestSetup = nothing The first argument to both of these macros is the number of expressions, which must be an integer. When you're writing a function that you intend to work in multiple dimensions, this may not be -something you want to hard-code. If you're writing code that you need to work with older Julia -versions, currently you should use the `@ngenerate` macro described in [an older version of this documentation](https://docs.julialang.org/en/release-0.3/devdocs/cartesian/#supplying-the-number-of-expressions). - -Starting in Julia 0.4-pre, the recommended approach is to use a `@generated function`. Here's +something you want to hard-code. The recommended approach is to use a `@generated function`. Here's an example: ```julia diff --git a/codex/devdocs/gc-sa.md b/codex/devdocs/gc-sa.md index 086601f..432c654 100644 --- a/codex/devdocs/gc-sa.md +++ b/codex/devdocs/gc-sa.md @@ -1,5 +1,15 @@ # Static analyzer annotations for GC correctness in C code +## Running the analysis + +The analyzer plugin that drives the anlysis ships with julia. Its +source code can be found in `src/clangsa`. Running it requires +the clang dependency to be build. Set the `BUILD_LLVM_CLANG` variable +in your Make.user in order to build an appropriate version of clang. +You may also want to use the prebuilt binaries using the +`USE_BINARYBUILDER_LLVM` options. Afterwards, running the analysis +over the source tree is as simple as running `make -C src analyzegc`. + ## General Overview Since Julia's GC is precise, it needs to maintain correct rooting diff --git a/codex/manual/environment-variables.md b/codex/manual/environment-variables.md index 551030f..322c806 100644 --- a/codex/manual/environment-variables.md +++ b/codex/manual/environment-variables.md @@ -116,8 +116,8 @@ environment variable or if it must have a value, set it to the string `:`. The `JULIA_DEPOT_PATH` environment variable is used to populate the global Julia [`DEPOT_PATH`](@ref) variable, which controls where the package manager, as well as Julia's code loading mechanisms, look for package registries, installed -packages, named environments, repo clones, cached compiled package images, and -configuration files. +packages, named environments, repo clones, cached compiled package images, +configuration files, and the default location of the REPL's history file. Unlike the shell `PATH` variable but similar to `JULIA_LOAD_PATH`, empty entries in `JULIA_DEPOT_PATH` are expanded to the default value of `DEPOT_PATH`. This allows @@ -143,7 +143,7 @@ The absolute path `REPL.find_hist_file()` of the REPL's history file. If `$JULIA_HISTORY` is not set, then `REPL.find_hist_file()` defaults to ``` -$HOME/.julia/logs/repl_history.jl +$(DEPOT_PATH[1])/logs/repl_history.jl ``` ### `JULIA_PKGRESOLVE_ACCURACY` diff --git a/codex/manual/faq.md b/codex/manual/faq.md index 498e478..77d1e96 100644 --- a/codex/manual/faq.md +++ b/codex/manual/faq.md @@ -334,7 +334,7 @@ julia> sqrt(-2.0+0im) 0.0 + 1.4142135623730951im ``` -### Why does Julia use native machine integer arithmetic? +### [Why does Julia use native machine integer arithmetic?](@id faq-integer-arithmetic) Julia uses machine arithmetic for integer computations. This means that the range of `Int` values is bounded and wraps around at either end so that adding, subtracting and multiplying integers diff --git a/codex/manual/noteworthy-differences.md b/codex/manual/noteworthy-differences.md index fe53689..5bd810c 100644 --- a/codex/manual/noteworthy-differences.md +++ b/codex/manual/noteworthy-differences.md @@ -308,3 +308,25 @@ For users coming to Julia from R, these are some noteworthy differences: in order to have dynamic dispatch. On the other hand, in Julia every method is "virtual" (although it's more general than that since methods are dispatched on every argument type, not only `this`, using the most-specific-declaration rule). + +## Noteworthy differences from Common Lisp + +- Julia uses 1-based indexing for arrays by default, and it can also handle arbitrary [index offsets](@ref man-custom-indices). + +- Functions and variables share the same namespace (“Lisp-1”). + +- There is a [`Pair`](@ref) type, but it is not meant to be used as a `COMMON-LISP:CONS`. Various iterable collections can be used interchangeably in most parts of the language (eg splatting, tuples, etc). `Tuple`s are the closest to Common Lisp lists for *short* collections of heterogeneous elements. Use `NamedTuple`s in place of alists. For larger collections of homogeneous types, `Array`s and `Dict`s should be used. + +- The typical Julia workflow for prototyping also uses continuous manipulation of the image, implemented with the [Revise.jl](https://github.com/timholy/Revise.jl) package. + +- Bignums are supported, but conversion is not automatic; ordinary integers [overflow](@ref faq-integer-arithmetic). + +- Modules (namespaces) can be hierarchical. [`import`](@ref) and [`using`](@ref) have a dual role: they load the code and make it available in the namespace. `import` for only the module name is possible (roughly equivalent to `ASDF:LOAD-OP`). Slot names don't need to be exported separately. Global variables can't be assigned to from outside the module (except with `eval(mod, :(var = val))` as an escape hatch). + +- Macros start with `@`, and are not as seamlessly integrated into the language as Common Lisp; consequently, macro usage is not as widespread as in the latter. A form of hygiene for [macros](@ref Metaprogramming) is supported by the language. Because of the different surface syntax, there is no equivalent to `COMMON-LISP:&BODY`. + +- *All* functions are generic and use multiple dispatch. Argument lists don't have to follow the same template, which leads to a powerful idiom (see [`do`](@ref)). Optional and keyword arguments are handled differently. Method ambiguities are not resolved like in the Common Lisp Object System, necessitating the definition of a more specific method for the intersection. + +- Symbols do not belong to any package, and do not contain any values *per se*. `M.var` evaluates the symbol `var` in the module `M`. + +- A functional programming style is fully supported by the language, including closures, but isn't always the idiomatic solution for Julia. Some [workarounds](@ref man-performance-captured) may be necessary for performance when modifying captured variables. diff --git a/codex/stdlib/LinearAlgebra.md b/codex/stdlib/LinearAlgebra.md index 81faa64..1db9a6e 100644 --- a/codex/stdlib/LinearAlgebra.md +++ b/codex/stdlib/LinearAlgebra.md @@ -168,8 +168,9 @@ as well as whether hooks to various optimized methods for them in LAPACK are ava | [`Hermitian`](@ref) | [Hermitian matrix](https://en.wikipedia.org/wiki/Hermitian_matrix) | | [`UpperTriangular`](@ref) | Upper [triangular matrix](https://en.wikipedia.org/wiki/Triangular_matrix) | | [`UnitUpperTriangular`](@ref) | Upper [triangular matrix](https://en.wikipedia.org/wiki/Triangular_matrix) with unit diagonal | -| [`LowerTriangular`](@ref) | Lower [triangular matrix](https://en.wikipedia.org/wiki/Triangular_matrix) | +| [`LowerTriangular`](@ref) | Lower [triangular matrix](https://en.wikipedia.org/wiki/Triangular_matrix) | | | [`UnitLowerTriangular`](@ref) | Lower [triangular matrix](https://en.wikipedia.org/wiki/Triangular_matrix) with unit diagonal | +| [`UpperHessenberg`](@ref) | Upper [Hessenberg matrix](https://en.wikipedia.org/wiki/Hessenberg_matrix) | [`Tridiagonal`](@ref) | [Tridiagonal matrix](https://en.wikipedia.org/wiki/Tridiagonal_matrix) | | [`SymTridiagonal`](@ref) | Symmetric tridiagonal matrix | | [`Bidiagonal`](@ref) | Upper/lower [bidiagonal matrix](https://en.wikipedia.org/wiki/Bidiagonal_matrix) | @@ -186,6 +187,7 @@ as well as whether hooks to various optimized methods for them in LAPACK are ava | [`UnitUpperTriangular`](@ref) | | | MV | MV | [`inv`](@ref), [`det`](@ref) | | [`LowerTriangular`](@ref) | | | MV | MV | [`inv`](@ref), [`det`](@ref) | | [`UnitLowerTriangular`](@ref) | | | MV | MV | [`inv`](@ref), [`det`](@ref) | +| [`UpperHessenberg`](@ref) | | | | MM | [`inv`](@ref), [`det`](@ref) | | [`SymTridiagonal`](@ref) | M | M | MS | MV | [`eigmax`](@ref), [`eigmin`](@ref) | | [`Tridiagonal`](@ref) | M | M | MS | MV | | | [`Bidiagonal`](@ref) | M | M | MS | MV | | @@ -269,6 +271,12 @@ Stacktrace: [...] ``` +If you need to solve many systems of the form `(A+μI)x = b` for the same `A` and different `μ`, it might be beneficial +to first compute the Hessenberg factorization `F` of `A` via the [`hessenberg`](@ref) function. +Given `F`, Julia employs an efficient algorithm for `(F+μ*I) \ b` (equivalent to `(A+μ*I)x \ b`) and related +operations like determinants. + + ## [Matrix factorizations](@id man-linalg-factorizations) [Matrix factorizations (a.k.a. matrix decompositions)](https://en.wikipedia.org/wiki/Matrix_decomposition) @@ -319,6 +327,7 @@ LinearAlgebra.LowerTriangular LinearAlgebra.UpperTriangular LinearAlgebra.UnitLowerTriangular LinearAlgebra.UnitUpperTriangular +LinearAlgebra.UpperHessenberg LinearAlgebra.UniformScaling LinearAlgebra.lu LinearAlgebra.lu! diff --git a/src/NEWS.md b/src/NEWS.md index 96e12d2..64b23fa 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -36,6 +36,8 @@ Standard library changes * The BLAS submodule no longer exports `dot`, which conflicts with that in LinearAlgebra ([#31838](https://github.com/JuliaLang/julia/issues/31838)). * `diagm` and `spdiagm` now accept optional `m,n` initial arguments to specify a size ([#31654](https://github.com/JuliaLang/julia/issues/31654)). +* `Hessenberg` factorizations `H` now support efficient shifted solves `(H+µI) \ b` and determinants, and use a specialized tridiagonal factorization for Hermitian matrices. There is also a new `UpperHessenberg` matrix type ([#31853](https://github.com/JuliaLang/julia/issues/31853)). + #### SparseArrays @@ -53,4 +55,10 @@ Standard library changes External dependencies --------------------- +Tooling Improvements +--------------------- + +* The `ClangSA.jl` static analysis package has been imported, which makes use of + the clang static analyzer to validate GC invariants in Julia's C code. The analysis + may be run using `make -C src analyzegc`. diff --git a/src/base/parallel.md b/src/base/parallel.md index 5a669b2..6b299eb 100644 --- a/src/base/parallel.md +++ b/src/base/parallel.md @@ -30,7 +30,7 @@ Base.Threads.Condition Base.notify Base.schedule -Base.Event +Base.Threads.Event Base.Semaphore Base.acquire diff --git a/src/devdocs/cartesian.md b/src/devdocs/cartesian.md index 4e548c5..6e115ea 100644 --- a/src/devdocs/cartesian.md +++ b/src/devdocs/cartesian.md @@ -1,8 +1,7 @@ # Base.Cartesian The (non-exported) Cartesian module provides macros that facilitate writing multidimensional algorithms. -It is hoped that Cartesian will not, in the long term, be necessary; however, at present it is -one of the few ways to write compact and performant multidimensional code. +Most often you can write such algorithms with [straightforward techniques](https://julialang.org/blog/2016/02/iteration); however, there are a few cases where `Base.Cartesian` is still useful or necessary. ## Principles of usage @@ -72,10 +71,7 @@ DocTestSetup = nothing The first argument to both of these macros is the number of expressions, which must be an integer. When you're writing a function that you intend to work in multiple dimensions, this may not be -something you want to hard-code. If you're writing code that you need to work with older Julia -versions, currently you should use the `@ngenerate` macro described in [an older version of this documentation](https://docs.julialang.org/en/release-0.3/devdocs/cartesian/#supplying-the-number-of-expressions). - -Starting in Julia 0.4-pre, the recommended approach is to use a `@generated function`. Here's +something you want to hard-code. The recommended approach is to use a `@generated function`. Here's an example: ```julia diff --git a/src/devdocs/gc-sa.md b/src/devdocs/gc-sa.md index 086601f..432c654 100644 --- a/src/devdocs/gc-sa.md +++ b/src/devdocs/gc-sa.md @@ -1,5 +1,15 @@ # Static analyzer annotations for GC correctness in C code +## Running the analysis + +The analyzer plugin that drives the anlysis ships with julia. Its +source code can be found in `src/clangsa`. Running it requires +the clang dependency to be build. Set the `BUILD_LLVM_CLANG` variable +in your Make.user in order to build an appropriate version of clang. +You may also want to use the prebuilt binaries using the +`USE_BINARYBUILDER_LLVM` options. Afterwards, running the analysis +over the source tree is as simple as running `make -C src analyzegc`. + ## General Overview Since Julia's GC is precise, it needs to maintain correct rooting diff --git a/src/manual/environment-variables.md b/src/manual/environment-variables.md index 551030f..322c806 100644 --- a/src/manual/environment-variables.md +++ b/src/manual/environment-variables.md @@ -116,8 +116,8 @@ environment variable or if it must have a value, set it to the string `:`. The `JULIA_DEPOT_PATH` environment variable is used to populate the global Julia [`DEPOT_PATH`](@ref) variable, which controls where the package manager, as well as Julia's code loading mechanisms, look for package registries, installed -packages, named environments, repo clones, cached compiled package images, and -configuration files. +packages, named environments, repo clones, cached compiled package images, +configuration files, and the default location of the REPL's history file. Unlike the shell `PATH` variable but similar to `JULIA_LOAD_PATH`, empty entries in `JULIA_DEPOT_PATH` are expanded to the default value of `DEPOT_PATH`. This allows @@ -143,7 +143,7 @@ The absolute path `REPL.find_hist_file()` of the REPL's history file. If `$JULIA_HISTORY` is not set, then `REPL.find_hist_file()` defaults to ``` -$HOME/.julia/logs/repl_history.jl +$(DEPOT_PATH[1])/logs/repl_history.jl ``` ### `JULIA_PKGRESOLVE_ACCURACY` diff --git a/src/manual/faq.md b/src/manual/faq.md index 498e478..77d1e96 100644 --- a/src/manual/faq.md +++ b/src/manual/faq.md @@ -334,7 +334,7 @@ julia> sqrt(-2.0+0im) 0.0 + 1.4142135623730951im ``` -### Why does Julia use native machine integer arithmetic? +### [Why does Julia use native machine integer arithmetic?](@id faq-integer-arithmetic) Julia uses machine arithmetic for integer computations. This means that the range of `Int` values is bounded and wraps around at either end so that adding, subtracting and multiplying integers diff --git a/src/manual/noteworthy-differences.md b/src/manual/noteworthy-differences.md index fe53689..5bd810c 100644 --- a/src/manual/noteworthy-differences.md +++ b/src/manual/noteworthy-differences.md @@ -308,3 +308,25 @@ For users coming to Julia from R, these are some noteworthy differences: in order to have dynamic dispatch. On the other hand, in Julia every method is "virtual" (although it's more general than that since methods are dispatched on every argument type, not only `this`, using the most-specific-declaration rule). + +## Noteworthy differences from Common Lisp + +- Julia uses 1-based indexing for arrays by default, and it can also handle arbitrary [index offsets](@ref man-custom-indices). + +- Functions and variables share the same namespace (“Lisp-1”). + +- There is a [`Pair`](@ref) type, but it is not meant to be used as a `COMMON-LISP:CONS`. Various iterable collections can be used interchangeably in most parts of the language (eg splatting, tuples, etc). `Tuple`s are the closest to Common Lisp lists for *short* collections of heterogeneous elements. Use `NamedTuple`s in place of alists. For larger collections of homogeneous types, `Array`s and `Dict`s should be used. + +- The typical Julia workflow for prototyping also uses continuous manipulation of the image, implemented with the [Revise.jl](https://github.com/timholy/Revise.jl) package. + +- Bignums are supported, but conversion is not automatic; ordinary integers [overflow](@ref faq-integer-arithmetic). + +- Modules (namespaces) can be hierarchical. [`import`](@ref) and [`using`](@ref) have a dual role: they load the code and make it available in the namespace. `import` for only the module name is possible (roughly equivalent to `ASDF:LOAD-OP`). Slot names don't need to be exported separately. Global variables can't be assigned to from outside the module (except with `eval(mod, :(var = val))` as an escape hatch). + +- Macros start with `@`, and are not as seamlessly integrated into the language as Common Lisp; consequently, macro usage is not as widespread as in the latter. A form of hygiene for [macros](@ref Metaprogramming) is supported by the language. Because of the different surface syntax, there is no equivalent to `COMMON-LISP:&BODY`. + +- *All* functions are generic and use multiple dispatch. Argument lists don't have to follow the same template, which leads to a powerful idiom (see [`do`](@ref)). Optional and keyword arguments are handled differently. Method ambiguities are not resolved like in the Common Lisp Object System, necessitating the definition of a more specific method for the intersection. + +- Symbols do not belong to any package, and do not contain any values *per se*. `M.var` evaluates the symbol `var` in the module `M`. + +- A functional programming style is fully supported by the language, including closures, but isn't always the idiomatic solution for Julia. Some [workarounds](@ref man-performance-captured) may be necessary for performance when modifying captured variables. diff --git a/src/stdlib/LinearAlgebra.md b/src/stdlib/LinearAlgebra.md index 81faa64..1db9a6e 100644 --- a/src/stdlib/LinearAlgebra.md +++ b/src/stdlib/LinearAlgebra.md @@ -168,8 +168,9 @@ as well as whether hooks to various optimized methods for them in LAPACK are ava | [`Hermitian`](@ref) | [Hermitian matrix](https://en.wikipedia.org/wiki/Hermitian_matrix) | | [`UpperTriangular`](@ref) | Upper [triangular matrix](https://en.wikipedia.org/wiki/Triangular_matrix) | | [`UnitUpperTriangular`](@ref) | Upper [triangular matrix](https://en.wikipedia.org/wiki/Triangular_matrix) with unit diagonal | -| [`LowerTriangular`](@ref) | Lower [triangular matrix](https://en.wikipedia.org/wiki/Triangular_matrix) | +| [`LowerTriangular`](@ref) | Lower [triangular matrix](https://en.wikipedia.org/wiki/Triangular_matrix) | | | [`UnitLowerTriangular`](@ref) | Lower [triangular matrix](https://en.wikipedia.org/wiki/Triangular_matrix) with unit diagonal | +| [`UpperHessenberg`](@ref) | Upper [Hessenberg matrix](https://en.wikipedia.org/wiki/Hessenberg_matrix) | [`Tridiagonal`](@ref) | [Tridiagonal matrix](https://en.wikipedia.org/wiki/Tridiagonal_matrix) | | [`SymTridiagonal`](@ref) | Symmetric tridiagonal matrix | | [`Bidiagonal`](@ref) | Upper/lower [bidiagonal matrix](https://en.wikipedia.org/wiki/Bidiagonal_matrix) | @@ -186,6 +187,7 @@ as well as whether hooks to various optimized methods for them in LAPACK are ava | [`UnitUpperTriangular`](@ref) | | | MV | MV | [`inv`](@ref), [`det`](@ref) | | [`LowerTriangular`](@ref) | | | MV | MV | [`inv`](@ref), [`det`](@ref) | | [`UnitLowerTriangular`](@ref) | | | MV | MV | [`inv`](@ref), [`det`](@ref) | +| [`UpperHessenberg`](@ref) | | | | MM | [`inv`](@ref), [`det`](@ref) | | [`SymTridiagonal`](@ref) | M | M | MS | MV | [`eigmax`](@ref), [`eigmin`](@ref) | | [`Tridiagonal`](@ref) | M | M | MS | MV | | | [`Bidiagonal`](@ref) | M | M | MS | MV | | @@ -269,6 +271,12 @@ Stacktrace: [...] ``` +If you need to solve many systems of the form `(A+μI)x = b` for the same `A` and different `μ`, it might be beneficial +to first compute the Hessenberg factorization `F` of `A` via the [`hessenberg`](@ref) function. +Given `F`, Julia employs an efficient algorithm for `(F+μ*I) \ b` (equivalent to `(A+μ*I)x \ b`) and related +operations like determinants. + + ## [Matrix factorizations](@id man-linalg-factorizations) [Matrix factorizations (a.k.a. matrix decompositions)](https://en.wikipedia.org/wiki/Matrix_decomposition) @@ -319,6 +327,7 @@ LinearAlgebra.LowerTriangular LinearAlgebra.UpperTriangular LinearAlgebra.UnitLowerTriangular LinearAlgebra.UnitUpperTriangular +LinearAlgebra.UpperHessenberg LinearAlgebra.UniformScaling LinearAlgebra.lu LinearAlgebra.lu! From 5af2ca3ed108b44d570608286ab16d367302d127 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Wed, 29 May 2019 11:47:00 +0900 Subject: [PATCH 117/153] update Julia 1.3.0-DEV.301 (2019-05-29) Commit 1a3f1f7d98 --- codex/NEWS.md | 2 ++ codex/base/base.md | 1 + codex/manual/faq.md | 4 ++-- codex/stdlib/Dates.md | 2 +- src/NEWS.md | 2 ++ src/base/base.md | 1 + src/manual/faq.md | 4 ++-- src/stdlib/Dates.md | 2 +- 8 files changed, 12 insertions(+), 6 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index 64b23fa..e955ef3 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -30,6 +30,7 @@ Standard library changes * Cmd interpolation (`` `$(x::Cmd) a b c` `` where) now propagates `x`'s process flags (environment, flags, working directory, etc) if `x` is the first interpolant and errors otherwise ([#24353](https://github.com/JuliaLang/julia/issues/24353)). +* `IPAddr` subtypes now behave like scalars when used in broadcasting ([#32133](https://github.com/JuliaLang/julia/issues/32133)). #### LinearAlgebra @@ -43,6 +44,7 @@ Standard library changes #### Dates +* Fixed `repr` such that it displays `Time` as it would be entered in Julia ([#32103](https://github.com/JuliaLang/julia/issues/32103)). #### Statistics diff --git a/codex/base/base.md b/codex/base/base.md index a2b6a0a..3006636 100644 --- a/codex/base/base.md +++ b/codex/base/base.md @@ -161,6 +161,7 @@ Base.isdispatchtuple Base.isimmutable Base.isabstracttype Base.isprimitivetype +Base.issingletontype Base.isstructtype Base.nameof(::DataType) Base.fieldnames diff --git a/codex/manual/faq.md b/codex/manual/faq.md index 77d1e96..5a2cd50 100644 --- a/codex/manual/faq.md +++ b/codex/manual/faq.md @@ -819,8 +819,8 @@ some ideas that might help to understand Julia's definition. therefore its length is `1`. * Zero-dimensional arrays don't natively have any dimensions into which you index -- they’re just `A[]`. We can apply the same "trailing one" rule for them - as for all other array dimensionalities, so you can indeed index them as - `A[1]`, `A[1,1]`, etc. + as for all other array dimensionalities, so you can indeed index them as `A[1]`, `A[1,1]`, etc; see + [Omitted and extra indices](@ref). It is also important to understand the differences to ordinary scalars. Scalars are not mutable containers (even though they are iterable and define things diff --git a/codex/stdlib/Dates.md b/codex/stdlib/Dates.md index c852943..1fa6f27 100644 --- a/codex/stdlib/Dates.md +++ b/codex/stdlib/Dates.md @@ -654,7 +654,7 @@ Dates.DateTime(::Dates.Period) Dates.DateTime(::Function, ::Any...) Dates.DateTime(::Dates.TimeType) Dates.DateTime(::AbstractString, ::AbstractString) -Dates.format +Dates.format(::Dates.TimeType, ::AbstractString) Dates.DateFormat Dates.@dateformat_str Dates.DateTime(::AbstractString, ::Dates.DateFormat) diff --git a/src/NEWS.md b/src/NEWS.md index 64b23fa..e955ef3 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -30,6 +30,7 @@ Standard library changes * Cmd interpolation (`` `$(x::Cmd) a b c` `` where) now propagates `x`'s process flags (environment, flags, working directory, etc) if `x` is the first interpolant and errors otherwise ([#24353](https://github.com/JuliaLang/julia/issues/24353)). +* `IPAddr` subtypes now behave like scalars when used in broadcasting ([#32133](https://github.com/JuliaLang/julia/issues/32133)). #### LinearAlgebra @@ -43,6 +44,7 @@ Standard library changes #### Dates +* Fixed `repr` such that it displays `Time` as it would be entered in Julia ([#32103](https://github.com/JuliaLang/julia/issues/32103)). #### Statistics diff --git a/src/base/base.md b/src/base/base.md index a2b6a0a..3006636 100644 --- a/src/base/base.md +++ b/src/base/base.md @@ -161,6 +161,7 @@ Base.isdispatchtuple Base.isimmutable Base.isabstracttype Base.isprimitivetype +Base.issingletontype Base.isstructtype Base.nameof(::DataType) Base.fieldnames diff --git a/src/manual/faq.md b/src/manual/faq.md index 77d1e96..5a2cd50 100644 --- a/src/manual/faq.md +++ b/src/manual/faq.md @@ -819,8 +819,8 @@ some ideas that might help to understand Julia's definition. therefore its length is `1`. * Zero-dimensional arrays don't natively have any dimensions into which you index -- they’re just `A[]`. We can apply the same "trailing one" rule for them - as for all other array dimensionalities, so you can indeed index them as - `A[1]`, `A[1,1]`, etc. + as for all other array dimensionalities, so you can indeed index them as `A[1]`, `A[1,1]`, etc; see + [Omitted and extra indices](@ref). It is also important to understand the differences to ordinary scalars. Scalars are not mutable containers (even though they are iterable and define things diff --git a/src/stdlib/Dates.md b/src/stdlib/Dates.md index c852943..1fa6f27 100644 --- a/src/stdlib/Dates.md +++ b/src/stdlib/Dates.md @@ -654,7 +654,7 @@ Dates.DateTime(::Dates.Period) Dates.DateTime(::Function, ::Any...) Dates.DateTime(::Dates.TimeType) Dates.DateTime(::AbstractString, ::AbstractString) -Dates.format +Dates.format(::Dates.TimeType, ::AbstractString) Dates.DateFormat Dates.@dateformat_str Dates.DateTime(::AbstractString, ::Dates.DateFormat) From c6736ca31333234e976448ebc3aa24e687cdccb7 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Wed, 12 Jun 2019 20:01:04 +0900 Subject: [PATCH 118/153] update Julia 1.3.0-DEV.395 (2019-06-11) Commit b7774095f6 --- codex/NEWS.md | 15 +++++- codex/manual/calling-c-and-fortran-code.md | 2 +- codex/manual/strings.md | 5 +- codex/stdlib/LinearAlgebra.md | 54 ++++++++++++++-------- codex/stdlib/Random.md | 7 +++ codex/stdlib/Sockets.md | 2 + src/NEWS.md | 15 +++++- src/manual/calling-c-and-fortran-code.md | 2 +- src/manual/strings.md | 5 +- src/stdlib/LinearAlgebra.md | 54 ++++++++++++++-------- src/stdlib/Random.md | 7 +++ src/stdlib/Sockets.md | 2 + 12 files changed, 122 insertions(+), 48 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index e955ef3..9ef4808 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -21,22 +21,28 @@ Build system changes New library functions --------------------- +* `findfirst`, `findlast`, `findnext` and `findprev` now accept a character as first argument + to search for that character in a string passed as the second argument ([#31664](https://github.com/JuliaLang/julia/issues/31664)). * New `findall(pattern, string)` method where `pattern` is a string or regex ([#31834](https://github.com/JuliaLang/julia/issues/31834)). Standard library changes ------------------------ * `Regex` can now be multiplied (`*`) and exponentiated (`^`), like strings ([#23422](https://github.com/JuliaLang/julia/issues/23422)). -* Cmd interpolation (`` `$(x::Cmd) a b c` `` where) now propagates `x`'s process flags +* `Cmd` interpolation (`` `$(x::Cmd) a b c` `` where) now propagates `x`'s process flags (environment, flags, working directory, etc) if `x` is the first interpolant and errors otherwise ([#24353](https://github.com/JuliaLang/julia/issues/24353)). * `IPAddr` subtypes now behave like scalars when used in broadcasting ([#32133](https://github.com/JuliaLang/julia/issues/32133)). +* `clamp` can now handle missing values ([#31066](https://github.com/JuliaLang/julia/issues/31066)). + +#### Libdl + +* `dlopen()` can now be invoked in `do`-block syntax, similar to `open()`. #### LinearAlgebra * The BLAS submodule no longer exports `dot`, which conflicts with that in LinearAlgebra ([#31838](https://github.com/JuliaLang/julia/issues/31838)). * `diagm` and `spdiagm` now accept optional `m,n` initial arguments to specify a size ([#31654](https://github.com/JuliaLang/julia/issues/31654)). - * `Hessenberg` factorizations `H` now support efficient shifted solves `(H+µI) \ b` and determinants, and use a specialized tridiagonal factorization for Hermitian matrices. There is also a new `UpperHessenberg` matrix type ([#31853](https://github.com/JuliaLang/julia/issues/31853)). #### SparseArrays @@ -46,6 +52,11 @@ Standard library changes * Fixed `repr` such that it displays `Time` as it would be entered in Julia ([#32103](https://github.com/JuliaLang/julia/issues/32103)). +#### Sockets + +* `getipaddrs` returns IP addresses in the order provided by libuv ([#32260](https://github.com/JuliaLang/julia/issues/32260)). +* `getipaddr` prefers to return the first `IPv4` interface address provided by libuv ([#32260](https://github.com/JuliaLang/julia/issues/32260)). + #### Statistics * `mean` now accepts both a function argument and a `dims` keyword ([#31576](https://github.com/JuliaLang/julia/issues/31576)). diff --git a/codex/manual/calling-c-and-fortran-code.md b/codex/manual/calling-c-and-fortran-code.md index 54c069a..2104d96 100644 --- a/codex/manual/calling-c-and-fortran-code.md +++ b/codex/manual/calling-c-and-fortran-code.md @@ -178,7 +178,7 @@ Julia function. The arguments to [`@cfunction`](@ref) are: !!! note Currently, only the platform-default C calling convention is supported. This means that `@cfunction`-generated pointers cannot be used in calls where WINAPI expects `stdcall` - function on 32-bit windows, but can be used on WIN64 (where `stdcall` is unified with the + function on 32-bit Windows, but can be used on WIN64 (where `stdcall` is unified with the C calling convention). A classic example is the standard C library `qsort` function, declared as: diff --git a/codex/manual/strings.md b/codex/manual/strings.md index 1010baa..e3b5935 100644 --- a/codex/manual/strings.md +++ b/codex/manual/strings.md @@ -202,14 +202,13 @@ Using an index less than 1 or greater than `end` raises an error: ```jldoctest helloworldstring julia> str[0] -ERROR: BoundsError: attempt to access "Hello, world.\n" +ERROR: BoundsError: attempt to access String at index [0] [...] julia> str[end+1] -ERROR: BoundsError: attempt to access "Hello, world.\n" +ERROR: BoundsError: attempt to access String at index [15] -Stacktrace: [...] ``` diff --git a/codex/stdlib/LinearAlgebra.md b/codex/stdlib/LinearAlgebra.md index 1db9a6e..fbf69e8 100644 --- a/codex/stdlib/LinearAlgebra.md +++ b/codex/stdlib/LinearAlgebra.md @@ -287,20 +287,24 @@ The following table summarizes the types of matrix factorizations that have been Julia. Details of their associated methods can be found in the [Standard Functions](@ref) section of the Linear Algebra documentation. -| Type | Description | -|:----------------- |:-------------------------------------------------------------------------------------------------------------- | -| `Cholesky` | [Cholesky factorization](https://en.wikipedia.org/wiki/Cholesky_decomposition) | -| `CholeskyPivoted` | [Pivoted](https://en.wikipedia.org/wiki/Pivot_element) Cholesky factorization | -| `LU` | [LU factorization](https://en.wikipedia.org/wiki/LU_decomposition) | -| `LUTridiagonal` | LU factorization for [`Tridiagonal`](@ref) matrices | -| `QR` | [QR factorization](https://en.wikipedia.org/wiki/QR_decomposition) | -| `QRCompactWY` | Compact WY form of the QR factorization | -| `QRPivoted` | Pivoted [QR factorization](https://en.wikipedia.org/wiki/QR_decomposition) | -| `Hessenberg` | [Hessenberg decomposition](http://mathworld.wolfram.com/HessenbergDecomposition.html) | -| `Eigen` | [Spectral decomposition](https://en.wikipedia.org/wiki/Eigendecomposition_(matrix)) | -| `SVD` | [Singular value decomposition](https://en.wikipedia.org/wiki/Singular_value_decomposition) | -| `GeneralizedSVD` | [Generalized SVD](https://en.wikipedia.org/wiki/Generalized_singular_value_decomposition#Higher_order_version) | - +| Type | Description | +|:------------------ |:-------------------------------------------------------------------------------------------------------------- | +| `BunchKaufman` | Bunch-Kaufman factorization | +| `Cholesky` | [Cholesky factorization](https://en.wikipedia.org/wiki/Cholesky_decomposition) | +| `CholeskyPivoted` | [Pivoted](https://en.wikipedia.org/wiki/Pivot_element) Cholesky factorization | +| `LDLt` | [LDL(T) factorization](https://en.wikipedia.org/wiki/Cholesky_decomposition#LDL_decomposition) | +| `LU` | [LU factorization](https://en.wikipedia.org/wiki/LU_decomposition) | +| `QR` | [QR factorization](https://en.wikipedia.org/wiki/QR_decomposition) | +| `QRCompactWY` | Compact WY form of the QR factorization | +| `QRPivoted` | Pivoted [QR factorization](https://en.wikipedia.org/wiki/QR_decomposition) | +| `LQ` | [QR factorization](https://en.wikipedia.org/wiki/QR_decomposition) of `transpose(A)` | +| `Hessenberg` | [Hessenberg decomposition](http://mathworld.wolfram.com/HessenbergDecomposition.html) | +| `Eigen` | [Spectral decomposition](https://en.wikipedia.org/wiki/Eigendecomposition_of_a_matrix) | +| `GeneralizedEigen` | [Generalized spectral decomposition](https://en.wikipedia.org/wiki/Eigendecomposition_of_a_matrix#Generalized_eigenvalue_problem) | +| `SVD` | [Singular value decomposition](https://en.wikipedia.org/wiki/Singular_value_decomposition) | +| `GeneralizedSVD` | [Generalized SVD](https://en.wikipedia.org/wiki/Generalized_singular_value_decomposition#Higher_order_version) | +| `Schur` | [Schur decomposition](https://en.wikipedia.org/wiki/Schur_decomposition) | +| `GeneralizedSchur` | [Generalized Schur decomposition](https://en.wikipedia.org/wiki/Schur_decomposition#Generalized_Schur_decomposition) | @@ -329,25 +333,34 @@ LinearAlgebra.UnitLowerTriangular LinearAlgebra.UnitUpperTriangular LinearAlgebra.UpperHessenberg LinearAlgebra.UniformScaling +LinearAlgebra.Factorization +LinearAlgebra.LU LinearAlgebra.lu LinearAlgebra.lu! +LinearAlgebra.Cholesky +LinearAlgebra.CholeskyPivoted LinearAlgebra.cholesky LinearAlgebra.cholesky! LinearAlgebra.lowrankupdate LinearAlgebra.lowrankdowndate LinearAlgebra.lowrankupdate! LinearAlgebra.lowrankdowndate! +LinearAlgebra.LDLt LinearAlgebra.ldlt LinearAlgebra.ldlt! -LinearAlgebra.qr -LinearAlgebra.qr! LinearAlgebra.QR LinearAlgebra.QRCompactWY LinearAlgebra.QRPivoted -LinearAlgebra.lq! +LinearAlgebra.qr +LinearAlgebra.qr! +LinearAlgebra.LQ LinearAlgebra.lq +LinearAlgebra.lq! +LinearAlgebra.BunchKaufman LinearAlgebra.bunchkaufman LinearAlgebra.bunchkaufman! +LinearAlgebra.Eigen +LinearAlgebra.GeneralizedEigen LinearAlgebra.eigvals LinearAlgebra.eigvals! LinearAlgebra.eigmax @@ -355,12 +368,17 @@ LinearAlgebra.eigmin LinearAlgebra.eigvecs LinearAlgebra.eigen LinearAlgebra.eigen! +LinearAlgebra.Hessenberg LinearAlgebra.hessenberg LinearAlgebra.hessenberg! -LinearAlgebra.schur! +LinearAlgebra.Schur +LinearAlgebra.GeneralizedSchur LinearAlgebra.schur +LinearAlgebra.schur! LinearAlgebra.ordschur LinearAlgebra.ordschur! +LinearAlgebra.SVD +LinearAlgebra.GeneralizedSVD LinearAlgebra.svd LinearAlgebra.svd! LinearAlgebra.svdvals diff --git a/codex/stdlib/Random.md b/codex/stdlib/Random.md index 6f23ea2..35ff059 100644 --- a/codex/stdlib/Random.md +++ b/codex/stdlib/Random.md @@ -248,6 +248,13 @@ Here, `sp.data` refers to the second parameter in the call to the `SamplerSimple (in this case equal to `Sampler(rng, 1:die.nsides, r)`), while the `Die` object can be accessed via `sp[]`. +Like `SamplerDie`, any custom sampler must be a subtype of `Sampler{T}` where `T` is the type +of the generated values. Note that `SamplerSimple(x, data) isa Sampler{eltype(x)}`, +so this constrains what the first argument to `SamplerSimple` can be +(it's recommended to use `SamplerSimple` like in the `Die` example, where +`x` is simply forwarded while defining a `Sampler` method). +Similarly, `SamplerTrivial(x) isa Sampler{eltype(x)}`. + Another helper type is currently available for other cases, `Random.SamplerTag`, but is considered as internal API, and can break at any time without proper deprecations. diff --git a/codex/stdlib/Sockets.md b/codex/stdlib/Sockets.md index f993e83..90acd10 100644 --- a/codex/stdlib/Sockets.md +++ b/codex/stdlib/Sockets.md @@ -30,6 +30,8 @@ Sockets.send Sockets.recv Sockets.recvfrom Sockets.setopt +Sockets.nagle +Sockets.quickack ``` ```@meta diff --git a/src/NEWS.md b/src/NEWS.md index e955ef3..9ef4808 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -21,22 +21,28 @@ Build system changes New library functions --------------------- +* `findfirst`, `findlast`, `findnext` and `findprev` now accept a character as first argument + to search for that character in a string passed as the second argument ([#31664](https://github.com/JuliaLang/julia/issues/31664)). * New `findall(pattern, string)` method where `pattern` is a string or regex ([#31834](https://github.com/JuliaLang/julia/issues/31834)). Standard library changes ------------------------ * `Regex` can now be multiplied (`*`) and exponentiated (`^`), like strings ([#23422](https://github.com/JuliaLang/julia/issues/23422)). -* Cmd interpolation (`` `$(x::Cmd) a b c` `` where) now propagates `x`'s process flags +* `Cmd` interpolation (`` `$(x::Cmd) a b c` `` where) now propagates `x`'s process flags (environment, flags, working directory, etc) if `x` is the first interpolant and errors otherwise ([#24353](https://github.com/JuliaLang/julia/issues/24353)). * `IPAddr` subtypes now behave like scalars when used in broadcasting ([#32133](https://github.com/JuliaLang/julia/issues/32133)). +* `clamp` can now handle missing values ([#31066](https://github.com/JuliaLang/julia/issues/31066)). + +#### Libdl + +* `dlopen()` can now be invoked in `do`-block syntax, similar to `open()`. #### LinearAlgebra * The BLAS submodule no longer exports `dot`, which conflicts with that in LinearAlgebra ([#31838](https://github.com/JuliaLang/julia/issues/31838)). * `diagm` and `spdiagm` now accept optional `m,n` initial arguments to specify a size ([#31654](https://github.com/JuliaLang/julia/issues/31654)). - * `Hessenberg` factorizations `H` now support efficient shifted solves `(H+µI) \ b` and determinants, and use a specialized tridiagonal factorization for Hermitian matrices. There is also a new `UpperHessenberg` matrix type ([#31853](https://github.com/JuliaLang/julia/issues/31853)). #### SparseArrays @@ -46,6 +52,11 @@ Standard library changes * Fixed `repr` such that it displays `Time` as it would be entered in Julia ([#32103](https://github.com/JuliaLang/julia/issues/32103)). +#### Sockets + +* `getipaddrs` returns IP addresses in the order provided by libuv ([#32260](https://github.com/JuliaLang/julia/issues/32260)). +* `getipaddr` prefers to return the first `IPv4` interface address provided by libuv ([#32260](https://github.com/JuliaLang/julia/issues/32260)). + #### Statistics * `mean` now accepts both a function argument and a `dims` keyword ([#31576](https://github.com/JuliaLang/julia/issues/31576)). diff --git a/src/manual/calling-c-and-fortran-code.md b/src/manual/calling-c-and-fortran-code.md index 54c069a..2104d96 100644 --- a/src/manual/calling-c-and-fortran-code.md +++ b/src/manual/calling-c-and-fortran-code.md @@ -178,7 +178,7 @@ Julia function. The arguments to [`@cfunction`](@ref) are: !!! note Currently, only the platform-default C calling convention is supported. This means that `@cfunction`-generated pointers cannot be used in calls where WINAPI expects `stdcall` - function on 32-bit windows, but can be used on WIN64 (where `stdcall` is unified with the + function on 32-bit Windows, but can be used on WIN64 (where `stdcall` is unified with the C calling convention). A classic example is the standard C library `qsort` function, declared as: diff --git a/src/manual/strings.md b/src/manual/strings.md index 1010baa..e3b5935 100644 --- a/src/manual/strings.md +++ b/src/manual/strings.md @@ -202,14 +202,13 @@ Using an index less than 1 or greater than `end` raises an error: ```jldoctest helloworldstring julia> str[0] -ERROR: BoundsError: attempt to access "Hello, world.\n" +ERROR: BoundsError: attempt to access String at index [0] [...] julia> str[end+1] -ERROR: BoundsError: attempt to access "Hello, world.\n" +ERROR: BoundsError: attempt to access String at index [15] -Stacktrace: [...] ``` diff --git a/src/stdlib/LinearAlgebra.md b/src/stdlib/LinearAlgebra.md index 1db9a6e..fbf69e8 100644 --- a/src/stdlib/LinearAlgebra.md +++ b/src/stdlib/LinearAlgebra.md @@ -287,20 +287,24 @@ The following table summarizes the types of matrix factorizations that have been Julia. Details of their associated methods can be found in the [Standard Functions](@ref) section of the Linear Algebra documentation. -| Type | Description | -|:----------------- |:-------------------------------------------------------------------------------------------------------------- | -| `Cholesky` | [Cholesky factorization](https://en.wikipedia.org/wiki/Cholesky_decomposition) | -| `CholeskyPivoted` | [Pivoted](https://en.wikipedia.org/wiki/Pivot_element) Cholesky factorization | -| `LU` | [LU factorization](https://en.wikipedia.org/wiki/LU_decomposition) | -| `LUTridiagonal` | LU factorization for [`Tridiagonal`](@ref) matrices | -| `QR` | [QR factorization](https://en.wikipedia.org/wiki/QR_decomposition) | -| `QRCompactWY` | Compact WY form of the QR factorization | -| `QRPivoted` | Pivoted [QR factorization](https://en.wikipedia.org/wiki/QR_decomposition) | -| `Hessenberg` | [Hessenberg decomposition](http://mathworld.wolfram.com/HessenbergDecomposition.html) | -| `Eigen` | [Spectral decomposition](https://en.wikipedia.org/wiki/Eigendecomposition_(matrix)) | -| `SVD` | [Singular value decomposition](https://en.wikipedia.org/wiki/Singular_value_decomposition) | -| `GeneralizedSVD` | [Generalized SVD](https://en.wikipedia.org/wiki/Generalized_singular_value_decomposition#Higher_order_version) | - +| Type | Description | +|:------------------ |:-------------------------------------------------------------------------------------------------------------- | +| `BunchKaufman` | Bunch-Kaufman factorization | +| `Cholesky` | [Cholesky factorization](https://en.wikipedia.org/wiki/Cholesky_decomposition) | +| `CholeskyPivoted` | [Pivoted](https://en.wikipedia.org/wiki/Pivot_element) Cholesky factorization | +| `LDLt` | [LDL(T) factorization](https://en.wikipedia.org/wiki/Cholesky_decomposition#LDL_decomposition) | +| `LU` | [LU factorization](https://en.wikipedia.org/wiki/LU_decomposition) | +| `QR` | [QR factorization](https://en.wikipedia.org/wiki/QR_decomposition) | +| `QRCompactWY` | Compact WY form of the QR factorization | +| `QRPivoted` | Pivoted [QR factorization](https://en.wikipedia.org/wiki/QR_decomposition) | +| `LQ` | [QR factorization](https://en.wikipedia.org/wiki/QR_decomposition) of `transpose(A)` | +| `Hessenberg` | [Hessenberg decomposition](http://mathworld.wolfram.com/HessenbergDecomposition.html) | +| `Eigen` | [Spectral decomposition](https://en.wikipedia.org/wiki/Eigendecomposition_of_a_matrix) | +| `GeneralizedEigen` | [Generalized spectral decomposition](https://en.wikipedia.org/wiki/Eigendecomposition_of_a_matrix#Generalized_eigenvalue_problem) | +| `SVD` | [Singular value decomposition](https://en.wikipedia.org/wiki/Singular_value_decomposition) | +| `GeneralizedSVD` | [Generalized SVD](https://en.wikipedia.org/wiki/Generalized_singular_value_decomposition#Higher_order_version) | +| `Schur` | [Schur decomposition](https://en.wikipedia.org/wiki/Schur_decomposition) | +| `GeneralizedSchur` | [Generalized Schur decomposition](https://en.wikipedia.org/wiki/Schur_decomposition#Generalized_Schur_decomposition) | @@ -329,25 +333,34 @@ LinearAlgebra.UnitLowerTriangular LinearAlgebra.UnitUpperTriangular LinearAlgebra.UpperHessenberg LinearAlgebra.UniformScaling +LinearAlgebra.Factorization +LinearAlgebra.LU LinearAlgebra.lu LinearAlgebra.lu! +LinearAlgebra.Cholesky +LinearAlgebra.CholeskyPivoted LinearAlgebra.cholesky LinearAlgebra.cholesky! LinearAlgebra.lowrankupdate LinearAlgebra.lowrankdowndate LinearAlgebra.lowrankupdate! LinearAlgebra.lowrankdowndate! +LinearAlgebra.LDLt LinearAlgebra.ldlt LinearAlgebra.ldlt! -LinearAlgebra.qr -LinearAlgebra.qr! LinearAlgebra.QR LinearAlgebra.QRCompactWY LinearAlgebra.QRPivoted -LinearAlgebra.lq! +LinearAlgebra.qr +LinearAlgebra.qr! +LinearAlgebra.LQ LinearAlgebra.lq +LinearAlgebra.lq! +LinearAlgebra.BunchKaufman LinearAlgebra.bunchkaufman LinearAlgebra.bunchkaufman! +LinearAlgebra.Eigen +LinearAlgebra.GeneralizedEigen LinearAlgebra.eigvals LinearAlgebra.eigvals! LinearAlgebra.eigmax @@ -355,12 +368,17 @@ LinearAlgebra.eigmin LinearAlgebra.eigvecs LinearAlgebra.eigen LinearAlgebra.eigen! +LinearAlgebra.Hessenberg LinearAlgebra.hessenberg LinearAlgebra.hessenberg! -LinearAlgebra.schur! +LinearAlgebra.Schur +LinearAlgebra.GeneralizedSchur LinearAlgebra.schur +LinearAlgebra.schur! LinearAlgebra.ordschur LinearAlgebra.ordschur! +LinearAlgebra.SVD +LinearAlgebra.GeneralizedSVD LinearAlgebra.svd LinearAlgebra.svd! LinearAlgebra.svdvals diff --git a/src/stdlib/Random.md b/src/stdlib/Random.md index 6f23ea2..35ff059 100644 --- a/src/stdlib/Random.md +++ b/src/stdlib/Random.md @@ -248,6 +248,13 @@ Here, `sp.data` refers to the second parameter in the call to the `SamplerSimple (in this case equal to `Sampler(rng, 1:die.nsides, r)`), while the `Die` object can be accessed via `sp[]`. +Like `SamplerDie`, any custom sampler must be a subtype of `Sampler{T}` where `T` is the type +of the generated values. Note that `SamplerSimple(x, data) isa Sampler{eltype(x)}`, +so this constrains what the first argument to `SamplerSimple` can be +(it's recommended to use `SamplerSimple` like in the `Die` example, where +`x` is simply forwarded while defining a `Sampler` method). +Similarly, `SamplerTrivial(x) isa Sampler{eltype(x)}`. + Another helper type is currently available for other cases, `Random.SamplerTag`, but is considered as internal API, and can break at any time without proper deprecations. diff --git a/src/stdlib/Sockets.md b/src/stdlib/Sockets.md index f993e83..90acd10 100644 --- a/src/stdlib/Sockets.md +++ b/src/stdlib/Sockets.md @@ -30,6 +30,8 @@ Sockets.send Sockets.recv Sockets.recvfrom Sockets.setopt +Sockets.nagle +Sockets.quickack ``` ```@meta From ba3546a631678a099fc5289170d0f31109f3b497 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Wed, 26 Jun 2019 01:46:02 +0900 Subject: [PATCH 119/153] update Julia 1.3.0-DEV.438 (2019-06-24) Commit cef655a68a --- codex/NEWS.md | 2 ++ codex/devdocs/locks.md | 32 +++++++++++------- codex/manual/faq.md | 54 +++++++++++++++++++++--------- codex/manual/methods.md | 4 +-- codex/manual/parallel-computing.md | 34 +++++++++---------- codex/manual/profile.md | 3 +- codex/stdlib/Distributed.md | 6 ++-- codex/stdlib/Future.md | 17 ++++++++++ src/NEWS.md | 2 ++ src/devdocs/locks.md | 32 +++++++++++------- src/manual/faq.md | 54 +++++++++++++++++++++--------- src/manual/methods.md | 1 - src/manual/parallel-computing.md | 34 +++++++++---------- src/manual/profile.md | 3 +- src/stdlib/Distributed.md | 6 ++-- src/stdlib/Future.md | 17 ++++++++++ 16 files changed, 195 insertions(+), 106 deletions(-) create mode 100644 codex/stdlib/Future.md create mode 100644 src/stdlib/Future.md diff --git a/codex/NEWS.md b/codex/NEWS.md index 9ef4808..d96ce7a 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -5,6 +5,7 @@ New language features --------------------- * Support for Unicode 12.1.0 ([#32002](https://github.com/JuliaLang/julia/issues/32002)). +* Methods can now be added to an abstract type ([#31916](https://github.com/JuliaLang/julia/issues/31916)). Language changes ---------------- @@ -50,6 +51,7 @@ Standard library changes #### Dates +* `DateTime` and `Time` formatting/parsing now supports 12-hour clocks with AM/PM via `I` and `p` codes, similar to `strftime` ([#32308](https://github.com/JuliaLang/julia/issues/32308)). * Fixed `repr` such that it displays `Time` as it would be entered in Julia ([#32103](https://github.com/JuliaLang/julia/issues/32103)). #### Sockets diff --git a/codex/devdocs/locks.md b/codex/devdocs/locks.md index 12dc8e4..912fe66 100644 --- a/codex/devdocs/locks.md +++ b/codex/devdocs/locks.md @@ -58,6 +58,17 @@ trying to acquire it: > > > > currently the lock is merged with the codegen lock, since they call each other recursively +The following lock synchronizes IO operation. Be aware that doing any I/O (for example, +printing warning messages or debug information) while holding any other lock listed above +may result in pernicious and hard-to-find deadlocks. BE VERY CAREFUL! + +> * iolock +> * Individual ThreadSynchronizers locks +> +> > this may continue to be held after releasing the iolock, or acquired without it, +> > but be very careful to never attempt to acquire the iolock while holding it + + The following is the root lock, meaning no other lock shall be held when trying to acquire it: > * toplevel @@ -95,37 +106,32 @@ Module serializer : toplevel lock JIT & type-inference : codegen lock -MethodInstance updates : codegen lock +MethodInstance/CodeInstance updates : Method->writelock, codegen lock -> * These fields are generally lazy initialized, using the test-and-test-and-set pattern. > * These are set at construction and immutable: -> > * specTypes > * sparam_vals > * def + > * These are set by `jl_type_infer` (while holding codegen lock): -> +> * cache > * rettype > * inferred -> * these can also be reset, see `jl_set_lambda_rettype` for that logic as it needs to keep `functionObjectsDecls` -> in sync + * valid ages + > * `inInference` flag: -> > * optimization to quickly avoid recurring into `jl_type_infer` while it is already running > * actual state (of setting `inferred`, then `fptr`) is protected by codegen lock -> * Function pointers (`jlcall_api` and `fptr`, `unspecialized_ducttape`): -> + +> * Function pointers: > * these transition once, from `NULL` to a value, while the codegen lock is held -> * Code-generator cache (the contents of `functionObjectsDecls`): > +> * Code-generator cache (the contents of `functionObjectsDecls`): > * these can transition multiple times, but only while the codegen lock is held > * it is valid to use old version of this, or block for new versions of this, so races are benign, > as long as the code is careful not to reference other data in the method instance (such as `rettype`) > and assume it is coordinated, unless also holding the codegen lock -> * `compile_traced` flag: > -> * unknown - LLVMContext : codegen lock Method : Method->writelock diff --git a/codex/manual/faq.md b/codex/manual/faq.md index 5a2cd50..1b86e18 100644 --- a/codex/manual/faq.md +++ b/codex/manual/faq.md @@ -1,5 +1,23 @@ # Frequently Asked Questions +## General + +### Is Julia named after someone or something? + +No. + +### Why don't you compile Matlab/Python/R/… code to Julia? + +Since many people are familiar with the syntax of other dynamic languages, and lots of code has already been written in those languages, it is natural to wonder why we didn't just plug a Matlab or Python front-end into a Julia back-end (or “transpile” code to Julia) in order to get all the performance benefits of Julia without requiring programmers to learn a new language. Simple, right? + +The basic issue is that there is *nothing special about Julia's compiler*: we use a commonplace compiler (LLVM) with no “secret sauce” that other language developers don't know about. Indeed, Julia's compiler is in many ways much simpler than those of other dynamic languages (e.g. PyPy or LuaJIT). Julia's performance advantage derives almost entirely from its front-end: its language semantics allow a [well-written Julia program](@ref man-performance-tips) to *give more opportunities to the compiler* to generate efficient code and memory layouts. If you tried to compile Matlab or Python code to Julia, our compiler would be limited by the semantics of Matlab or Python to producing code no better than that of existing compilers for those languages (and probably worse). The key role of semantics is also why several existing Python compilers (like Numba and Pythran) only attempt to optimize a small subset of the language (e.g. operations on Numpy arrays and scalars), and for this subset they are already doing at least as well as we could for the same semantics. The people working on those projects are incredibly smart and have accomplished amazing things, but retrofitting a compiler onto a language that was designed to be interpreted is a very difficult problem. + +Julia's advantage is that good performance is not limited to a small subset of “built-in” types and operations, and one can write high-level type-generic code that works on arbitrary user-defined types while remaining fast and memory-efficient. Types in languages like Python simply don't provide enough information to the compiler for similar capabilities, so as soon as you used those languages as a Julia front-end you would be stuck. + +For similar reasons, automated translation to Julia would also typically generate unreadable, slow, non-idiomatic code that would not be a good starting point for a native Julia port from another language. + +On the other hand, language *interoperability* is extremely useful: we want to exploit existing high-quality code in other languages from Julia (and vice versa)! The best way to enable this is not a transpiler, but rather via easy inter-language calling facilities. We have worked hard on this, from the built-in `ccall` intrinsic (to call C and Fortran libraries) to [JuliaInterop](https://github.com/JuliaInterop) packages that connect Julia to Python, Matlab, C++, and more. + ## Sessions and the REPL ### How do I delete an object in memory? @@ -859,26 +877,30 @@ Modifying OpenBLAS settings or compiling Julia with a different BLAS library, eg ## Julia Releases -### Do I want to use a release, beta, or nightly version of Julia? +### Do I want to use the Stable, LTS, or nightly version of Julia? -You may prefer the release version of Julia if you are looking for a stable code base. Releases -generally occur every 6 months, giving you a stable platform for writing code. +The Stable version of Julia is the latest released version of Julia, this is the version most people will want to run. +It has the latest features, including improved performance. +The Stable version of Julia is versioned according to [SemVer](https://semver.org/) as v1.x.y. +A new minor release of Julia corresponding to a new Stable version is made approximately every 4-5 months after a few weeks of testing as a release candidate. +Unlike the LTS version the a Stable version will not normally recieve bugfixes after another Stable version of Julia has been released. +However, upgrading to the next Stable release will always be possible as each release of Julia v1.x will continue to run code written for earlier versions. -You may prefer the beta version of Julia if you don't mind being slightly behind the latest bugfixes -and changes, but find the slightly faster rate of changes more appealing. Additionally, these -binaries are tested before they are published to ensure they are fully functional. +You may prefer the LTS (Long Term Support) version of Julia if you are looking for a very stable code base. +The current LTS version of Julia is versioned according to SemVer as v1.0.x; +this branch will continue to recieve bugfixes until a new LTS branch is chosen, at which point the v1.0.x series will no longer recieved regular bug fixes and all but the most conservative users will be advised to upgrade to the new LTS version series. +As a package developer, you may prefer to develop for the LTS version, to maximize the number of users who can use your package. +As per SemVer, code written for v1.0 will continue to work for all future LTS and Stable versions. +In general, even if targetting the LTS, one can develop and run code in the latest Stable version, to take advantage of the improved performance; so long as one avoids using new features (such as added library functions or new methods). -You may prefer the nightly version of Julia if you want to take advantage of the latest updates -to the language, and don't mind if the version available today occasionally doesn't actually work. +You may prefer the nightly version of Julia if you want to take advantage of the latest updates to the language, and don't mind if the version available today occasionally doesn't actually work. +As the name implies, releases to the nightly version are made roughly every night (depending on build infrastructure stability). +In general nightly released are fairly safe to use—your code will not catch on fire. +However, they may be occasional regressions and or issues that will not be found until more thorough pre-release testing. +You may wish to test against the nightly version to ensure that such regressions that affect your use case are caught before a release is made. -Finally, you may also consider building Julia from source for yourself. This option is mainly -for those individuals who are comfortable at the command line, or interested in learning. If this -describes you, you may also be interested in reading our [guidelines for contributing](https://github.com/JuliaLang/julia/blob/master/CONTRIBUTING.md). +Finally, you may also consider building Julia from source for yourself. This option is mainly for those individuals who are comfortable at the command line, or interested in learning. +If this describes you, you may also be interested in reading our [guidelines for contributing](https://github.com/JuliaLang/julia/blob/master/CONTRIBUTING.md). Links to each of these download types can be found on the download page at [https://julialang.org/downloads/](https://julialang.org/downloads/). Note that not all versions of Julia are available for all platforms. - -### When are deprecated functions removed? - -Deprecated functions are removed after the subsequent release. For example, functions marked as -deprecated in the 0.1 release will not be available starting with the 0.2 release. diff --git a/codex/manual/methods.md b/codex/manual/methods.md index 07f0c99..c39c11b 100644 --- a/codex/manual/methods.md +++ b/codex/manual/methods.md @@ -981,9 +981,7 @@ f(x, y) = f(promote(x, y)...) One risk with this design is the possibility that if there is no suitable promotion method converting `x` and `y` to the same type, the second method will recurse on itself infinitely and trigger a stack -overflow. The non-exported function `Base.promote_noncircular` can be -used as an alternative; when promotion fails it will still throw an -error, but one that fails faster with a more specific error message. +overflow. ### Dispatch on one argument at a time diff --git a/codex/manual/parallel-computing.md b/codex/manual/parallel-computing.md index efa9077..04076b5 100644 --- a/codex/manual/parallel-computing.md +++ b/codex/manual/parallel-computing.md @@ -531,11 +531,11 @@ A remote reference is an object that can be used from any process to refer to an on a particular process. A remote call is a request by one process to call a certain function on certain arguments on another (possibly the same) process. -Remote references come in two flavors: [`Future`](@ref) and [`RemoteChannel`](@ref). +Remote references come in two flavors: [`Future`](@ref Distributed.Future) and [`RemoteChannel`](@ref). -A remote call returns a [`Future`](@ref) to its result. Remote calls return immediately; the process +A remote call returns a [`Future`](@ref Distributed.Future) to its result. Remote calls return immediately; the process that made the call proceeds to its next operation while the remote call happens somewhere else. -You can wait for a remote call to finish by calling [`wait`](@ref) on the returned [`Future`](@ref), +You can wait for a remote call to finish by calling [`wait`](@ref) on the returned [`Future`](@ref Distributed.Future), and you can obtain the full value of the result using [`fetch`](@ref). On the other hand, [`RemoteChannel`](@ref) s are rewritable. For example, multiple processes can @@ -615,8 +615,8 @@ on the process that owns `r`, so the [`fetch`](@ref) will be a no-op (no work is (It is worth noting that [`@spawn`](@ref) is not built-in but defined in Julia as a [macro](@ref man-macros). It is possible to define your own such constructs.) -An important thing to remember is that, once fetched, a [`Future`](@ref) will cache its value -locally. Further [`fetch`](@ref) calls do not entail a network hop. Once all referencing [`Future`](@ref)s +An important thing to remember is that, once fetched, a [`Future`](@ref Distributed.Future) will cache its value +locally. Further [`fetch`](@ref) calls do not entail a network hop. Once all referencing [`Future`](@ref Distributed.Future)s have fetched, the remote stored value is deleted. [`@async`](@ref) is similar to [`@spawn`](@ref), but only runs tasks on the local process. We @@ -981,8 +981,8 @@ Here each iteration applies `f` to a randomly-chosen sample from a vector `a` sh As you could see, the reduction operator can be omitted if it is not needed. In that case, the loop executes asynchronously, i.e. it spawns independent tasks on all available workers and returns -an array of [`Future`](@ref) immediately without waiting for completion. The caller can wait for -the [`Future`](@ref) completions at a later point by calling [`fetch`](@ref) on them, or wait +an array of [`Future`](@ref Distributed.Future) immediately without waiting for completion. The caller can wait for +the [`Future`](@ref Distributed.Future) completions at a later point by calling [`fetch`](@ref) on them, or wait for completion at the end of the loop by prefixing it with [`@sync`](@ref), like `@sync @distributed for`. In some cases no reduction operator is needed, and we merely wish to apply a function to all integers @@ -1008,7 +1008,7 @@ Remote references always refer to an implementation of an `AbstractChannel`. A concrete implementation of an `AbstractChannel` (like `Channel`), is required to implement [`put!`](@ref), [`take!`](@ref), [`fetch`](@ref), [`isready`](@ref) and [`wait`](@ref). -The remote object referred to by a [`Future`](@ref) is stored in a `Channel{Any}(1)`, i.e., a +The remote object referred to by a [`Future`](@ref Distributed.Future) is stored in a `Channel{Any}(1)`, i.e., a `Channel` of size 1 capable of holding objects of `Any` type. [`RemoteChannel`](@ref), which is rewritable, can point to any type and size of channels, or any @@ -1111,9 +1111,9 @@ Objects referred to by remote references can be freed only when *all* held refer in the cluster are deleted. The node where the value is stored keeps track of which of the workers have a reference to it. -Every time a [`RemoteChannel`](@ref) or a (unfetched) [`Future`](@ref) is serialized to a worker, +Every time a [`RemoteChannel`](@ref) or a (unfetched) [`Future`](@ref Distributed.Future) is serialized to a worker, the node pointed to by the reference is notified. And every time a [`RemoteChannel`](@ref) or -a (unfetched) [`Future`](@ref) is garbage collected locally, the node owning the value is again +a (unfetched) [`Future`](@ref Distributed.Future) is garbage collected locally, the node owning the value is again notified. This is implemented in an internal cluster aware serializer. Remote references are only valid in the context of a running cluster. Serializing and deserializing references to and from regular `IO` objects is not supported. @@ -1122,12 +1122,12 @@ The notifications are done via sending of "tracking" messages--an "add reference a reference is serialized to a different process and a "delete reference" message when a reference is locally garbage collected. -Since [`Future`](@ref)s are write-once and cached locally, the act of [`fetch`](@ref)ing a -[`Future`](@ref) also updates reference tracking information on the node owning the value. +Since [`Future`](@ref Distributed.Future)s are write-once and cached locally, the act of [`fetch`](@ref)ing a +[`Future`](@ref Distributed.Future) also updates reference tracking information on the node owning the value. The node which owns the value frees it once all references to it are cleared. -With [`Future`](@ref)s, serializing an already fetched [`Future`](@ref) to a different node also +With [`Future`](@ref Distributed.Future)s, serializing an already fetched [`Future`](@ref Distributed.Future) to a different node also sends the value since the original remote store may have collected the value by this time. It is important to note that *when* an object is locally garbage collected depends on the size @@ -1136,9 +1136,9 @@ of the object and the current memory pressure in the system. In case of remote references, the size of the local reference object is quite small, while the value stored on the remote node may be quite large. Since the local object may not be collected immediately, it is a good practice to explicitly call [`finalize`](@ref) on local instances -of a [`RemoteChannel`](@ref), or on unfetched [`Future`](@ref)s. Since calling [`fetch`](@ref) -on a [`Future`](@ref) also removes its reference from the remote store, this is not required on -fetched [`Future`](@ref)s. Explicitly calling [`finalize`](@ref) results in an immediate message +of a [`RemoteChannel`](@ref), or on unfetched [`Future`](@ref Distributed.Future)s. Since calling [`fetch`](@ref) +on a [`Future`](@ref Distributed.Future) also removes its reference from the remote store, this is not required on +fetched [`Future`](@ref Distributed.Future)s. Explicitly calling [`finalize`](@ref) results in an immediate message sent to the remote node to go ahead and remove its reference to the value. Once finalized, a reference becomes invalid and cannot be used in any further calls. @@ -1147,7 +1147,7 @@ Once finalized, a reference becomes invalid and cannot be used in any further ca ## Local invocations(@id man-distributed-local-invocations) Data is necessarily copied over to the remote node for execution. This is the case for both -remotecalls and when data is stored to a[`RemoteChannel`](@ref) / [`Future`](@ref) on +remotecalls and when data is stored to a[`RemoteChannel`](@ref) / [`Future`](@ref Distributed.Future) on a different node. As expected, this results in a copy of the serialized objects on the remote node. However, when the destination node is the local node, i.e. the calling process id is the same as the remote node id, it is executed diff --git a/codex/manual/profile.md b/codex/manual/profile.md index a4e26ff..0e5acc1 100644 --- a/codex/manual/profile.md +++ b/codex/manual/profile.md @@ -23,8 +23,7 @@ is subject to statistical noise. Despite these limitations, sampling profilers have substantial strengths: - * You do not have to make any modifications to your code to take timing measurements (in contrast - to the alternative [instrumenting profiler](https://github.com/timholy/IProfile.jl)). + * You do not have to make any modifications to your code to take timing measurements. * It can profile into Julia's core code and even (optionally) into C and Fortran libraries. * By running "infrequently" there is very little performance overhead; while profiling, your code can run at nearly native speed. diff --git a/codex/stdlib/Distributed.md b/codex/stdlib/Distributed.md index bddc2a3..7b4efae 100644 --- a/codex/stdlib/Distributed.md +++ b/codex/stdlib/Distributed.md @@ -18,17 +18,17 @@ Distributed.pmap Distributed.RemoteException Distributed.Future Distributed.RemoteChannel -Distributed.fetch(::Future) +Distributed.fetch(::Distributed.Future) Distributed.fetch(::RemoteChannel) Distributed.remotecall(::Any, ::Integer, ::Any...) Distributed.remotecall_wait(::Any, ::Integer, ::Any...) Distributed.remotecall_fetch(::Any, ::Integer, ::Any...) Distributed.remote_do(::Any, ::Integer, ::Any...) Distributed.put!(::RemoteChannel, ::Any...) -Distributed.put!(::Future, ::Any) +Distributed.put!(::Distributed.Future, ::Any) Distributed.take!(::RemoteChannel, ::Any...) Distributed.isready(::RemoteChannel, ::Any...) -Distributed.isready(::Future) +Distributed.isready(::Distributed.Future) Distributed.AbstractWorkerPool Distributed.WorkerPool Distributed.CachingPool diff --git a/codex/stdlib/Future.md b/codex/stdlib/Future.md new file mode 100644 index 0000000..8e2ce67 --- /dev/null +++ b/codex/stdlib/Future.md @@ -0,0 +1,17 @@ +# Future + +The `Future` module implements future behavior of already existing functions, +which will replace the current version in a future release of Julia. + +```@meta +DocTestSetup = :(using Future) +``` + +```@docs +Future.copy! +Future.randjump +``` + +```@meta +DocTestSetup = nothing +``` diff --git a/src/NEWS.md b/src/NEWS.md index 9ef4808..d96ce7a 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -5,6 +5,7 @@ New language features --------------------- * Support for Unicode 12.1.0 ([#32002](https://github.com/JuliaLang/julia/issues/32002)). +* Methods can now be added to an abstract type ([#31916](https://github.com/JuliaLang/julia/issues/31916)). Language changes ---------------- @@ -50,6 +51,7 @@ Standard library changes #### Dates +* `DateTime` and `Time` formatting/parsing now supports 12-hour clocks with AM/PM via `I` and `p` codes, similar to `strftime` ([#32308](https://github.com/JuliaLang/julia/issues/32308)). * Fixed `repr` such that it displays `Time` as it would be entered in Julia ([#32103](https://github.com/JuliaLang/julia/issues/32103)). #### Sockets diff --git a/src/devdocs/locks.md b/src/devdocs/locks.md index 12dc8e4..912fe66 100644 --- a/src/devdocs/locks.md +++ b/src/devdocs/locks.md @@ -58,6 +58,17 @@ trying to acquire it: > > > > currently the lock is merged with the codegen lock, since they call each other recursively +The following lock synchronizes IO operation. Be aware that doing any I/O (for example, +printing warning messages or debug information) while holding any other lock listed above +may result in pernicious and hard-to-find deadlocks. BE VERY CAREFUL! + +> * iolock +> * Individual ThreadSynchronizers locks +> +> > this may continue to be held after releasing the iolock, or acquired without it, +> > but be very careful to never attempt to acquire the iolock while holding it + + The following is the root lock, meaning no other lock shall be held when trying to acquire it: > * toplevel @@ -95,37 +106,32 @@ Module serializer : toplevel lock JIT & type-inference : codegen lock -MethodInstance updates : codegen lock +MethodInstance/CodeInstance updates : Method->writelock, codegen lock -> * These fields are generally lazy initialized, using the test-and-test-and-set pattern. > * These are set at construction and immutable: -> > * specTypes > * sparam_vals > * def + > * These are set by `jl_type_infer` (while holding codegen lock): -> +> * cache > * rettype > * inferred -> * these can also be reset, see `jl_set_lambda_rettype` for that logic as it needs to keep `functionObjectsDecls` -> in sync + * valid ages + > * `inInference` flag: -> > * optimization to quickly avoid recurring into `jl_type_infer` while it is already running > * actual state (of setting `inferred`, then `fptr`) is protected by codegen lock -> * Function pointers (`jlcall_api` and `fptr`, `unspecialized_ducttape`): -> + +> * Function pointers: > * these transition once, from `NULL` to a value, while the codegen lock is held -> * Code-generator cache (the contents of `functionObjectsDecls`): > +> * Code-generator cache (the contents of `functionObjectsDecls`): > * these can transition multiple times, but only while the codegen lock is held > * it is valid to use old version of this, or block for new versions of this, so races are benign, > as long as the code is careful not to reference other data in the method instance (such as `rettype`) > and assume it is coordinated, unless also holding the codegen lock -> * `compile_traced` flag: > -> * unknown - LLVMContext : codegen lock Method : Method->writelock diff --git a/src/manual/faq.md b/src/manual/faq.md index 5a2cd50..1b86e18 100644 --- a/src/manual/faq.md +++ b/src/manual/faq.md @@ -1,5 +1,23 @@ # Frequently Asked Questions +## General + +### Is Julia named after someone or something? + +No. + +### Why don't you compile Matlab/Python/R/… code to Julia? + +Since many people are familiar with the syntax of other dynamic languages, and lots of code has already been written in those languages, it is natural to wonder why we didn't just plug a Matlab or Python front-end into a Julia back-end (or “transpile” code to Julia) in order to get all the performance benefits of Julia without requiring programmers to learn a new language. Simple, right? + +The basic issue is that there is *nothing special about Julia's compiler*: we use a commonplace compiler (LLVM) with no “secret sauce” that other language developers don't know about. Indeed, Julia's compiler is in many ways much simpler than those of other dynamic languages (e.g. PyPy or LuaJIT). Julia's performance advantage derives almost entirely from its front-end: its language semantics allow a [well-written Julia program](@ref man-performance-tips) to *give more opportunities to the compiler* to generate efficient code and memory layouts. If you tried to compile Matlab or Python code to Julia, our compiler would be limited by the semantics of Matlab or Python to producing code no better than that of existing compilers for those languages (and probably worse). The key role of semantics is also why several existing Python compilers (like Numba and Pythran) only attempt to optimize a small subset of the language (e.g. operations on Numpy arrays and scalars), and for this subset they are already doing at least as well as we could for the same semantics. The people working on those projects are incredibly smart and have accomplished amazing things, but retrofitting a compiler onto a language that was designed to be interpreted is a very difficult problem. + +Julia's advantage is that good performance is not limited to a small subset of “built-in” types and operations, and one can write high-level type-generic code that works on arbitrary user-defined types while remaining fast and memory-efficient. Types in languages like Python simply don't provide enough information to the compiler for similar capabilities, so as soon as you used those languages as a Julia front-end you would be stuck. + +For similar reasons, automated translation to Julia would also typically generate unreadable, slow, non-idiomatic code that would not be a good starting point for a native Julia port from another language. + +On the other hand, language *interoperability* is extremely useful: we want to exploit existing high-quality code in other languages from Julia (and vice versa)! The best way to enable this is not a transpiler, but rather via easy inter-language calling facilities. We have worked hard on this, from the built-in `ccall` intrinsic (to call C and Fortran libraries) to [JuliaInterop](https://github.com/JuliaInterop) packages that connect Julia to Python, Matlab, C++, and more. + ## Sessions and the REPL ### How do I delete an object in memory? @@ -859,26 +877,30 @@ Modifying OpenBLAS settings or compiling Julia with a different BLAS library, eg ## Julia Releases -### Do I want to use a release, beta, or nightly version of Julia? +### Do I want to use the Stable, LTS, or nightly version of Julia? -You may prefer the release version of Julia if you are looking for a stable code base. Releases -generally occur every 6 months, giving you a stable platform for writing code. +The Stable version of Julia is the latest released version of Julia, this is the version most people will want to run. +It has the latest features, including improved performance. +The Stable version of Julia is versioned according to [SemVer](https://semver.org/) as v1.x.y. +A new minor release of Julia corresponding to a new Stable version is made approximately every 4-5 months after a few weeks of testing as a release candidate. +Unlike the LTS version the a Stable version will not normally recieve bugfixes after another Stable version of Julia has been released. +However, upgrading to the next Stable release will always be possible as each release of Julia v1.x will continue to run code written for earlier versions. -You may prefer the beta version of Julia if you don't mind being slightly behind the latest bugfixes -and changes, but find the slightly faster rate of changes more appealing. Additionally, these -binaries are tested before they are published to ensure they are fully functional. +You may prefer the LTS (Long Term Support) version of Julia if you are looking for a very stable code base. +The current LTS version of Julia is versioned according to SemVer as v1.0.x; +this branch will continue to recieve bugfixes until a new LTS branch is chosen, at which point the v1.0.x series will no longer recieved regular bug fixes and all but the most conservative users will be advised to upgrade to the new LTS version series. +As a package developer, you may prefer to develop for the LTS version, to maximize the number of users who can use your package. +As per SemVer, code written for v1.0 will continue to work for all future LTS and Stable versions. +In general, even if targetting the LTS, one can develop and run code in the latest Stable version, to take advantage of the improved performance; so long as one avoids using new features (such as added library functions or new methods). -You may prefer the nightly version of Julia if you want to take advantage of the latest updates -to the language, and don't mind if the version available today occasionally doesn't actually work. +You may prefer the nightly version of Julia if you want to take advantage of the latest updates to the language, and don't mind if the version available today occasionally doesn't actually work. +As the name implies, releases to the nightly version are made roughly every night (depending on build infrastructure stability). +In general nightly released are fairly safe to use—your code will not catch on fire. +However, they may be occasional regressions and or issues that will not be found until more thorough pre-release testing. +You may wish to test against the nightly version to ensure that such regressions that affect your use case are caught before a release is made. -Finally, you may also consider building Julia from source for yourself. This option is mainly -for those individuals who are comfortable at the command line, or interested in learning. If this -describes you, you may also be interested in reading our [guidelines for contributing](https://github.com/JuliaLang/julia/blob/master/CONTRIBUTING.md). +Finally, you may also consider building Julia from source for yourself. This option is mainly for those individuals who are comfortable at the command line, or interested in learning. +If this describes you, you may also be interested in reading our [guidelines for contributing](https://github.com/JuliaLang/julia/blob/master/CONTRIBUTING.md). Links to each of these download types can be found on the download page at [https://julialang.org/downloads/](https://julialang.org/downloads/). Note that not all versions of Julia are available for all platforms. - -### When are deprecated functions removed? - -Deprecated functions are removed after the subsequent release. For example, functions marked as -deprecated in the 0.1 release will not be available starting with the 0.2 release. diff --git a/src/manual/methods.md b/src/manual/methods.md index 5fa1494..8aa5b29 100644 --- a/src/manual/methods.md +++ b/src/manual/methods.md @@ -865,7 +865,6 @@ f(x, y) = f(promote(x, y)...) ``` 이 디자인의 한 가지 위험은 `x` 와 `y` 를 같은 유형으로 변환하는 적절한 프로모션 방법이 없으면 두 번째 방법이 무한히 반복되어 스택 오버플로가 트리거 될 수 있다는 것입니다. -exported 안 된 함수 `Base.promote_noncircular` 는 대안으로 사용할 수 있습니다. 프로모션이 실패하면 여전히 오류가 발생하지만 더 구체적인 오류 메시지로 인해 더 빨리 오류가 발생합니다. ### 한 번에 하나의 인수로 디스패치 diff --git a/src/manual/parallel-computing.md b/src/manual/parallel-computing.md index efa9077..04076b5 100644 --- a/src/manual/parallel-computing.md +++ b/src/manual/parallel-computing.md @@ -531,11 +531,11 @@ A remote reference is an object that can be used from any process to refer to an on a particular process. A remote call is a request by one process to call a certain function on certain arguments on another (possibly the same) process. -Remote references come in two flavors: [`Future`](@ref) and [`RemoteChannel`](@ref). +Remote references come in two flavors: [`Future`](@ref Distributed.Future) and [`RemoteChannel`](@ref). -A remote call returns a [`Future`](@ref) to its result. Remote calls return immediately; the process +A remote call returns a [`Future`](@ref Distributed.Future) to its result. Remote calls return immediately; the process that made the call proceeds to its next operation while the remote call happens somewhere else. -You can wait for a remote call to finish by calling [`wait`](@ref) on the returned [`Future`](@ref), +You can wait for a remote call to finish by calling [`wait`](@ref) on the returned [`Future`](@ref Distributed.Future), and you can obtain the full value of the result using [`fetch`](@ref). On the other hand, [`RemoteChannel`](@ref) s are rewritable. For example, multiple processes can @@ -615,8 +615,8 @@ on the process that owns `r`, so the [`fetch`](@ref) will be a no-op (no work is (It is worth noting that [`@spawn`](@ref) is not built-in but defined in Julia as a [macro](@ref man-macros). It is possible to define your own such constructs.) -An important thing to remember is that, once fetched, a [`Future`](@ref) will cache its value -locally. Further [`fetch`](@ref) calls do not entail a network hop. Once all referencing [`Future`](@ref)s +An important thing to remember is that, once fetched, a [`Future`](@ref Distributed.Future) will cache its value +locally. Further [`fetch`](@ref) calls do not entail a network hop. Once all referencing [`Future`](@ref Distributed.Future)s have fetched, the remote stored value is deleted. [`@async`](@ref) is similar to [`@spawn`](@ref), but only runs tasks on the local process. We @@ -981,8 +981,8 @@ Here each iteration applies `f` to a randomly-chosen sample from a vector `a` sh As you could see, the reduction operator can be omitted if it is not needed. In that case, the loop executes asynchronously, i.e. it spawns independent tasks on all available workers and returns -an array of [`Future`](@ref) immediately without waiting for completion. The caller can wait for -the [`Future`](@ref) completions at a later point by calling [`fetch`](@ref) on them, or wait +an array of [`Future`](@ref Distributed.Future) immediately without waiting for completion. The caller can wait for +the [`Future`](@ref Distributed.Future) completions at a later point by calling [`fetch`](@ref) on them, or wait for completion at the end of the loop by prefixing it with [`@sync`](@ref), like `@sync @distributed for`. In some cases no reduction operator is needed, and we merely wish to apply a function to all integers @@ -1008,7 +1008,7 @@ Remote references always refer to an implementation of an `AbstractChannel`. A concrete implementation of an `AbstractChannel` (like `Channel`), is required to implement [`put!`](@ref), [`take!`](@ref), [`fetch`](@ref), [`isready`](@ref) and [`wait`](@ref). -The remote object referred to by a [`Future`](@ref) is stored in a `Channel{Any}(1)`, i.e., a +The remote object referred to by a [`Future`](@ref Distributed.Future) is stored in a `Channel{Any}(1)`, i.e., a `Channel` of size 1 capable of holding objects of `Any` type. [`RemoteChannel`](@ref), which is rewritable, can point to any type and size of channels, or any @@ -1111,9 +1111,9 @@ Objects referred to by remote references can be freed only when *all* held refer in the cluster are deleted. The node where the value is stored keeps track of which of the workers have a reference to it. -Every time a [`RemoteChannel`](@ref) or a (unfetched) [`Future`](@ref) is serialized to a worker, +Every time a [`RemoteChannel`](@ref) or a (unfetched) [`Future`](@ref Distributed.Future) is serialized to a worker, the node pointed to by the reference is notified. And every time a [`RemoteChannel`](@ref) or -a (unfetched) [`Future`](@ref) is garbage collected locally, the node owning the value is again +a (unfetched) [`Future`](@ref Distributed.Future) is garbage collected locally, the node owning the value is again notified. This is implemented in an internal cluster aware serializer. Remote references are only valid in the context of a running cluster. Serializing and deserializing references to and from regular `IO` objects is not supported. @@ -1122,12 +1122,12 @@ The notifications are done via sending of "tracking" messages--an "add reference a reference is serialized to a different process and a "delete reference" message when a reference is locally garbage collected. -Since [`Future`](@ref)s are write-once and cached locally, the act of [`fetch`](@ref)ing a -[`Future`](@ref) also updates reference tracking information on the node owning the value. +Since [`Future`](@ref Distributed.Future)s are write-once and cached locally, the act of [`fetch`](@ref)ing a +[`Future`](@ref Distributed.Future) also updates reference tracking information on the node owning the value. The node which owns the value frees it once all references to it are cleared. -With [`Future`](@ref)s, serializing an already fetched [`Future`](@ref) to a different node also +With [`Future`](@ref Distributed.Future)s, serializing an already fetched [`Future`](@ref Distributed.Future) to a different node also sends the value since the original remote store may have collected the value by this time. It is important to note that *when* an object is locally garbage collected depends on the size @@ -1136,9 +1136,9 @@ of the object and the current memory pressure in the system. In case of remote references, the size of the local reference object is quite small, while the value stored on the remote node may be quite large. Since the local object may not be collected immediately, it is a good practice to explicitly call [`finalize`](@ref) on local instances -of a [`RemoteChannel`](@ref), or on unfetched [`Future`](@ref)s. Since calling [`fetch`](@ref) -on a [`Future`](@ref) also removes its reference from the remote store, this is not required on -fetched [`Future`](@ref)s. Explicitly calling [`finalize`](@ref) results in an immediate message +of a [`RemoteChannel`](@ref), or on unfetched [`Future`](@ref Distributed.Future)s. Since calling [`fetch`](@ref) +on a [`Future`](@ref Distributed.Future) also removes its reference from the remote store, this is not required on +fetched [`Future`](@ref Distributed.Future)s. Explicitly calling [`finalize`](@ref) results in an immediate message sent to the remote node to go ahead and remove its reference to the value. Once finalized, a reference becomes invalid and cannot be used in any further calls. @@ -1147,7 +1147,7 @@ Once finalized, a reference becomes invalid and cannot be used in any further ca ## Local invocations(@id man-distributed-local-invocations) Data is necessarily copied over to the remote node for execution. This is the case for both -remotecalls and when data is stored to a[`RemoteChannel`](@ref) / [`Future`](@ref) on +remotecalls and when data is stored to a[`RemoteChannel`](@ref) / [`Future`](@ref Distributed.Future) on a different node. As expected, this results in a copy of the serialized objects on the remote node. However, when the destination node is the local node, i.e. the calling process id is the same as the remote node id, it is executed diff --git a/src/manual/profile.md b/src/manual/profile.md index a4e26ff..0e5acc1 100644 --- a/src/manual/profile.md +++ b/src/manual/profile.md @@ -23,8 +23,7 @@ is subject to statistical noise. Despite these limitations, sampling profilers have substantial strengths: - * You do not have to make any modifications to your code to take timing measurements (in contrast - to the alternative [instrumenting profiler](https://github.com/timholy/IProfile.jl)). + * You do not have to make any modifications to your code to take timing measurements. * It can profile into Julia's core code and even (optionally) into C and Fortran libraries. * By running "infrequently" there is very little performance overhead; while profiling, your code can run at nearly native speed. diff --git a/src/stdlib/Distributed.md b/src/stdlib/Distributed.md index bddc2a3..7b4efae 100644 --- a/src/stdlib/Distributed.md +++ b/src/stdlib/Distributed.md @@ -18,17 +18,17 @@ Distributed.pmap Distributed.RemoteException Distributed.Future Distributed.RemoteChannel -Distributed.fetch(::Future) +Distributed.fetch(::Distributed.Future) Distributed.fetch(::RemoteChannel) Distributed.remotecall(::Any, ::Integer, ::Any...) Distributed.remotecall_wait(::Any, ::Integer, ::Any...) Distributed.remotecall_fetch(::Any, ::Integer, ::Any...) Distributed.remote_do(::Any, ::Integer, ::Any...) Distributed.put!(::RemoteChannel, ::Any...) -Distributed.put!(::Future, ::Any) +Distributed.put!(::Distributed.Future, ::Any) Distributed.take!(::RemoteChannel, ::Any...) Distributed.isready(::RemoteChannel, ::Any...) -Distributed.isready(::Future) +Distributed.isready(::Distributed.Future) Distributed.AbstractWorkerPool Distributed.WorkerPool Distributed.CachingPool diff --git a/src/stdlib/Future.md b/src/stdlib/Future.md new file mode 100644 index 0000000..8e2ce67 --- /dev/null +++ b/src/stdlib/Future.md @@ -0,0 +1,17 @@ +# Future + +The `Future` module implements future behavior of already existing functions, +which will replace the current version in a future release of Julia. + +```@meta +DocTestSetup = :(using Future) +``` + +```@docs +Future.copy! +Future.randjump +``` + +```@meta +DocTestSetup = nothing +``` From c4c49fa42712e39b5177c03d8c16b80d4c959ada Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Thu, 4 Jul 2019 14:45:19 +0900 Subject: [PATCH 120/153] update Julia 1.3.0-DEV.507 (2019-07-03) Commit 61a0b04f91 --- codex/NEWS.md | 14 ++++++++++++++ codex/base/parallel.md | 1 + codex/base/strings.md | 2 ++ codex/devdocs/ssair.md | 2 +- codex/manual/constructors.md | 4 ++-- codex/manual/getting-started.md | 2 +- codex/manual/metaprogramming.md | 3 +++ codex/manual/methods.md | 2 +- codex/stdlib/LinearAlgebra.md | 2 ++ src/NEWS.md | 14 ++++++++++++++ src/base/parallel.md | 1 + src/base/strings.md | 2 ++ src/devdocs/ssair.md | 2 +- src/manual/constructors.md | 4 ++-- src/manual/getting-started.md | 2 +- src/manual/metaprogramming.md | 3 +++ src/manual/methods.md | 2 +- src/stdlib/LinearAlgebra.md | 2 ++ 18 files changed, 54 insertions(+), 10 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index d96ce7a..1fe0a69 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -33,6 +33,10 @@ Standard library changes * `Cmd` interpolation (`` `$(x::Cmd) a b c` `` where) now propagates `x`'s process flags (environment, flags, working directory, etc) if `x` is the first interpolant and errors otherwise ([#24353](https://github.com/JuliaLang/julia/issues/24353)). +* Zero-dimensional arrays are now consistently preserved in the return values of mathematical + functions that operate on the array(s) as a whole (and are not explicitly broadcasted across their elements). + Previously, the functions `+`, `-`, `*`, `/`, `conj`, `real` and `imag` returned the unwrapped element + when operating over zero-dimensional arrays ([#32122](https://github.com/JuliaLang/julia/issues/32122)). * `IPAddr` subtypes now behave like scalars when used in broadcasting ([#32133](https://github.com/JuliaLang/julia/issues/32133)). * `clamp` can now handle missing values ([#31066](https://github.com/JuliaLang/julia/issues/31066)). @@ -48,6 +52,11 @@ Standard library changes #### SparseArrays +* `SparseMatrixCSC(m,n,colptr,rowval,nzval)` perform consistency checks for arguments: + `colptr` must be properly populated and lengths of `colptr`, `rowval`, and `nzval` + must be compatible with `m`, `n`, and `eltype(colptr)`. +* `sparse(I, J, V, m, n)` verifies lengths of `I`, `J`, `V` are equal and compatible with + `eltype(I)` and `m`, `n`. #### Dates @@ -63,6 +72,11 @@ Standard library changes * `mean` now accepts both a function argument and a `dims` keyword ([#31576](https://github.com/JuliaLang/julia/issues/31576)). +#### Sockets + +* Added `InetAddr` constructor from `AbstractString`, representing IP address, and `Integer`, + representing port number ([#31459](https://github.com/JuliaLang/julia/issues/31459)). + #### Miscellaneous * `foldr` and `mapfoldr` now work on any iterator that supports `Iterators.reverse`, not just arrays ([#31781](https://github.com/JuliaLang/julia/issues/31781)). diff --git a/codex/base/parallel.md b/codex/base/parallel.md index 6b299eb..362e6bc 100644 --- a/codex/base/parallel.md +++ b/codex/base/parallel.md @@ -44,6 +44,7 @@ Base.islocked Base.ReentrantLock Base.Channel +Base.Channel(::Function) Base.put!(::Channel, ::Any) Base.take!(::Channel) Base.isready(::Channel) diff --git a/codex/base/strings.md b/codex/base/strings.md index f7bfc66..12da6d9 100644 --- a/codex/base/strings.md +++ b/codex/base/strings.md @@ -39,7 +39,9 @@ Base.lpad Base.rpad Base.findfirst(::AbstractString, ::AbstractString) Base.findnext(::AbstractString, ::AbstractString, ::Integer) +Base.findnext(::AbstractChar, ::AbstractString, ::Integer) Base.findlast(::AbstractString, ::AbstractString) +Base.findlast(::AbstractChar, ::AbstractString) Base.findprev(::AbstractString, ::AbstractString, ::Integer) Base.occursin Base.reverse(::Union{String,SubString{String}}) diff --git a/codex/devdocs/ssair.md b/codex/devdocs/ssair.md index 96476d0..005db5a 100644 --- a/codex/devdocs/ssair.md +++ b/codex/devdocs/ssair.md @@ -88,7 +88,7 @@ catch: ``` However, this is problematic in a language like julia where at the start of the optimization -pipeline, we do not now which calls throw. We would have to conservatively assume that every +pipeline, we do not know which calls throw. We would have to conservatively assume that every call (which in julia is every statement) throws. This would have several negative effects. On the one hand, it would essentially recuce the scope of every basic block to a single call, defeating the purpose of having operations be performed at the basic block level. On the other diff --git a/codex/manual/constructors.md b/codex/manual/constructors.md index 6d64130..33f6d8f 100644 --- a/codex/manual/constructors.md +++ b/codex/manual/constructors.md @@ -294,7 +294,7 @@ Point{Float64}(1.0, 2.5) julia> Point(1,2.5) ## implicit T ## ERROR: MethodError: no method matching Point(::Int64, ::Float64) Closest candidates are: - Point(::T<:Real, ::T<:Real) where T<:Real at none:2 + Point(::T, ::T) where T<:Real at none:2 julia> Point{Int64}(1, 2) ## explicit T ## Point{Int64}(1, 2) @@ -373,7 +373,7 @@ However, other similar calls still don't work: julia> Point(1.5,2) ERROR: MethodError: no method matching Point(::Float64, ::Int64) Closest candidates are: - Point(::T<:Real, !Matched::T<:Real) where T<:Real at none:1 + Point(::T, !Matched::T) where T<:Real at none:1 ``` For a more general way to make all such calls work sensibly, see [Conversion and Promotion](@ref conversion-and-promotion). diff --git a/codex/manual/getting-started.md b/codex/manual/getting-started.md index f6fa622..c583f14 100644 --- a/codex/manual/getting-started.md +++ b/codex/manual/getting-started.md @@ -94,7 +94,7 @@ julia [switches] -- [programfile] [args...] |Switch |Description| |:--- |:---| |`-v`, `--version` |Display version information| -|`-h`, `--help` |Print this message| +|`-h`, `--help` |Print command-line options (this message).| |`--project[={\|@.}]` |Set as the home project/environment. The default @. option will search through parent directories until a Project.toml or JuliaProject.toml file is found.| |`-J`, `--sysimage ` |Start up with the given system image file| |`-H`, `--home ` |Set location of `julia` executable| diff --git a/codex/manual/metaprogramming.md b/codex/manual/metaprogramming.md index 7faa0e5..f2a63fe 100644 --- a/codex/manual/metaprogramming.md +++ b/codex/manual/metaprogramming.md @@ -126,6 +126,9 @@ julia> Symbol(:var,'_',"sym") :var_sym ``` +Note that to use `:` syntax, the symbol's name must be a valid identifier. +Otherwise the `Symbol(str)` constructor must be used. + In the context of an expression, symbols are used to indicate access to variables; when an expression is evaluated, a symbol is replaced with the value bound to that symbol in the appropriate [scope](@ref scope-of-variables). diff --git a/codex/manual/methods.md b/codex/manual/methods.md index c39c11b..4fff31b 100644 --- a/codex/manual/methods.md +++ b/codex/manual/methods.md @@ -386,7 +386,7 @@ true julia> same_type_numeric("foo", 2.0) ERROR: MethodError: no method matching same_type_numeric(::String, ::Float64) Closest candidates are: - same_type_numeric(!Matched::T<:Number, ::T<:Number) where T<:Number at none:1 + same_type_numeric(!Matched::T, ::T) where T<:Number at none:1 same_type_numeric(!Matched::Number, ::Number) at none:1 julia> same_type_numeric("foo", "bar") diff --git a/codex/stdlib/LinearAlgebra.md b/codex/stdlib/LinearAlgebra.md index fbf69e8..df83cc8 100644 --- a/codex/stdlib/LinearAlgebra.md +++ b/codex/stdlib/LinearAlgebra.md @@ -520,12 +520,14 @@ the input argument belongs on (`side`). The possibilities are: ```@docs LinearAlgebra.BLAS +LinearAlgebra.BLAS.dot LinearAlgebra.BLAS.dotu LinearAlgebra.BLAS.dotc LinearAlgebra.BLAS.blascopy! LinearAlgebra.BLAS.nrm2 LinearAlgebra.BLAS.asum LinearAlgebra.axpy! +LinearAlgebra.axpby! LinearAlgebra.BLAS.scal! LinearAlgebra.BLAS.scal LinearAlgebra.BLAS.iamax diff --git a/src/NEWS.md b/src/NEWS.md index d96ce7a..1fe0a69 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -33,6 +33,10 @@ Standard library changes * `Cmd` interpolation (`` `$(x::Cmd) a b c` `` where) now propagates `x`'s process flags (environment, flags, working directory, etc) if `x` is the first interpolant and errors otherwise ([#24353](https://github.com/JuliaLang/julia/issues/24353)). +* Zero-dimensional arrays are now consistently preserved in the return values of mathematical + functions that operate on the array(s) as a whole (and are not explicitly broadcasted across their elements). + Previously, the functions `+`, `-`, `*`, `/`, `conj`, `real` and `imag` returned the unwrapped element + when operating over zero-dimensional arrays ([#32122](https://github.com/JuliaLang/julia/issues/32122)). * `IPAddr` subtypes now behave like scalars when used in broadcasting ([#32133](https://github.com/JuliaLang/julia/issues/32133)). * `clamp` can now handle missing values ([#31066](https://github.com/JuliaLang/julia/issues/31066)). @@ -48,6 +52,11 @@ Standard library changes #### SparseArrays +* `SparseMatrixCSC(m,n,colptr,rowval,nzval)` perform consistency checks for arguments: + `colptr` must be properly populated and lengths of `colptr`, `rowval`, and `nzval` + must be compatible with `m`, `n`, and `eltype(colptr)`. +* `sparse(I, J, V, m, n)` verifies lengths of `I`, `J`, `V` are equal and compatible with + `eltype(I)` and `m`, `n`. #### Dates @@ -63,6 +72,11 @@ Standard library changes * `mean` now accepts both a function argument and a `dims` keyword ([#31576](https://github.com/JuliaLang/julia/issues/31576)). +#### Sockets + +* Added `InetAddr` constructor from `AbstractString`, representing IP address, and `Integer`, + representing port number ([#31459](https://github.com/JuliaLang/julia/issues/31459)). + #### Miscellaneous * `foldr` and `mapfoldr` now work on any iterator that supports `Iterators.reverse`, not just arrays ([#31781](https://github.com/JuliaLang/julia/issues/31781)). diff --git a/src/base/parallel.md b/src/base/parallel.md index 6b299eb..362e6bc 100644 --- a/src/base/parallel.md +++ b/src/base/parallel.md @@ -44,6 +44,7 @@ Base.islocked Base.ReentrantLock Base.Channel +Base.Channel(::Function) Base.put!(::Channel, ::Any) Base.take!(::Channel) Base.isready(::Channel) diff --git a/src/base/strings.md b/src/base/strings.md index f7bfc66..12da6d9 100644 --- a/src/base/strings.md +++ b/src/base/strings.md @@ -39,7 +39,9 @@ Base.lpad Base.rpad Base.findfirst(::AbstractString, ::AbstractString) Base.findnext(::AbstractString, ::AbstractString, ::Integer) +Base.findnext(::AbstractChar, ::AbstractString, ::Integer) Base.findlast(::AbstractString, ::AbstractString) +Base.findlast(::AbstractChar, ::AbstractString) Base.findprev(::AbstractString, ::AbstractString, ::Integer) Base.occursin Base.reverse(::Union{String,SubString{String}}) diff --git a/src/devdocs/ssair.md b/src/devdocs/ssair.md index 96476d0..005db5a 100644 --- a/src/devdocs/ssair.md +++ b/src/devdocs/ssair.md @@ -88,7 +88,7 @@ catch: ``` However, this is problematic in a language like julia where at the start of the optimization -pipeline, we do not now which calls throw. We would have to conservatively assume that every +pipeline, we do not know which calls throw. We would have to conservatively assume that every call (which in julia is every statement) throws. This would have several negative effects. On the one hand, it would essentially recuce the scope of every basic block to a single call, defeating the purpose of having operations be performed at the basic block level. On the other diff --git a/src/manual/constructors.md b/src/manual/constructors.md index 6d64130..33f6d8f 100644 --- a/src/manual/constructors.md +++ b/src/manual/constructors.md @@ -294,7 +294,7 @@ Point{Float64}(1.0, 2.5) julia> Point(1,2.5) ## implicit T ## ERROR: MethodError: no method matching Point(::Int64, ::Float64) Closest candidates are: - Point(::T<:Real, ::T<:Real) where T<:Real at none:2 + Point(::T, ::T) where T<:Real at none:2 julia> Point{Int64}(1, 2) ## explicit T ## Point{Int64}(1, 2) @@ -373,7 +373,7 @@ However, other similar calls still don't work: julia> Point(1.5,2) ERROR: MethodError: no method matching Point(::Float64, ::Int64) Closest candidates are: - Point(::T<:Real, !Matched::T<:Real) where T<:Real at none:1 + Point(::T, !Matched::T) where T<:Real at none:1 ``` For a more general way to make all such calls work sensibly, see [Conversion and Promotion](@ref conversion-and-promotion). diff --git a/src/manual/getting-started.md b/src/manual/getting-started.md index c475917..042a03f 100644 --- a/src/manual/getting-started.md +++ b/src/manual/getting-started.md @@ -74,7 +74,7 @@ julia [switches] -- [programfile] [args...] |스위치 |설명| |:--- |:---| |`-v`, `--version` |버전 정보를 표시한다| -|`-h`, `--help` |이 메세지를 표시한다| +|`-h`, `--help` |command-line 옵션(이 메세지)을 표시한다| |`--project[={\|@.}]` |Set as the home project/environment. The default @. option will search through parent directories until a Project.toml or JuliaProject.toml file is found.| |`-J`, `--sysimage ` |주어진 시스템 이미지 파일로 실행한다| |`-H`, `--home ` |`julia` 실행파일의 위치를 지정한다| diff --git a/src/manual/metaprogramming.md b/src/manual/metaprogramming.md index 7faa0e5..f2a63fe 100644 --- a/src/manual/metaprogramming.md +++ b/src/manual/metaprogramming.md @@ -126,6 +126,9 @@ julia> Symbol(:var,'_',"sym") :var_sym ``` +Note that to use `:` syntax, the symbol's name must be a valid identifier. +Otherwise the `Symbol(str)` constructor must be used. + In the context of an expression, symbols are used to indicate access to variables; when an expression is evaluated, a symbol is replaced with the value bound to that symbol in the appropriate [scope](@ref scope-of-variables). diff --git a/src/manual/methods.md b/src/manual/methods.md index 8aa5b29..35e20ce 100644 --- a/src/manual/methods.md +++ b/src/manual/methods.md @@ -345,7 +345,7 @@ true julia> same_type_numeric("foo", 2.0) ERROR: MethodError: no method matching same_type_numeric(::String, ::Float64) Closest candidates are: - same_type_numeric(!Matched::T<:Number, ::T<:Number) where T<:Number at none:1 + same_type_numeric(!Matched::T, ::T) where T<:Number at none:1 same_type_numeric(!Matched::Number, ::Number) at none:1 julia> same_type_numeric("foo", "bar") diff --git a/src/stdlib/LinearAlgebra.md b/src/stdlib/LinearAlgebra.md index fbf69e8..df83cc8 100644 --- a/src/stdlib/LinearAlgebra.md +++ b/src/stdlib/LinearAlgebra.md @@ -520,12 +520,14 @@ the input argument belongs on (`side`). The possibilities are: ```@docs LinearAlgebra.BLAS +LinearAlgebra.BLAS.dot LinearAlgebra.BLAS.dotu LinearAlgebra.BLAS.dotc LinearAlgebra.BLAS.blascopy! LinearAlgebra.BLAS.nrm2 LinearAlgebra.BLAS.asum LinearAlgebra.axpy! +LinearAlgebra.axpby! LinearAlgebra.BLAS.scal! LinearAlgebra.BLAS.scal LinearAlgebra.BLAS.iamax From b332b39a780179d583c2c9243ef95f164eb800aa Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Sun, 28 Jul 2019 01:23:20 +0900 Subject: [PATCH 121/153] update Julia 1.3.0-alpha.24 (2019-07-27) Commit 89b80571a7 --- codex/NEWS.md | 18 ++++++++++++++- codex/base/multi-threading.md | 1 + codex/base/parallel.md | 1 + codex/devdocs/ast.md | 2 +- codex/devdocs/cartesian.md | 12 +++++----- codex/devdocs/gc-sa.md | 2 +- codex/devdocs/locks.md | 6 +++++ codex/manual/documentation.md | 24 +++++++++++++------ codex/manual/modules.md | 4 ++-- codex/manual/parallel-computing.md | 37 +++++++++++++++--------------- codex/stdlib/Distributed.md | 1 - src/NEWS.md | 18 ++++++++++++++- src/base/multi-threading.md | 1 + src/base/parallel.md | 1 + src/devdocs/ast.md | 2 +- src/devdocs/cartesian.md | 12 +++++----- src/devdocs/gc-sa.md | 2 +- src/devdocs/locks.md | 6 +++++ src/manual/documentation.md | 24 +++++++++++++------ src/manual/modules.md | 4 ++-- src/manual/parallel-computing.md | 37 +++++++++++++++--------------- src/stdlib/Distributed.md | 1 - 22 files changed, 140 insertions(+), 76 deletions(-) diff --git a/codex/NEWS.md b/codex/NEWS.md index 1fe0a69..f542849 100644 --- a/codex/NEWS.md +++ b/codex/NEWS.md @@ -14,6 +14,12 @@ Language changes Multi-threading changes ----------------------- +* All system-level I/O operations (e.g. files and sockets) are now thread-safe. + This does not include subtypes of `IO` that are entirely in-memory, such as `IOBuffer`, + although it specifically does include `BufferStream`. + ([#32309](https://github.com/JuliaLang/julia/issues/32309), [#32174](https://github.com/JuliaLang/julia/issues/32174), [#31981](https://github.com/JuliaLang/julia/issues/31981), [#32421](https://github.com/JuliaLang/julia/issues/32421)). +* The global random number generator (`GLOBAL_RNG`) is now thread-safe (and thread-local) ([#32407](https://github.com/JuliaLang/julia/issues/32407)). +* New experimental `Threads.@spawn` macro that runs a task on any available thread ([#32600](https://github.com/JuliaLang/julia/issues/32600)). Build system changes -------------------- @@ -25,12 +31,14 @@ New library functions * `findfirst`, `findlast`, `findnext` and `findprev` now accept a character as first argument to search for that character in a string passed as the second argument ([#31664](https://github.com/JuliaLang/julia/issues/31664)). * New `findall(pattern, string)` method where `pattern` is a string or regex ([#31834](https://github.com/JuliaLang/julia/issues/31834)). +* `istaskfailed` is now documented and exported, like its siblings `istaskdone` and `istaskstarted` ([#32300](https://github.com/JuliaLang/julia/issues/32300)). +* `RefArray` and `RefValue` objects now accept index `CartesianIndex()` in `getindex` and `setindex!` ([#32653](https://github.com/JuliaLang/julia/issues/32653)) Standard library changes ------------------------ * `Regex` can now be multiplied (`*`) and exponentiated (`^`), like strings ([#23422](https://github.com/JuliaLang/julia/issues/23422)). -* `Cmd` interpolation (`` `$(x::Cmd) a b c` `` where) now propagates `x`'s process flags +* `Cmd` interpolation (``` `$(x::Cmd) a b c` ``` where) now propagates `x`'s process flags (environment, flags, working directory, etc) if `x` is the first interpolant and errors otherwise ([#24353](https://github.com/JuliaLang/julia/issues/24353)). * Zero-dimensional arrays are now consistently preserved in the return values of mathematical @@ -39,6 +47,8 @@ Standard library changes when operating over zero-dimensional arrays ([#32122](https://github.com/JuliaLang/julia/issues/32122)). * `IPAddr` subtypes now behave like scalars when used in broadcasting ([#32133](https://github.com/JuliaLang/julia/issues/32133)). * `clamp` can now handle missing values ([#31066](https://github.com/JuliaLang/julia/issues/31066)). +* `empty` now accepts a `NamedTuple` ([#32534](https://github.com/JuliaLang/julia/issues/32534)). +* `mod` now accepts a unit range as the second argument to easily perform offset modular arithmetic to ensure the result is inside the range ([#32628](https://github.com/JuliaLang/julia/issues/32628)). #### Libdl @@ -57,6 +67,7 @@ Standard library changes must be compatible with `m`, `n`, and `eltype(colptr)`. * `sparse(I, J, V, m, n)` verifies lengths of `I`, `J`, `V` are equal and compatible with `eltype(I)` and `m`, `n`. +* The `sprand` function is now 2 to 5 times faster ([#30494](https://github.com/JuliaLang/julia/issues/30494)). As a consequence of this change, the random stream of matrices produced with `sprand` and `sprandn` has changed. #### Dates @@ -81,6 +92,11 @@ Standard library changes * `foldr` and `mapfoldr` now work on any iterator that supports `Iterators.reverse`, not just arrays ([#31781](https://github.com/JuliaLang/julia/issues/31781)). +Deprecated or removed +--------------------- + +* `@spawn expr` from the `Distributed` standard library should be replaced with `@spawnat :any expr` ([#32600](https://github.com/JuliaLang/julia/issues/32600)). + External dependencies --------------------- diff --git a/codex/base/multi-threading.md b/codex/base/multi-threading.md index 1b58e61..3508bbc 100644 --- a/codex/base/multi-threading.md +++ b/codex/base/multi-threading.md @@ -7,6 +7,7 @@ described here might (and likely will) change in the future. Base.Threads.threadid Base.Threads.nthreads Base.Threads.@threads +Base.Threads.@spawn ``` ```@docs diff --git a/codex/base/parallel.md b/codex/base/parallel.md index 362e6bc..453cd45 100644 --- a/codex/base/parallel.md +++ b/codex/base/parallel.md @@ -11,6 +11,7 @@ Base.fetch(t::Task) Base.current_task Base.istaskdone Base.istaskstarted +Base.istaskfailed Base.task_local_storage(::Any) Base.task_local_storage(::Any, ::Any) Base.task_local_storage(::Function, ::Any, ::Any) diff --git a/codex/devdocs/ast.md b/codex/devdocs/ast.md index e234880..c5b23df 100644 --- a/codex/devdocs/ast.md +++ b/codex/devdocs/ast.md @@ -236,7 +236,7 @@ to interpolate code from the caller. ## Lowered form Lowered form (IR) is more important to the compiler, since it is used for type inference, -optimizations like inlining, and and code generation. It is also less obvious to the human, +optimizations like inlining, and code generation. It is also less obvious to the human, since it results from a significant rearrangement of the input syntax. In addition to `Symbol`s and some number types, the following data diff --git a/codex/devdocs/cartesian.md b/codex/devdocs/cartesian.md index 6e115ea..1d338cb 100644 --- a/codex/devdocs/cartesian.md +++ b/codex/devdocs/cartesian.md @@ -16,10 +16,10 @@ end which generates the following code: ```julia -for i_3 = 1:size(A,3) - for i_2 = 1:size(A,2) - for i_1 = 1:size(A,1) - s += A[i_1,i_2,i_3] +for i_3 = axes(A, 3) + for i_2 = axes(A, 2) + for i_1 = axes(A, 1) + s += A[i_1, i_2, i_3] end end end @@ -38,7 +38,7 @@ The (basic) syntax of `@nloops` is as follows: * The second argument is the symbol-prefix used for the iterator variable. Here we used `i`, and variables `i_1, i_2, i_3` were generated. * The third argument specifies the range for each iterator variable. If you use a variable (symbol) - here, it's taken as `1:size(A,dim)`. More flexibly, you can use the anonymous-function expression + here, it's taken as `axes(A, dim)`. More flexibly, you can use the anonymous-function expression syntax described below. * The last argument is the body of the loop. Here, that's what appears between the `begin...end`. @@ -46,7 +46,7 @@ There are some additional features of `@nloops` described in the [reference sect `@nref` follows a similar pattern, generating `A[i_1,i_2,i_3]` from `@nref 3 A i`. The general practice is to read from left to right, which is why `@nloops` is `@nloops 3 i A expr` (as in -`for i_2 = 1:size(A,2)`, where `i_2` is to the left and the range is to the right) whereas `@nref` +`for i_2 = axes(A, 2)`, where `i_2` is to the left and the range is to the right) whereas `@nref` is `@nref 3 A i` (as in `A[i_1,i_2,i_3]`, where the array comes first). If you're developing code with Cartesian, you may find that debugging is easier when you examine diff --git a/codex/devdocs/gc-sa.md b/codex/devdocs/gc-sa.md index 432c654..85d16c1 100644 --- a/codex/devdocs/gc-sa.md +++ b/codex/devdocs/gc-sa.md @@ -48,7 +48,7 @@ code base to make things work. ## GC Invariants There is two simple invariants correctness: -- All GC_PUSH calls need to be followed by an appropriate GC_POP (in practice we enforce this +- All `GC_PUSH` calls need to be followed by an appropriate `GC_POP` (in practice we enforce this at the function level) - If a value was previously not rooted at any safepoint, it may no longer be referenced afterwards diff --git a/codex/devdocs/locks.md b/codex/devdocs/locks.md index 912fe66..89a7d43 100644 --- a/codex/devdocs/locks.md +++ b/codex/devdocs/locks.md @@ -34,6 +34,10 @@ The following is a leaf lock (level 2), and only acquires level 1 locks (safepoi > * typecache +The following is a level 2 lock: + +> * Module->lock + The following is a level 3 lock, which can only acquire level 1 or level 2 locks internally: > * Method->writelock @@ -102,6 +106,8 @@ Type declarations : toplevel lock Type application : typecache lock +Global variable tables : Module->lock + Module serializer : toplevel lock JIT & type-inference : codegen lock diff --git a/codex/manual/documentation.md b/codex/manual/documentation.md index 8d12c62..a8841a5 100644 --- a/codex/manual/documentation.md +++ b/codex/manual/documentation.md @@ -260,9 +260,7 @@ with the `catdoc` function, which can of course be overridden for custom types. ## Advanced Usage The `@doc` macro associates its first argument with its second in a per-module dictionary called -`META`. By default, documentation is expected to be written in Markdown, and the `doc""` string -macro simply creates an object representing the Markdown content. In the future it is likely to -do more advanced things such as allowing for relative image or link paths. +`META`. To make it easier to write documentation, the parser treats the macro name `@doc` specially: if a call to `@doc` has one argument, but another expression appears after a single line @@ -276,7 +274,7 @@ Therefore the following syntax is parsed as a 2-argument call to `@doc`: f(x) = x ``` -This makes it easy to use an arbitrary object (here a `raw` string) as a docstring. +This makes it possible to use expressions other than normal string literals (such as the `raw""` string macro) as a docstring. When used for retrieving documentation, the `@doc` macro (or equally, the `doc` function) will search all `META` dictionaries for metadata relevant to the given object and return it. The returned @@ -337,11 +335,23 @@ y = MyType("y") ## Syntax Guide A comprehensive overview of all documentable Julia syntax. - In the following examples `"..."` is used to illustrate an arbitrary docstring. -`doc""` should only be used when the docstring contains `$` or `\` characters that should not -be parsed by Julia such as LaTeX syntax or Julia source code examples containing interpolation. +### `$` and `\` characters + +The `$` and `\` characters are still parsed as string interpolation or start of an escape sequence +in docstrings too. The `raw""` string macro together with the `@doc` macro can be used to avoid +having to escape them. This is handy when the docstrings include LaTeX or Julia source code examples +containing interpolation: + +````julia +@doc raw""" +```math +\LaTeX +``` +""" +function f end +```` ### Functions and Methods diff --git a/codex/manual/modules.md b/codex/manual/modules.md index 80f59ff..01a057a 100644 --- a/codex/manual/modules.md +++ b/codex/manual/modules.md @@ -46,8 +46,8 @@ The statement `using BigLib: thing1, thing2` brings just the identifiers `thing1 into scope from module `BigLib`. If these names refer to functions, adding methods to them will not be allowed (you may only "use" them, not extend them). -The [`import`](@ref) keyword supports the same syntax as [`using`](@ref), but only operates on a single name -at a time. It does not add modules to be searched the way `using` does. `import` also differs +The [`import`](@ref) keyword supports the same syntax as [`using`](@ref). +It does not add modules to be searched the way `using` does. `import` also differs from `using` in that functions imported using `import` can be extended with new methods. In `MyModule` above we wanted to add a method to the standard [`show`](@ref) function, so we had to write diff --git a/codex/manual/parallel-computing.md b/codex/manual/parallel-computing.md index 04076b5..a796b7d 100644 --- a/codex/manual/parallel-computing.md +++ b/codex/manual/parallel-computing.md @@ -590,15 +590,14 @@ julia> remotecall_fetch(getindex, 2, r, 1, 1) Remember that [`getindex(r,1,1)`](@ref) is [equivalent](@ref man-array-indexing) to `r[1,1]`, so this call fetches the first element of the future `r`. -The syntax of [`remotecall`](@ref) is not especially convenient. The macro [`@spawn`](@ref) -makes things easier. It operates on an expression rather than a function, and picks where to do +To make things easier, the symbol `:any` can be passed to [`@spawnat`], which picks where to do the operation for you: ```julia-repl -julia> r = @spawn rand(2,2) +julia> r = @spawnat :any rand(2,2) Future(2, 1, 4, nothing) -julia> s = @spawn 1 .+ fetch(r) +julia> s = @spawnat :any 1 .+ fetch(r) Future(3, 1, 5, nothing) julia> fetch(s) @@ -609,17 +608,17 @@ julia> fetch(s) Note that we used `1 .+ fetch(r)` instead of `1 .+ r`. This is because we do not know where the code will run, so in general a [`fetch`](@ref) might be required to move `r` to the process -doing the addition. In this case, [`@spawn`](@ref) is smart enough to perform the computation +doing the addition. In this case, [`@spawnat`](@ref) is smart enough to perform the computation on the process that owns `r`, so the [`fetch`](@ref) will be a no-op (no work is done). -(It is worth noting that [`@spawn`](@ref) is not built-in but defined in Julia as a [macro](@ref man-macros). +(It is worth noting that [`@spawnat`](@ref) is not built-in but defined in Julia as a [macro](@ref man-macros). It is possible to define your own such constructs.) An important thing to remember is that, once fetched, a [`Future`](@ref Distributed.Future) will cache its value locally. Further [`fetch`](@ref) calls do not entail a network hop. Once all referencing [`Future`](@ref Distributed.Future)s have fetched, the remote stored value is deleted. -[`@async`](@ref) is similar to [`@spawn`](@ref), but only runs tasks on the local process. We +[`@async`](@ref) is similar to [`@spawnat`](@ref), but only runs tasks on the local process. We use it to create a "feeder" task for each process. Each task picks the next index that needs to be computed, then waits for its process to finish, then repeats until we run out of indices. Note that the feeder tasks do not begin to execute until the main task reaches the end of the [`@sync`](@ref) @@ -653,7 +652,7 @@ julia> rand2(2,2) 0.153756 0.368514 1.15119 0.918912 -julia> fetch(@spawn rand2(2,2)) +julia> fetch(@spawnat :any rand2(2,2)) ERROR: RemoteException(2, CapturedException(UndefVarError(Symbol("#rand2")) Stacktrace: [...] @@ -772,7 +771,7 @@ To this end, it is important to understand the data movement performed by Julia' programming constructs. [`fetch`](@ref) can be considered an explicit data movement operation, since it directly asks -that an object be moved to the local machine. [`@spawn`](@ref) (and a few related constructs) +that an object be moved to the local machine. [`@spawnat`](@ref) (and a few related constructs) also moves data, but this is not as obvious, hence it can be called an implicit data movement operation. Consider these two approaches to constructing and squaring a random matrix: @@ -781,7 +780,7 @@ Method 1: ```julia-repl julia> A = rand(1000,1000); -julia> Bref = @spawn A^2; +julia> Bref = @spawnat :any A^2; [...] @@ -791,14 +790,14 @@ julia> fetch(Bref); Method 2: ```julia-repl -julia> Bref = @spawn rand(1000,1000)^2; +julia> Bref = @spawnat :any rand(1000,1000)^2; [...] julia> fetch(Bref); ``` -The difference seems trivial, but in fact is quite significant due to the behavior of [`@spawn`](@ref). +The difference seems trivial, but in fact is quite significant due to the behavior of [`@spawnat`](@ref). In the first method, a random matrix is constructed locally, then sent to another process where it is squared. In the second method, a random matrix is both constructed and squared on another process. Therefore the second method sends much less data than the first. @@ -807,13 +806,13 @@ In this toy example, the two methods are easy to distinguish and choose from. Ho program designing data movement might require more thought and likely some measurement. For example, if the first process needs matrix `A` then the first method might be better. Or, if computing `A` is expensive and only the current process has it, then moving it to another process might -be unavoidable. Or, if the current process has very little to do between the [`@spawn`](@ref) +be unavoidable. Or, if the current process has very little to do between the [`@spawnat`](@ref) and `fetch(Bref)`, it might be better to eliminate the parallelism altogether. Or imagine `rand(1000,1000)` -is replaced with a more expensive operation. Then it might make sense to add another [`@spawn`](@ref) +is replaced with a more expensive operation. Then it might make sense to add another [`@spawnat`](@ref) statement just for this step. ## Global variables -Expressions executed remotely via `@spawn`, or closures specified for remote execution using +Expressions executed remotely via `@spawnat`, or closures specified for remote execution using `remotecall` may refer to global variables. Global bindings under module `Main` are treated a little differently compared to global bindings in other modules. Consider the following code snippet: @@ -887,7 +886,7 @@ and hence a binding for `B` does not exist on worker 2. Fortunately, many useful parallel computations do not require data movement. A common example is a Monte Carlo simulation, where multiple processes can handle independent simulation trials -simultaneously. We can use [`@spawn`](@ref) to flip coins on two processes. First, write the following +simultaneously. We can use [`@spawnat`](@ref) to flip coins on two processes. First, write the following function in `count_heads.jl`: ```julia @@ -906,10 +905,10 @@ trials on two machines, and add together the results: ```julia-repl julia> @everywhere include_string(Main, $(read("count_heads.jl", String)), "count_heads.jl") -julia> a = @spawn count_heads(100000000) +julia> a = @spawnat :any count_heads(100000000) Future(2, 1, 6, nothing) -julia> b = @spawn count_heads(100000000) +julia> b = @spawnat :any count_heads(100000000) Future(3, 1, 7, nothing) julia> fetch(a)+fetch(b) @@ -926,7 +925,7 @@ for `f` to be associative, so that it does not matter what order the operations in. Notice that our use of this pattern with `count_heads` can be generalized. We used two explicit -[`@spawn`](@ref) statements, which limits the parallelism to two processes. To run on any number +[`@spawnat`](@ref) statements, which limits the parallelism to two processes. To run on any number of processes, we can use a *parallel for loop*, running in distributed memory, which can be written in Julia using [`@distributed`](@ref) like this: diff --git a/codex/stdlib/Distributed.md b/codex/stdlib/Distributed.md index 7b4efae..49668bb 100644 --- a/codex/stdlib/Distributed.md +++ b/codex/stdlib/Distributed.md @@ -39,7 +39,6 @@ Distributed.remotecall(::Any, ::AbstractWorkerPool, ::Any...) Distributed.remotecall_wait(::Any, ::AbstractWorkerPool, ::Any...) Distributed.remotecall_fetch(::Any, ::AbstractWorkerPool, ::Any...) Distributed.remote_do(::Any, ::AbstractWorkerPool, ::Any...) -Distributed.@spawn Distributed.@spawnat Distributed.@fetch Distributed.@fetchfrom diff --git a/src/NEWS.md b/src/NEWS.md index 1fe0a69..f542849 100644 --- a/src/NEWS.md +++ b/src/NEWS.md @@ -14,6 +14,12 @@ Language changes Multi-threading changes ----------------------- +* All system-level I/O operations (e.g. files and sockets) are now thread-safe. + This does not include subtypes of `IO` that are entirely in-memory, such as `IOBuffer`, + although it specifically does include `BufferStream`. + ([#32309](https://github.com/JuliaLang/julia/issues/32309), [#32174](https://github.com/JuliaLang/julia/issues/32174), [#31981](https://github.com/JuliaLang/julia/issues/31981), [#32421](https://github.com/JuliaLang/julia/issues/32421)). +* The global random number generator (`GLOBAL_RNG`) is now thread-safe (and thread-local) ([#32407](https://github.com/JuliaLang/julia/issues/32407)). +* New experimental `Threads.@spawn` macro that runs a task on any available thread ([#32600](https://github.com/JuliaLang/julia/issues/32600)). Build system changes -------------------- @@ -25,12 +31,14 @@ New library functions * `findfirst`, `findlast`, `findnext` and `findprev` now accept a character as first argument to search for that character in a string passed as the second argument ([#31664](https://github.com/JuliaLang/julia/issues/31664)). * New `findall(pattern, string)` method where `pattern` is a string or regex ([#31834](https://github.com/JuliaLang/julia/issues/31834)). +* `istaskfailed` is now documented and exported, like its siblings `istaskdone` and `istaskstarted` ([#32300](https://github.com/JuliaLang/julia/issues/32300)). +* `RefArray` and `RefValue` objects now accept index `CartesianIndex()` in `getindex` and `setindex!` ([#32653](https://github.com/JuliaLang/julia/issues/32653)) Standard library changes ------------------------ * `Regex` can now be multiplied (`*`) and exponentiated (`^`), like strings ([#23422](https://github.com/JuliaLang/julia/issues/23422)). -* `Cmd` interpolation (`` `$(x::Cmd) a b c` `` where) now propagates `x`'s process flags +* `Cmd` interpolation (``` `$(x::Cmd) a b c` ``` where) now propagates `x`'s process flags (environment, flags, working directory, etc) if `x` is the first interpolant and errors otherwise ([#24353](https://github.com/JuliaLang/julia/issues/24353)). * Zero-dimensional arrays are now consistently preserved in the return values of mathematical @@ -39,6 +47,8 @@ Standard library changes when operating over zero-dimensional arrays ([#32122](https://github.com/JuliaLang/julia/issues/32122)). * `IPAddr` subtypes now behave like scalars when used in broadcasting ([#32133](https://github.com/JuliaLang/julia/issues/32133)). * `clamp` can now handle missing values ([#31066](https://github.com/JuliaLang/julia/issues/31066)). +* `empty` now accepts a `NamedTuple` ([#32534](https://github.com/JuliaLang/julia/issues/32534)). +* `mod` now accepts a unit range as the second argument to easily perform offset modular arithmetic to ensure the result is inside the range ([#32628](https://github.com/JuliaLang/julia/issues/32628)). #### Libdl @@ -57,6 +67,7 @@ Standard library changes must be compatible with `m`, `n`, and `eltype(colptr)`. * `sparse(I, J, V, m, n)` verifies lengths of `I`, `J`, `V` are equal and compatible with `eltype(I)` and `m`, `n`. +* The `sprand` function is now 2 to 5 times faster ([#30494](https://github.com/JuliaLang/julia/issues/30494)). As a consequence of this change, the random stream of matrices produced with `sprand` and `sprandn` has changed. #### Dates @@ -81,6 +92,11 @@ Standard library changes * `foldr` and `mapfoldr` now work on any iterator that supports `Iterators.reverse`, not just arrays ([#31781](https://github.com/JuliaLang/julia/issues/31781)). +Deprecated or removed +--------------------- + +* `@spawn expr` from the `Distributed` standard library should be replaced with `@spawnat :any expr` ([#32600](https://github.com/JuliaLang/julia/issues/32600)). + External dependencies --------------------- diff --git a/src/base/multi-threading.md b/src/base/multi-threading.md index 1b58e61..3508bbc 100644 --- a/src/base/multi-threading.md +++ b/src/base/multi-threading.md @@ -7,6 +7,7 @@ described here might (and likely will) change in the future. Base.Threads.threadid Base.Threads.nthreads Base.Threads.@threads +Base.Threads.@spawn ``` ```@docs diff --git a/src/base/parallel.md b/src/base/parallel.md index 362e6bc..453cd45 100644 --- a/src/base/parallel.md +++ b/src/base/parallel.md @@ -11,6 +11,7 @@ Base.fetch(t::Task) Base.current_task Base.istaskdone Base.istaskstarted +Base.istaskfailed Base.task_local_storage(::Any) Base.task_local_storage(::Any, ::Any) Base.task_local_storage(::Function, ::Any, ::Any) diff --git a/src/devdocs/ast.md b/src/devdocs/ast.md index e234880..c5b23df 100644 --- a/src/devdocs/ast.md +++ b/src/devdocs/ast.md @@ -236,7 +236,7 @@ to interpolate code from the caller. ## Lowered form Lowered form (IR) is more important to the compiler, since it is used for type inference, -optimizations like inlining, and and code generation. It is also less obvious to the human, +optimizations like inlining, and code generation. It is also less obvious to the human, since it results from a significant rearrangement of the input syntax. In addition to `Symbol`s and some number types, the following data diff --git a/src/devdocs/cartesian.md b/src/devdocs/cartesian.md index 6e115ea..1d338cb 100644 --- a/src/devdocs/cartesian.md +++ b/src/devdocs/cartesian.md @@ -16,10 +16,10 @@ end which generates the following code: ```julia -for i_3 = 1:size(A,3) - for i_2 = 1:size(A,2) - for i_1 = 1:size(A,1) - s += A[i_1,i_2,i_3] +for i_3 = axes(A, 3) + for i_2 = axes(A, 2) + for i_1 = axes(A, 1) + s += A[i_1, i_2, i_3] end end end @@ -38,7 +38,7 @@ The (basic) syntax of `@nloops` is as follows: * The second argument is the symbol-prefix used for the iterator variable. Here we used `i`, and variables `i_1, i_2, i_3` were generated. * The third argument specifies the range for each iterator variable. If you use a variable (symbol) - here, it's taken as `1:size(A,dim)`. More flexibly, you can use the anonymous-function expression + here, it's taken as `axes(A, dim)`. More flexibly, you can use the anonymous-function expression syntax described below. * The last argument is the body of the loop. Here, that's what appears between the `begin...end`. @@ -46,7 +46,7 @@ There are some additional features of `@nloops` described in the [reference sect `@nref` follows a similar pattern, generating `A[i_1,i_2,i_3]` from `@nref 3 A i`. The general practice is to read from left to right, which is why `@nloops` is `@nloops 3 i A expr` (as in -`for i_2 = 1:size(A,2)`, where `i_2` is to the left and the range is to the right) whereas `@nref` +`for i_2 = axes(A, 2)`, where `i_2` is to the left and the range is to the right) whereas `@nref` is `@nref 3 A i` (as in `A[i_1,i_2,i_3]`, where the array comes first). If you're developing code with Cartesian, you may find that debugging is easier when you examine diff --git a/src/devdocs/gc-sa.md b/src/devdocs/gc-sa.md index 432c654..85d16c1 100644 --- a/src/devdocs/gc-sa.md +++ b/src/devdocs/gc-sa.md @@ -48,7 +48,7 @@ code base to make things work. ## GC Invariants There is two simple invariants correctness: -- All GC_PUSH calls need to be followed by an appropriate GC_POP (in practice we enforce this +- All `GC_PUSH` calls need to be followed by an appropriate `GC_POP` (in practice we enforce this at the function level) - If a value was previously not rooted at any safepoint, it may no longer be referenced afterwards diff --git a/src/devdocs/locks.md b/src/devdocs/locks.md index 912fe66..89a7d43 100644 --- a/src/devdocs/locks.md +++ b/src/devdocs/locks.md @@ -34,6 +34,10 @@ The following is a leaf lock (level 2), and only acquires level 1 locks (safepoi > * typecache +The following is a level 2 lock: + +> * Module->lock + The following is a level 3 lock, which can only acquire level 1 or level 2 locks internally: > * Method->writelock @@ -102,6 +106,8 @@ Type declarations : toplevel lock Type application : typecache lock +Global variable tables : Module->lock + Module serializer : toplevel lock JIT & type-inference : codegen lock diff --git a/src/manual/documentation.md b/src/manual/documentation.md index 8d12c62..a8841a5 100644 --- a/src/manual/documentation.md +++ b/src/manual/documentation.md @@ -260,9 +260,7 @@ with the `catdoc` function, which can of course be overridden for custom types. ## Advanced Usage The `@doc` macro associates its first argument with its second in a per-module dictionary called -`META`. By default, documentation is expected to be written in Markdown, and the `doc""` string -macro simply creates an object representing the Markdown content. In the future it is likely to -do more advanced things such as allowing for relative image or link paths. +`META`. To make it easier to write documentation, the parser treats the macro name `@doc` specially: if a call to `@doc` has one argument, but another expression appears after a single line @@ -276,7 +274,7 @@ Therefore the following syntax is parsed as a 2-argument call to `@doc`: f(x) = x ``` -This makes it easy to use an arbitrary object (here a `raw` string) as a docstring. +This makes it possible to use expressions other than normal string literals (such as the `raw""` string macro) as a docstring. When used for retrieving documentation, the `@doc` macro (or equally, the `doc` function) will search all `META` dictionaries for metadata relevant to the given object and return it. The returned @@ -337,11 +335,23 @@ y = MyType("y") ## Syntax Guide A comprehensive overview of all documentable Julia syntax. - In the following examples `"..."` is used to illustrate an arbitrary docstring. -`doc""` should only be used when the docstring contains `$` or `\` characters that should not -be parsed by Julia such as LaTeX syntax or Julia source code examples containing interpolation. +### `$` and `\` characters + +The `$` and `\` characters are still parsed as string interpolation or start of an escape sequence +in docstrings too. The `raw""` string macro together with the `@doc` macro can be used to avoid +having to escape them. This is handy when the docstrings include LaTeX or Julia source code examples +containing interpolation: + +````julia +@doc raw""" +```math +\LaTeX +``` +""" +function f end +```` ### Functions and Methods diff --git a/src/manual/modules.md b/src/manual/modules.md index 80f59ff..01a057a 100644 --- a/src/manual/modules.md +++ b/src/manual/modules.md @@ -46,8 +46,8 @@ The statement `using BigLib: thing1, thing2` brings just the identifiers `thing1 into scope from module `BigLib`. If these names refer to functions, adding methods to them will not be allowed (you may only "use" them, not extend them). -The [`import`](@ref) keyword supports the same syntax as [`using`](@ref), but only operates on a single name -at a time. It does not add modules to be searched the way `using` does. `import` also differs +The [`import`](@ref) keyword supports the same syntax as [`using`](@ref). +It does not add modules to be searched the way `using` does. `import` also differs from `using` in that functions imported using `import` can be extended with new methods. In `MyModule` above we wanted to add a method to the standard [`show`](@ref) function, so we had to write diff --git a/src/manual/parallel-computing.md b/src/manual/parallel-computing.md index 04076b5..a796b7d 100644 --- a/src/manual/parallel-computing.md +++ b/src/manual/parallel-computing.md @@ -590,15 +590,14 @@ julia> remotecall_fetch(getindex, 2, r, 1, 1) Remember that [`getindex(r,1,1)`](@ref) is [equivalent](@ref man-array-indexing) to `r[1,1]`, so this call fetches the first element of the future `r`. -The syntax of [`remotecall`](@ref) is not especially convenient. The macro [`@spawn`](@ref) -makes things easier. It operates on an expression rather than a function, and picks where to do +To make things easier, the symbol `:any` can be passed to [`@spawnat`], which picks where to do the operation for you: ```julia-repl -julia> r = @spawn rand(2,2) +julia> r = @spawnat :any rand(2,2) Future(2, 1, 4, nothing) -julia> s = @spawn 1 .+ fetch(r) +julia> s = @spawnat :any 1 .+ fetch(r) Future(3, 1, 5, nothing) julia> fetch(s) @@ -609,17 +608,17 @@ julia> fetch(s) Note that we used `1 .+ fetch(r)` instead of `1 .+ r`. This is because we do not know where the code will run, so in general a [`fetch`](@ref) might be required to move `r` to the process -doing the addition. In this case, [`@spawn`](@ref) is smart enough to perform the computation +doing the addition. In this case, [`@spawnat`](@ref) is smart enough to perform the computation on the process that owns `r`, so the [`fetch`](@ref) will be a no-op (no work is done). -(It is worth noting that [`@spawn`](@ref) is not built-in but defined in Julia as a [macro](@ref man-macros). +(It is worth noting that [`@spawnat`](@ref) is not built-in but defined in Julia as a [macro](@ref man-macros). It is possible to define your own such constructs.) An important thing to remember is that, once fetched, a [`Future`](@ref Distributed.Future) will cache its value locally. Further [`fetch`](@ref) calls do not entail a network hop. Once all referencing [`Future`](@ref Distributed.Future)s have fetched, the remote stored value is deleted. -[`@async`](@ref) is similar to [`@spawn`](@ref), but only runs tasks on the local process. We +[`@async`](@ref) is similar to [`@spawnat`](@ref), but only runs tasks on the local process. We use it to create a "feeder" task for each process. Each task picks the next index that needs to be computed, then waits for its process to finish, then repeats until we run out of indices. Note that the feeder tasks do not begin to execute until the main task reaches the end of the [`@sync`](@ref) @@ -653,7 +652,7 @@ julia> rand2(2,2) 0.153756 0.368514 1.15119 0.918912 -julia> fetch(@spawn rand2(2,2)) +julia> fetch(@spawnat :any rand2(2,2)) ERROR: RemoteException(2, CapturedException(UndefVarError(Symbol("#rand2")) Stacktrace: [...] @@ -772,7 +771,7 @@ To this end, it is important to understand the data movement performed by Julia' programming constructs. [`fetch`](@ref) can be considered an explicit data movement operation, since it directly asks -that an object be moved to the local machine. [`@spawn`](@ref) (and a few related constructs) +that an object be moved to the local machine. [`@spawnat`](@ref) (and a few related constructs) also moves data, but this is not as obvious, hence it can be called an implicit data movement operation. Consider these two approaches to constructing and squaring a random matrix: @@ -781,7 +780,7 @@ Method 1: ```julia-repl julia> A = rand(1000,1000); -julia> Bref = @spawn A^2; +julia> Bref = @spawnat :any A^2; [...] @@ -791,14 +790,14 @@ julia> fetch(Bref); Method 2: ```julia-repl -julia> Bref = @spawn rand(1000,1000)^2; +julia> Bref = @spawnat :any rand(1000,1000)^2; [...] julia> fetch(Bref); ``` -The difference seems trivial, but in fact is quite significant due to the behavior of [`@spawn`](@ref). +The difference seems trivial, but in fact is quite significant due to the behavior of [`@spawnat`](@ref). In the first method, a random matrix is constructed locally, then sent to another process where it is squared. In the second method, a random matrix is both constructed and squared on another process. Therefore the second method sends much less data than the first. @@ -807,13 +806,13 @@ In this toy example, the two methods are easy to distinguish and choose from. Ho program designing data movement might require more thought and likely some measurement. For example, if the first process needs matrix `A` then the first method might be better. Or, if computing `A` is expensive and only the current process has it, then moving it to another process might -be unavoidable. Or, if the current process has very little to do between the [`@spawn`](@ref) +be unavoidable. Or, if the current process has very little to do between the [`@spawnat`](@ref) and `fetch(Bref)`, it might be better to eliminate the parallelism altogether. Or imagine `rand(1000,1000)` -is replaced with a more expensive operation. Then it might make sense to add another [`@spawn`](@ref) +is replaced with a more expensive operation. Then it might make sense to add another [`@spawnat`](@ref) statement just for this step. ## Global variables -Expressions executed remotely via `@spawn`, or closures specified for remote execution using +Expressions executed remotely via `@spawnat`, or closures specified for remote execution using `remotecall` may refer to global variables. Global bindings under module `Main` are treated a little differently compared to global bindings in other modules. Consider the following code snippet: @@ -887,7 +886,7 @@ and hence a binding for `B` does not exist on worker 2. Fortunately, many useful parallel computations do not require data movement. A common example is a Monte Carlo simulation, where multiple processes can handle independent simulation trials -simultaneously. We can use [`@spawn`](@ref) to flip coins on two processes. First, write the following +simultaneously. We can use [`@spawnat`](@ref) to flip coins on two processes. First, write the following function in `count_heads.jl`: ```julia @@ -906,10 +905,10 @@ trials on two machines, and add together the results: ```julia-repl julia> @everywhere include_string(Main, $(read("count_heads.jl", String)), "count_heads.jl") -julia> a = @spawn count_heads(100000000) +julia> a = @spawnat :any count_heads(100000000) Future(2, 1, 6, nothing) -julia> b = @spawn count_heads(100000000) +julia> b = @spawnat :any count_heads(100000000) Future(3, 1, 7, nothing) julia> fetch(a)+fetch(b) @@ -926,7 +925,7 @@ for `f` to be associative, so that it does not matter what order the operations in. Notice that our use of this pattern with `count_heads` can be generalized. We used two explicit -[`@spawn`](@ref) statements, which limits the parallelism to two processes. To run on any number +[`@spawnat`](@ref) statements, which limits the parallelism to two processes. To run on any number of processes, we can use a *parallel for loop*, running in distributed memory, which can be written in Julia using [`@distributed`](@ref) like this: diff --git a/src/stdlib/Distributed.md b/src/stdlib/Distributed.md index 7b4efae..49668bb 100644 --- a/src/stdlib/Distributed.md +++ b/src/stdlib/Distributed.md @@ -39,7 +39,6 @@ Distributed.remotecall(::Any, ::AbstractWorkerPool, ::Any...) Distributed.remotecall_wait(::Any, ::AbstractWorkerPool, ::Any...) Distributed.remotecall_fetch(::Any, ::AbstractWorkerPool, ::Any...) Distributed.remote_do(::Any, ::AbstractWorkerPool, ::Any...) -Distributed.@spawn Distributed.@spawnat Distributed.@fetch Distributed.@fetchfrom From aa233b979962014131a8cfcdcba39f976854973b Mon Sep 17 00:00:00 2001 From: dentos Date: Sun, 26 Jul 2020 23:16:25 +0900 Subject: [PATCH 122/153] =?UTF-8?q?=ED=95=9C=EA=B5=AD=20=EC=9C=84=ED=82=A4?= =?UTF-8?q?=EB=A1=9C=20=EB=A7=81=ED=81=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/index.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/index.md b/src/index.md index feeb442..aaf1586 100644 --- a/src/index.md +++ b/src/index.md @@ -56,13 +56,13 @@ Markdown.parse(""" 그럼에도 작성한 코드가 느리다면 [성능 팁](@ref man-performance-tips)을 읽어보길 권한다. 줄리아가 어떤 식으로 작동하는지 이해한 뒤라면, C에 근접하는 성능의 코드를 짜는 건 쉽다. -줄리아는 타입 추론과 [LLVM](https://en.wikipedia.org/wiki/Low_Level_Virtual_Machine)으로 구현한 [적시 컴파일 (JIT)](https://en.wikipedia.org/wiki/Just-in-time_compilation)을 사용해 +줄리아는 타입 추론과 [LLVM](https://ko.wikipedia.org/wiki/LLVM)으로 구현한 [JIT 컴파일](https://ko.wikipedia.org/wiki/JIT_%EC%BB%B4%ED%8C%8C%EC%9D%BC)을 사용해 선택적 타입, 멀티플 디스패치, 좋은 성능을 이뤄내고 있다. 그리고 명령형, 함수형, 객체 지향 프로그래밍의 특징을 포괄하는 다양한 패러다임을 추구한다. 줄리아는 고급 단계의 수치 계산에 있어 R, 매트랩, 파이썬처럼 간편하고 표현력이 우수하다. 뿐만 아니라 일반적인 형태의 프로그래밍 또한 가능하다. 이를 위해 줄리아는 수학 프로그래밍 언어를 근간으로 해서 구축하였고 -[리스프](https://en.wikipedia.org/wiki/Lisp_(programming_language)), [펄](https://en.wikipedia.org/wiki/Perl_(programming_language)), -[파이썬](https://en.wikipedia.org/wiki/Python_(programming_language)), [루아](https://en.wikipedia.org/wiki/Lua_(programming_language)), -[루비](https://en.wikipedia.org/wiki/Ruby_(programming_language))와 같은 인기있는 동적 언어의 기능을 취합하고 있다. +[리스프](https://ko.wikipedia.org/wiki/%EB%A6%AC%EC%8A%A4%ED%94%84), [펄](https://ko.wikipedia.org/wiki/%ED%8E%84), +[파이썬](https://ko.wikipedia.org/wiki/%ED%8C%8C%EC%9D%B4%EC%8D%AC), [루아](https://ko.wikipedia.org/wiki/%EB%A3%A8%EC%95%84_(%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D_%EC%96%B8%EC%96%B4)), +[루비](https://ko.wikipedia.org/wiki/%EB%A3%A8%EB%B9%84_(%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D_%EC%96%B8%EC%96%B4))와 같은 인기있는 동적 언어의 기능을 취합하고 있다. 기존에 있는 동적 언어와 비교해 보는 줄리아만의 독특한 점은: @@ -96,7 +96,7 @@ Markdown.parse(""" * 가벼운 "그린" 쓰레딩 ([코루틴](https://en.wikipedia.org/wiki/Coroutine)) * 거슬리지 않는 강력한 타입 시스템 * 숫자와 다른 타입을 위한 우아하고 확장 가능한 컨버젼 및 프로모션(타입 변환) - * 효율적인 [유니코드](https://en.wikipedia.org/wiki/Unicode) 와 [UTF-8](https://en.wikipedia.org/wiki/UTF-8) 지원 + * 효율적인 [유니코드](https://ko.wikipedia.org/wiki/%EC%9C%A0%EB%8B%88%EC%BD%94%EB%93%9C) 와 [UTF-8](https://ko.wikipedia.org/wiki/UTF-8) 지원 * C 함수 직접 호출(별도의 래퍼나 특정한 API가 필요하지 않음) * 다른 프로세스를 관리하는 쉘과 비슷한 강력한 기능 * 리스프와 비슷한 매크로, 메타프로그래밍을 위한 장치들 From fd7d1650c3410aa671fdbc66faabdf6c06ea531d Mon Sep 17 00:00:00 2001 From: dentos Date: Mon, 27 Jul 2020 00:44:07 +0900 Subject: [PATCH 123/153] =?UTF-8?q?=ED=95=A8=EC=88=98=20/=EB=8B=A4?= =?UTF-8?q?=EC=B0=A8=EC=9B=90=20=EB=B0=B0=EC=97=B4=20=EB=B2=88=EC=97=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/manual/arrays.md | 14 ++------- src/manual/functions.md | 69 +++++++++++------------------------------ 2 files changed, 20 insertions(+), 63 deletions(-) diff --git a/src/manual/arrays.md b/src/manual/arrays.md index e8803b3..19f9102 100644 --- a/src/manual/arrays.md +++ b/src/manual/arrays.md @@ -15,17 +15,7 @@ Julia는 배열을 특별하게 취급하지는 않는다. Julia 컴파일러는 타입 추론을 사용하여 스칼라 배열 인덱싱에 최적화된 코드를 생성한다. 따라서 편리하고 읽기 쉬운 스타일로 프로그램을 작성하더라도 성능을 희생하지 않으며, 오히려 메모리를 더 적게 사용하는 경우도 있다. -In Julia, all arguments to functions are [passed by -sharing](https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing) -(i.e. by pointers). Some technical computing languages pass arrays by value, and -while this prevents accidental modification by callees of a value in the caller, -it makes avoiding unwanted copying of arrays difficult. By convention, a -function name ending with a `!` indicates that it will mutate or destroy the -value of one or more of its arguments (compare, for example, [`sort`](@ref) and [`sort!`](@ref)). -Callees must make explicit copies to ensure that they don't modify inputs that -they don't intend to change. Many non- mutating functions are implemented by -calling a function of the same name with an added `!` at the end on an explicit -copy of the input, and returning that copy. +줄리아는 함수에 인자를 줄 때 "공유를 통한 전달[pass-by-sharing](https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing)을 한다. 몇몇 프로그래밍 언어는 배열을 값으로 전달하여([pass-by-value](https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_value)), 원치않는 수정을 막지만 무분별한 값의 복사로 인해 속도 지연을 겪을 수 있다. 줄리아는 관습적으로 `!`울 함수 이름의 마지막에 붙여 값이 수정되거나 삭제될 수 있음을 미연에 알려준다([`sort`](@ref)와 [`sort!`](@ref)를 비교해보자). 함수내에서 오브젝트를 수정하지 않으려면 명시적으로 복사를 해야한다. 이렇게 오브젝트를 수정하지 않는 함수는 `!`이 붙여진 동일 이름의 함수와 같은 역할을 하면서 복사된 오브젝트를 반환한다. ## 기본 함수 @@ -122,7 +112,7 @@ julia> hcat([1 2], 3) | `[A B; C D; ...]` | [`hvcat`](@ref) | [`hvcat`](@ref) 은 1차원 (세미콜론으로 구분) 과 2차원(스페이스로 구분) 모두 병합한다. -Consider these examples of this syntax: +아래 예제의 문법과 결과물을 비교해보자: ```jldoctest julia> [[1; 2]; [3, 4]] 4-element Array{Int64,1}: diff --git a/src/manual/functions.md b/src/manual/functions.md index 1c68f08..88cf799 100644 --- a/src/manual/functions.md +++ b/src/manual/functions.md @@ -1,8 +1,6 @@ -# [Functions](@id man-functions) +# [함수](@id man-functions) -In Julia, a function is an object that maps a tuple of argument values to a return value. Julia -functions are not pure mathematical functions, in the sense that functions can alter and be affected -by the global state of the program. The basic syntax for defining functions in Julia is: +함수는 인자를 받아 값을 리턴하는 오브젝트이다. 줄리아에서 정의하는 함수는 실행 상황에 영향을 받는다는 점에서 수학적 정의에 따른 함수와는 다르다. 아래는 줄리아에서 함수는 정의하는 가장 기본적인 방법이다: ```jldoctest julia> function f(x,y) @@ -10,29 +8,20 @@ julia> function f(x,y) end f (generic function with 1 method) ``` - -There is a second, more terse syntax for defining a function in Julia. The traditional function -declaration syntax demonstrated above is equivalent to the following compact "assignment form": - +아래와 같이 함수를 정의하는 방법도 있다: ```jldoctest fofxy julia> f(x,y) = x + y f (generic function with 1 method) ``` +위처럼 "할당 형식(assignment form)"으로 선언할 경우 복합 표현이더라도 한줄로 표현해야 한다([복합 표현을 자세하고 알고 싶다면?](@ref man-compound-expressions)). 이렇게 함수를 표현하는 경우는 줄리아에 흔한 일이고, 때론 코드 가독성을 높여준다. -In the assignment form, the body of the function must be a single expression, although it can -be a compound expression (see [Compound Expressions](@ref man-compound-expressions)). Short, simple function definitions -are common in Julia. The short function syntax is accordingly quite idiomatic, considerably reducing -both typing and visual noise. - -A function is called using the traditional parenthesis syntax: +다른 언어처럼 괄호를 통해 함수 인자를 전달한다: ```jldoctest fofxy julia> f(2,3) 5 ``` - -Without parentheses, the expression `f` refers to the function object, and can be passed around -like any value: +괄호가 없는 `f`는 함수 오브젝트로써 하나의 값으로 취급할 수 있다: ```jldoctest fofxy julia> g = f; @@ -40,8 +29,7 @@ julia> g = f; julia> g(2,3) 5 ``` - -As with variables, Unicode can also be used for function names: +함수의 이름은 유니코드라면 무엇이든지 가능하다: ```jldoctest julia> ∑(x,y) = x + y @@ -51,22 +39,11 @@ julia> ∑(2, 3) 5 ``` -## Argument Passing Behavior +## 인자 전달 방식 +함수에 인자를 줄 때 줄리아는 "공유를 통한 전달([pass-by-sharing](https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing))"을 한다. 이 말은 즉슨, 오브젝트를 복사하지 않고 공유한다는 뜻이다. 전달된 인자는 함수 안에 있는 변수에 할당되고, 함수 안의 변수는 단지 그 오브젝트를 가리킬 뿐이다. `Array`와 같은 mutable 오브젝트가 함수 안에서 변하면, 함수 밖에서도 그 변화를 볼 수 있다. 이런 방식은 Scheme, Python, Ruby, Perl 그리고 대부분의 Lisp와 같은 동적언어가 채택한 방식이다. -Julia function arguments follow a convention sometimes called "pass-by-sharing", which means that -values are not copied when they are passed to functions. Function arguments themselves act as -new variable *bindings* (new locations that can refer to values), but the values they refer to -are identical to the passed values. Modifications to mutable values (such as `Array`s) made within -a function will be visible to the caller. This is the same behavior found in Scheme, most Lisps, -Python, Ruby and Perl, among other dynamic languages. - -## The `return` Keyword - -The value returned by a function is the value of the last expression evaluated, which, by default, -is the last expression in the body of the function definition. In the example function, `f`, from -the previous section this is the value of the expression `x + y`. As in C and most other imperative -or functional languages, the `return` keyword causes a function to return immediately, providing -an expression whose value is returned: +## 반환값 +함수가 반환하는 값은 암묵적으로 가장 마지막으로 계산된 값이다. 이전의 예제 함수 `f`에서는 `x+y`의 값이 반환될 것이다. 다른 프로그래밍 언어처럼 `return`과 리턴값이 명시적으로 선언될 경우, 함수는 즉시 종료되고 `return`앞에 있는 식을 계산하고 반환할 것이다: ```julia function g(x,y) @@ -74,9 +51,7 @@ function g(x,y) x + y end ``` - -Since function definitions can be entered into interactive sessions, it is easy to compare these -definitions: +직접 테스트해보자: ```jldoctest julia> f(x,y) = x + y @@ -94,12 +69,8 @@ julia> f(2,3) julia> g(2,3) 6 ``` - -Of course, in a purely linear function body like `g`, the usage of `return` is pointless since -the expression `x + y` is never evaluated and we could simply make `x * y` the last expression -in the function and omit the `return`. In conjunction with other control flow, however, `return` -is of real use. Here, for example, is a function that computes the hypotenuse length of a right -triangle with sides of length `x` and `y`, avoiding overflow: +함수 `g`에서 `x+y`는 절대 실행되지 않기 때문에, 이 부분을 빼고 `x*y`만 남겨놔도 똑같이 작동한다. +`return`을 직접 선언하는 방식은 조건문과 같이 코드의 흐름을 바꾸는 구문과 사용했을 대 빛을 발한다. 아래에 직각 삼각형에서 밑변 `x`와 높이 `y`가 주어졌을 때 빗변의 길이는 구하는 예제로 확인할 수 있다. 아래 함수는 overflow를 없애기 위해 조건문을 사용했다: ```jldoctest julia> function hypot(x,y) @@ -120,13 +91,9 @@ hypot (generic function with 1 method) julia> hypot(3, 4) 5.0 ``` +위 함수는 경우에 따라 세가지 방법으로 값을 반환한다. 마지막은 `return`은 생략해도 된다. -There are three possible points of return from this function, returning the values of three different -expressions, depending on the values of `x` and `y`. The `return` on the last line could be omitted -since it is the last expression. - -A return type can also be specified in the function declaration using the `::` operator. This converts -the return value to the specified type. +반환값의 타입은 `::`로 명시할 수 있으며, 이경우 반환값이 자동 형변환된다. ```jldoctest julia> function g(x, y)::Int8 @@ -137,8 +104,8 @@ julia> typeof(g(1, 2)) Int8 ``` -This function will always return an `Int8` regardless of the types of `x` and `y`. -See [Type Declarations](@ref) for more on return types. +위 함수는 `x`와 `y`의 타입에 상관없이 반환값은 `Int8`로 정해져있다. 타입에 대해 자세히 알고 싶다면 +[타입 선언](@ref)을 참고하자. ## Operators Are Functions From b38e73284f7848b5c751c2f1ff1522f21c1c49ef Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Mon, 27 Jul 2020 02:29:55 +0900 Subject: [PATCH 124/153] =?UTF-8?q?=EB=B9=8C=EB=93=9C=EB=A5=BC=20=EC=9C=84?= =?UTF-8?q?=ED=95=B4=20codex/base/multi-threading.md=20=EC=9A=B0=EC=84=A0?= =?UTF-8?q?=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Manifest.toml | 44 +++++++++++++++++++++++++---------- Project.toml | 1 + codex/base/multi-threading.md | 26 +++++++++++++++------ contrib/html_writer.jl | 2 ++ make.jl | 12 +++++----- src/base/multi-threading.md | 26 +++++++++++++++------ 6 files changed, 79 insertions(+), 32 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index 609d04b..7dd3aff 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -1,3 +1,5 @@ +# This file is machine-generated - editing it directly is not advised + [[Base64]] uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" @@ -6,35 +8,44 @@ deps = ["Printf"] uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" [[Distributed]] -deps = ["LinearAlgebra", "Random", "Serialization", "Sockets"] +deps = ["Random", "Serialization", "Sockets"] uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" [[DocStringExtensions]] deps = ["LibGit2", "Markdown", "Pkg", "Test"] -git-tree-sha1 = "a016e0bfe98a748c4488e2248c2ef4c67d6fdd35" +git-tree-sha1 = "88bb0edb352b16608036faadcc071adda068582a" uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" -version = "0.5.0" +version = "0.8.1" [[Documenter]] -deps = ["Base64", "DocStringExtensions", "InteractiveUtils", "LibGit2", "Logging", "Markdown", "Pkg", "REPL", "Random", "Test", "Unicode"] -git-tree-sha1 = "9f2135e0e7ecb63f9c3ef73ea15a31d8cdb79bb7" +deps = ["Base64", "Dates", "DocStringExtensions", "InteractiveUtils", "JSON", "LibGit2", "Logging", "Markdown", "REPL", "Test", "Unicode"] +git-tree-sha1 = "395fa1554c69735802bba37d9e7d9586fd44326c" uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" -version = "0.20.0" +version = "0.24.11" + +[[DocumenterLaTeX]] +deps = ["Documenter", "Test"] +git-tree-sha1 = "653299370be20ff580bccd707dc9f360c0852d7f" +uuid = "cd674d7a-5f81-5cf3-af33-235ef1834b99" +version = "0.2.0" [[InteractiveUtils]] -deps = ["LinearAlgebra", "Markdown"] +deps = ["Markdown"] uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" +[[JSON]] +deps = ["Dates", "Mmap", "Parsers", "Unicode"] +git-tree-sha1 = "b34d7cef7b337321e97d22242c3c2b91f476748e" +uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +version = "0.21.0" + [[LibGit2]] +deps = ["Printf"] uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" [[Libdl]] uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" -[[LinearAlgebra]] -deps = ["Libdl"] -uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" - [[Logging]] uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" @@ -42,8 +53,17 @@ uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" deps = ["Base64"] uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" +[[Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" + +[[Parsers]] +deps = ["Dates", "Test"] +git-tree-sha1 = "f8f5d2d4b4b07342e5811d2b6428e45524e241df" +uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" +version = "1.0.2" + [[Pkg]] -deps = ["Dates", "LibGit2", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"] +deps = ["Dates", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"] uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" [[Printf]] diff --git a/Project.toml b/Project.toml index dfa65cd..c09e74d 100644 --- a/Project.toml +++ b/Project.toml @@ -1,2 +1,3 @@ [deps] Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" +DocumenterLaTeX = "cd674d7a-5f81-5cf3-af33-235ef1834b99" diff --git a/codex/base/multi-threading.md b/codex/base/multi-threading.md index 3508bbc..4f3e4e5 100644 --- a/codex/base/multi-threading.md +++ b/codex/base/multi-threading.md @@ -1,15 +1,28 @@ # [Multi-Threading](@id lib-multithreading) -This experimental interface supports Julia's multi-threading capabilities. Types and functions -described here might (and likely will) change in the future. - ```@docs -Base.Threads.threadid -Base.Threads.nthreads Base.Threads.@threads +Base.Threads.foreach Base.Threads.@spawn +Base.Threads.threadid +Base.Threads.nthreads ``` +## Synchronization + +```@docs +Base.Threads.Condition +Base.Threads.Event +``` + +See also [Synchronization](@ref lib-task-sync). + +## Atomic operations + +!!! warning + + The API for atomic operations has not yet been finalized and is likely to change. + ```@docs Base.Threads.Atomic Base.Threads.atomic_cas! @@ -31,11 +44,10 @@ Base.Threads.atomic_fence Base.@threadcall ``` -# Low-level synchronization primitives +## Low-level synchronization primitives These building blocks are used to create the regular synchronization objects. ```@docs -Base.Threads.Mutex Base.Threads.SpinLock ``` diff --git a/contrib/html_writer.jl b/contrib/html_writer.jl index e1c316f..138ed03 100644 --- a/contrib/html_writer.jl +++ b/contrib/html_writer.jl @@ -1,5 +1,6 @@ # override Documenter.jl/src/Writers/HTMLWriter.jl +#= import Documenter: Anchors, Builder, Documents, Expanders, Documenter, Utilities, Writers import Documenter.Utilities.DOM: DOM, Tag, @tags import Documenter.Writers.HTMLWriter: pagetitle, domify, open_output @@ -147,3 +148,4 @@ function Documenter.Writers.HTMLWriter.render_article(ctx, navnode) pagenodes = domify(ctx, navnode) article["#docs"](art_header, pagenodes, art_footer) end +=# diff --git a/make.jl b/make.jl index 8c309fb..4c5f977 100644 --- a/make.jl +++ b/make.jl @@ -1,12 +1,12 @@ # code from https://github.com/JuliaLang/julia/blob/master/doc/make.jl # Install dependencies needed to build the documentation. -# empty!(LOAD_PATH) -# push!(LOAD_PATH, @__DIR__, "@stdlib") -# empty!(DEPOT_PATH) -# pushfirst!(DEPOT_PATH, joinpath(@__DIR__, "deps")) -# using Pkg -# Pkg.instantiate() +empty!(LOAD_PATH) +push!(LOAD_PATH, @__DIR__, "@stdlib") +empty!(DEPOT_PATH) +pushfirst!(DEPOT_PATH, joinpath(@__DIR__, "deps")) +using Pkg +Pkg.instantiate() # using Documenter, DocumenterLaTeX using Documenter diff --git a/src/base/multi-threading.md b/src/base/multi-threading.md index 3508bbc..4f3e4e5 100644 --- a/src/base/multi-threading.md +++ b/src/base/multi-threading.md @@ -1,15 +1,28 @@ # [Multi-Threading](@id lib-multithreading) -This experimental interface supports Julia's multi-threading capabilities. Types and functions -described here might (and likely will) change in the future. - ```@docs -Base.Threads.threadid -Base.Threads.nthreads Base.Threads.@threads +Base.Threads.foreach Base.Threads.@spawn +Base.Threads.threadid +Base.Threads.nthreads ``` +## Synchronization + +```@docs +Base.Threads.Condition +Base.Threads.Event +``` + +See also [Synchronization](@ref lib-task-sync). + +## Atomic operations + +!!! warning + + The API for atomic operations has not yet been finalized and is likely to change. + ```@docs Base.Threads.Atomic Base.Threads.atomic_cas! @@ -31,11 +44,10 @@ Base.Threads.atomic_fence Base.@threadcall ``` -# Low-level synchronization primitives +## Low-level synchronization primitives These building blocks are used to create the regular synchronization objects. ```@docs -Base.Threads.Mutex Base.Threads.SpinLock ``` From 64d69636690ffcb87ecea82121e9ad6a9672fad5 Mon Sep 17 00:00:00 2001 From: dentos Date: Wed, 29 Jul 2020 01:13:55 +0900 Subject: [PATCH 125/153] =?UTF-8?q?=ED=95=A8=EC=88=98=20=EB=B6=80=EB=B6=84?= =?UTF-8?q?=20=EB=B2=88=EC=97=AD=20=EB=B0=8F=20=EC=98=A4=ED=83=88=EC=9E=90?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/manual/functions.md | 89 ++++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 49 deletions(-) diff --git a/src/manual/functions.md b/src/manual/functions.md index 88cf799..c8bde0f 100644 --- a/src/manual/functions.md +++ b/src/manual/functions.md @@ -1,6 +1,6 @@ # [함수](@id man-functions) -함수는 인자를 받아 값을 리턴하는 오브젝트이다. 줄리아에서 정의하는 함수는 실행 상황에 영향을 받는다는 점에서 수학적 정의에 따른 함수와는 다르다. 아래는 줄리아에서 함수는 정의하는 가장 기본적인 방법이다: +함수는 인자를 받아 값을 리턴하는 객체이다. Julia에서 정의하는 함수는 실행 상황에 영향을 받는다는 점에서 수학적 정의에 따른 함수와는 다르다. 아래는 Julia에서 함수는 정의하는 가장 기본적인 방법이다: ```jldoctest julia> function f(x,y) @@ -13,15 +13,15 @@ f (generic function with 1 method) julia> f(x,y) = x + y f (generic function with 1 method) ``` -위처럼 "할당 형식(assignment form)"으로 선언할 경우 복합 표현이더라도 한줄로 표현해야 한다([복합 표현을 자세하고 알고 싶다면?](@ref man-compound-expressions)). 이렇게 함수를 표현하는 경우는 줄리아에 흔한 일이고, 때론 코드 가독성을 높여준다. +위처럼 "할당 형식(assignment form)"으로 선언할 경우 복합 표현이더라도 한줄로 표현해야 한다([복합 표현을 자세하고 알고 싶다면?](@ref man-compound-expressions)). 이렇게 함수를 표현하는 경우는 Julia에 흔한 일이고, 때론 코드 가독성을 높여준다. -다른 언어처럼 괄호를 통해 함수 인자를 전달한다: +다른 언어처럼 소괄호를 통해 함수 인자를 전달한다: ```jldoctest fofxy julia> f(2,3) 5 ``` -괄호가 없는 `f`는 함수 오브젝트로써 하나의 값으로 취급할 수 있다: +소괄호가 없는 `f`는 함수 객체로써 하나의 값으로 취급할 수 있다: ```jldoctest fofxy julia> g = f; @@ -40,10 +40,15 @@ julia> ∑(2, 3) ``` ## 인자 전달 방식 -함수에 인자를 줄 때 줄리아는 "공유를 통한 전달([pass-by-sharing](https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing))"을 한다. 이 말은 즉슨, 오브젝트를 복사하지 않고 공유한다는 뜻이다. 전달된 인자는 함수 안에 있는 변수에 할당되고, 함수 안의 변수는 단지 그 오브젝트를 가리킬 뿐이다. `Array`와 같은 mutable 오브젝트가 함수 안에서 변하면, 함수 밖에서도 그 변화를 볼 수 있다. 이런 방식은 Scheme, Python, Ruby, Perl 그리고 대부분의 Lisp와 같은 동적언어가 채택한 방식이다. +함수에 인자를 줄 때 Julia는 "공유를 통한 전달([pass-by-sharing](https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing))"을 한다. +이 말은 즉슨, 객체를 복사하지 않고 공유한다는 뜻이다. +전달된 인자는 함수 안에 있는 변수에 할당되고, 함수 안의 변수는 단지 그 객체를 가리킬 뿐이다. +`Array`와 같은 mutable 객체가 함수 안에서 변하면, 함수 밖에서도 그 변화를 볼 수 있다. +이런 방식은 Scheme, Python, Ruby, Perl 그리고 대부분의 Lisp와 같은 동적언어가 채택한 방식이다. ## 반환값 -함수가 반환하는 값은 암묵적으로 가장 마지막으로 계산된 값이다. 이전의 예제 함수 `f`에서는 `x+y`의 값이 반환될 것이다. 다른 프로그래밍 언어처럼 `return`과 리턴값이 명시적으로 선언될 경우, 함수는 즉시 종료되고 `return`앞에 있는 식을 계산하고 반환할 것이다: +함수가 반환하는 값은 암묵적으로 가장 마지막으로 계산된 값이다. 이전의 예제 함수 `f`에서는 `x+y`의 값이 반환될 것이다. +다른 프로그래밍 언어처럼 `return`과 리턴값이 명시적으로 선언될 경우, 함수는 즉시 종료되고 `return`앞에 있는 식을 계산하고 반환할 것이다: ```julia function g(x,y) @@ -91,7 +96,7 @@ hypot (generic function with 1 method) julia> hypot(3, 4) 5.0 ``` -위 함수는 경우에 따라 세가지 방법으로 값을 반환한다. 마지막은 `return`은 생략해도 된다. +위 함수는 경우에 따라 세가지 방법으로 값을 반환한다. 마지막에 `return`은 생략해도 된다. 반환값의 타입은 `::`로 명시할 수 있으며, 이경우 반환값이 자동 형변환된다. @@ -107,13 +112,11 @@ Int8 위 함수는 `x`와 `y`의 타입에 상관없이 반환값은 `Int8`로 정해져있다. 타입에 대해 자세히 알고 싶다면 [타입 선언](@ref)을 참고하자. -## Operators Are Functions +## 연산자는 함수다 -In Julia, most operators are just functions with support for special syntax. (The exceptions are -operators with special evaluation semantics like `&&` and `||`. These operators cannot be functions -since [Short-Circuit Evaluation](@ref) requires that their operands are not evaluated before evaluation -of the operator.) Accordingly, you can also apply them using parenthesized argument lists, just -as you would any other function: +Julia에서 연산자는 특별한 문법을 가진 함수일 뿐입니다(`&&`와 `||`는 예외다. +이들은 [Short-Circuit Evaluation](@ref)에서 나왔다시피 연산자가 피연산자보다 먼저 계산되기 때문이다). +따라서 연산자는 일반 함수처럼 소괄호를 이용해 인자를 전달할 수 있다: ```jldoctest julia> 1 + 2 + 3 @@ -123,9 +126,8 @@ julia> +(1,2,3) 6 ``` -The infix form is exactly equivalent to the function application form -- in fact the former is -parsed to produce the function call internally. This also means that you can assign and pass around -operators such as [`+`](@ref) and [`*`](@ref) just like you would with other function values: +infix 표기법(`1+2+3`)과 함수 표기법은 같은 결과를 낸다. 실제로 Julia는 내부에서 infix 표기를 함수 표기로 바꿔서 계산하기 때문에 같을 수밖에 없다. +연산자가 함수이기 때문에 다음과 같이 사용할 수도 있다: ```jldoctest julia> f = +; @@ -134,13 +136,13 @@ julia> f(1,2,3) 6 ``` -Under the name `f`, the function does not support infix notation, however. +다만 위처럼 함수 이름이 바뀌면 infix 표기법을 사용할 수 없다. -## Operators With Special Names +## 특별한 이름을 가진 함수 -A few special expressions correspond to calls to functions with non-obvious names. These are: +특정 함수는 호출 대신 특수한 문법으로 대체할 수 있다. 그러한 함수는 다음과 같습니다: -| Expression | Calls | +| 문법 | 함수 이름 | |:----------------- |:----------------------- | | `[A B C ...]` | [`hcat`](@ref) | | `[A; B; C; ...]` | [`vcat`](@ref) | @@ -151,13 +153,12 @@ A few special expressions correspond to calls to functions with non-obvious name | `A.n` | [`getproperty`](@ref Base.getproperty) | | `A.n = x` | [`setproperty!`](@ref Base.setproperty!) | -## [Anonymous Functions](@id man-anonymous-functions) +## [익명 함수](@id man-anonymous-functions) -Functions in Julia are [first-class objects](https://en.wikipedia.org/wiki/First-class_citizen): -they can be assigned to variables, and called using the standard function call syntax from the -variable they have been assigned to. They can be used as arguments, and they can be returned as -values. They can also be created anonymously, without being given a name, using either of these -syntaxes: +Julia에서 함수는 [일급 객체](https://ko.wikipedia.org/wiki/%EC%9D%BC%EA%B8%89_%EA%B0%9D%EC%B2%B4)다: +변수에 값으로 저장될 수 있고, 해당 변수를 함수로 사용할 수 있다. +또 함수 객체는 다른 함수의 인자가 될 수도 있고 반환값이 될 수도 있다. +함수의 이름이 없어도 함수를 다음과 같은 방법으로 정의할 수 있다: ```jldoctest julia> x -> x^2 + 2x - 1 @@ -169,13 +170,11 @@ julia> function (x) #3 (generic function with 1 method) ``` -This creates a function taking one argument `x` and returning the value of the polynomial `x^2 + -2x - 1` at that value. Notice that the result is a generic function, but with a compiler-generated -name based on consecutive numbering. +두 방법 모두 `x`를 받아 `x^2 + 2x - 1`를 반환하는 함수를 만든다. +위와 같은 방식으로 함수를 만들면 함수 이름 대신 컴파일러가 #1, #3과 같은 숫자로 함수를 구분하는 걸 볼 수 있다. -The primary use for anonymous functions is passing them to functions which take other functions -as arguments. A classic example is [`map`](@ref), which applies a function to each value of -an array and returns a new array containing the resulting values: +익명 함수는 함수를 함수 인자로 주면서, 한 번 밖에 사용하지 않을 때 유용하다. +[`map`](@ref)이 그 중 하나로, 배열이 값 각각을 인자로 받는 함수를 받아 반환값으로 새로운 배열을 만든다: ```jldoctest julia> map(round, [1.2,3.5,1.7]) @@ -185,10 +184,8 @@ julia> map(round, [1.2,3.5,1.7]) 2.0 ``` -This is fine if a named function effecting the transform already exists to pass as the first argument -to [`map`](@ref). Often, however, a ready-to-use, named function does not exist. In these -situations, the anonymous function construct allows easy creation of a single-use function object -without needing a name: +위에서는 이미 원하는 함수가 정의되어 있었기 때문에 문제가 없었다. +하지만 그런 함수가 없을 때, 익명 함수를 사용하면 편리하다: ```jldoctest julia> map(x -> x^2 + 2x - 1, [1,3,-1]) @@ -198,18 +195,14 @@ julia> map(x -> x^2 + 2x - 1, [1,3,-1]) -2 ``` -An anonymous function accepting multiple arguments can be written using the syntax `(x,y,z)->2x+y-z`. -A zero-argument anonymous function is written as `()->3`. The idea of a function with no arguments -may seem strange, but is useful for "delaying" a computation. In this usage, a block of code is -wrapped in a zero-argument function, which is later invoked by calling it as `f`. +익명 함수에 다중 인자를 사용하려면 `(x,y,z)->2x+y-z`처럼 쓰면 된다. `()->3`처럼 인자를 받지 않는 함수를 정의할 수도 있다. 처음 프로그래밍을 접하면 "인자를 받지 않는 함수를 왜쓰지?"라고 생각할 수 있지만 코딩을 하다보면 여러모로 유용하다. -## Tuples +## 튜플 -Julia has a built-in data structure called a *tuple* that is closely related to function -arguments and return values. -A tuple is a fixed-length container that can hold any values, but cannot be modified -(it is *immutable*). -Tuples are constructed with commas and parentheses, and can be accessed via indexing: + +줄리아의 *튜플*은 함수의 입출력에 중요하게 관여한다. +튜플은 어떤 값이든 저장할 수 있는 고정 크기의 컨테이너이며, 생성 후에는 수정이 불가능(immutable)하다. +튜플은 반점과 소괄호를 이용해 만들고 인덱싱을 통해 값에 접근한다: ```jldoctest julia> (1, 1+1) @@ -225,9 +218,7 @@ julia> x[2] "hello" ``` -Notice that a length-1 tuple must be written with a comma, `(1,)`, since `(1)` would just -be a parenthesized value. -`()` represents the empty (length-0) tuple. +크기가 1인 튜플을 만들고 싶어도 `(1,)`처럼 꼭 반점을 넣어야 한다. `(1)`은 값을 소괄호로 감싼 것으로 취급된다. `()`은 비어 있는 튜플을 생성한다. ## Named Tuples From 0f99575fabc5ee13bb9eff2e67a74599c82f8df9 Mon Sep 17 00:00:00 2001 From: dentos Date: Wed, 29 Jul 2020 01:26:38 +0900 Subject: [PATCH 126/153] =?UTF-8?q?=EB=8B=A4=EC=B0=A8=EC=9B=90=20=EB=B0=B0?= =?UTF-8?q?=EC=97=B4=20=EB=B2=88=EC=97=AD=ED=88=AC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/manual/arrays.md | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/src/manual/arrays.md b/src/manual/arrays.md index 19f9102..16a7051 100644 --- a/src/manual/arrays.md +++ b/src/manual/arrays.md @@ -1,21 +1,23 @@ # [다차원 배열](@id man-multi-dim-arrays) -대부분의 기술 계산 언어와 마찬가지로, Julia는 일급 배열 구현을 제공한다. -대부분의 기술 계산 언어는 다른 컨테이너를 희생해 가면서도 배열의 구현에 많은 신경을 쓴다. -Julia는 배열을 특별하게 취급하지는 않는다. -배열 라이브러리는 거의 전부 Julia로 작성되었으며, Julia로 쓰여진 다른 코드와 마찬가지로 컴파일러가 퍼포먼스를 결정한다. -따라서 [`AbstractArray`](@ref)로 부터 상속하여 커스텀 배열 타입을 정의하는 것도 가능하다. -커스텀 배열 타입을 구현하는 것의 세부사항은 [manual section on the AbstractArray interface](@ref man-interface-array) 를 참조하기 바란다. - -배열은 다차원 그리드에 저장된 객체들의 모음이다. -가장 일반적인 경우, 배열은 [`Any`](@ref) 타입의 객체들을 담을 수 있다. -대부분의 계산 목적을 위해서는, 배열은 [`Float64`](@ref) 혹은 [`Int32`](@ref)와 같이 더 구체적인 타입의 객체를 담는 것이 좋다. - -다른 많은 기술 계산 언어에서는 성능을 위해 프로그램을 벡터화된 스타일로 작성할 필요가 있지만, Julia에서는 일반적으로 그럴 필요가 없다. -Julia 컴파일러는 타입 추론을 사용하여 스칼라 배열 인덱싱에 최적화된 코드를 생성한다. -따라서 편리하고 읽기 쉬운 스타일로 프로그램을 작성하더라도 성능을 희생하지 않으며, 오히려 메모리를 더 적게 사용하는 경우도 있다. - -줄리아는 함수에 인자를 줄 때 "공유를 통한 전달[pass-by-sharing](https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing)을 한다. 몇몇 프로그래밍 언어는 배열을 값으로 전달하여([pass-by-value](https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_value)), 원치않는 수정을 막지만 무분별한 값의 복사로 인해 속도 지연을 겪을 수 있다. 줄리아는 관습적으로 `!`울 함수 이름의 마지막에 붙여 값이 수정되거나 삭제될 수 있음을 미연에 알려준다([`sort`](@ref)와 [`sort!`](@ref)를 비교해보자). 함수내에서 오브젝트를 수정하지 않으려면 명시적으로 복사를 해야한다. 이렇게 오브젝트를 수정하지 않는 함수는 `!`이 붙여진 동일 이름의 함수와 같은 역할을 하면서 복사된 오브젝트를 반환한다. +Julia는 대부분의 수치 계산용 언어처럼 일급 객체로써 배열 구현을 제공한다. +대부분의 언어는 배열의 구현에 많은 신경을 쓰지만 Julia는 배열을 특별하게 취급하지는 않는다. +배열 관련 라이브러리는 거의 다 Julia로 작성되었으며, Julia 컴파일러가 성능을 좌우한다. +또한 [`AbstractArray`](@ref)를 상속하여 커스텀 배열 타입을 정의하는 것이 가능하다. +커스텀 배열 타입을 구현할 때 필요한 세부사항은 [manual section on the AbstractArray interface](@ref man-interface-array) 를 참조하기 바란다. + +배열은 다차원 그리드(multi-dimensional grid)에 저장된 객체들의 모음이다. +일반으로 배열은 [`Any`](@ref) 타입의 객체들을 담을 수 있다. +수치 계산용으로 사용하려면 배열은 [`Float64`](@ref)이나 [`Int32`](@ref)와 같이 더 구체적인 타입의 객체를 담는 것이 좋다. + +다른 많은 수치 계산용 언어에서는 성능을 위해 프로그램을 벡터화된 스타일로 작성하지만, Julia에서는 대게 그럴 필요가 없다. +Julia 컴파일러는 타입 추론을 통해 스칼라 배열 인덱싱에 최적화된 코드를 생성한다. +따라서 편리하고 읽기 쉬운 스타일로 프로그램을 작성해도 성능이 보존되며, 오히려 메모리를 더 적게 사용하는 경우도 있다. + +줄리아는 함수에 인자를 줄 때 "공유를 통한 전달([pass-by-sharing](https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing))을 한다. +몇몇 프로그래밍 언어는 배열을 값으로 전달하여([pass-by-value](https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_value)), 원치않는 수정을 막지만 무분별한 값의 복사로 인해 속도 지연을 겪을 수 있다. +줄리아는 관습적으로 `!`울 함수 이름의 마지막에 붙여 값이 수정되거나 삭제될 수 있음을 미연에 알려준다([`sort`](@ref)와 [`sort!`](@ref)를 비교해보자). +함수내에서 오브젝트를 수정하지 않으려면 명시적으로 복사를 해야한다. 이렇게 오브젝트를 수정하지 않는 함수는 `!`이 붙여진 동일 이름의 함수와 같은 역할을 하면서 복사된 오브젝트를 반환한다. ## 기본 함수 From 53f44cb189310ecc72db2693f689f719c572ba31 Mon Sep 17 00:00:00 2001 From: dentos Date: Wed, 29 Jul 2020 01:29:56 +0900 Subject: [PATCH 127/153] =?UTF-8?q?=EB=B3=B5=EC=86=8C=EC=88=98=EC=99=80=20?= =?UTF-8?q?=EC=9C=A0=EB=A6=AC=EC=88=98=20=EB=B2=88=EC=97=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/manual/complex-and-rational-numbers.md | 80 +++++++++------------- 1 file changed, 32 insertions(+), 48 deletions(-) diff --git a/src/manual/complex-and-rational-numbers.md b/src/manual/complex-and-rational-numbers.md index 6f2bfaf..372ce4a 100644 --- a/src/manual/complex-and-rational-numbers.md +++ b/src/manual/complex-and-rational-numbers.md @@ -1,23 +1,20 @@ -# Complex and Rational Numbers +# 복소수와 유리수 -Julia includes predefined types for both complex and rational numbers, and supports -all the standard [Mathematical Operations and Elementary Functions](@ref) on them. [Conversion and Promotion](@ref conversion-and-promotion) are defined -so that operations on any combination of predefined numeric types, whether primitive or composite, -behave as expected. +Julia에서는 복소수와 유리수를 표현할 수 있고 [산술 연산과 기본 함수](@ref)를 모두 지원한다. +[Conversion and Promotion](@ref conversion-and-promotion)으로 연산 결과가 수학적으로 예측한 것과 최대한 비슷하게 나오게 했다. -## Complex Numbers +## 복소수 -The global constant [`im`](@ref) is bound to the complex number *i*, representing the principal -square root of -1. (Using mathematicians' `i` or engineers' `j` for this global constant were rejected since they are such popular index variable names.) Since Julia allows numeric literals to be [juxtaposed with identifiers as coefficients](@ref man-numeric-literal-coefficients), -this binding suffices to provide convenient syntax for complex numbers, similar to the traditional -mathematical notation: +전역 상수 [`im`](@ref)는 -1의 루트값으로, 복소수의 허수부 *i*옆에 붙어있다. +(수학자는 `i`로 쓰고 공학자는 `j` 쓰지만, 이 이름은 인덱싱할 때 자주 사용하므로 전역 상수의 이름으로 채택되지 않았다.) +Julia는 [계수와 변수 사이에 곱셈 기호를 생략하는 것](@ref man-numeric-literal-coefficients)을 허용하기 때문에 수학적 표기법을 그대로 사용할 수 있다: ```jldoctest julia> 1+2im 1 + 2im ``` -You can perform all the standard arithmetic operations with complex numbers: +복소수는 산술 연산을 지원한다: ```jldoctest julia> (1 + 2im)*(2 - 3im) @@ -51,7 +48,7 @@ julia> 3(2 - 5im)^-1.0 0.20689655172413796 + 0.5172413793103449im ``` -The promotion mechanism ensures that combinations of operands of different types just work: +타입 자동 치환을 지원하기 때문에 계산 결과가 수학적으로 예상한 것과 동일하다: ```jldoctest julia> 2(1 - 1im) @@ -82,10 +79,9 @@ julia> 1 + 3/4im 1.0 - 0.75im ``` -Note that `3/4im == 3/(4*im) == -(3/4*im)`, since a literal coefficient binds more tightly than -division. +리터럴 계수가 나눗셈보다 중요도가 높으므로 `3/4im == 3/(4*im) == -(3/4*im)`가 되는 걸 볼 수 있다. -Standard functions to manipulate complex values are provided: +복소수를 다루기 위한 기본 함수가 제공된다: ```jldoctest julia> z = 1 + 2im @@ -110,11 +106,10 @@ julia> angle(1 + 2im) # phase angle in radians 1.1071487177940904 ``` -As usual, the absolute value ([`abs`](@ref)) of a complex number is its distance from zero. -[`abs2`](@ref) gives the square of the absolute value, and is of particular use for complex -numbers since it avoids taking a square root. [`angle`](@ref) returns the phase angle in radians -(also known as the *argument* or *arg* function). The full gamut of other [Elementary Functions](@ref) -is also defined for complex numbers: +여기서 [`abs`](@ref)는 일반적으로 아는 복소수의 절댓값을 반환하고, [`abs2`](@ref)는 복소수 절댓값의 제곱값, [`angle`](@ref)은 복소수의 각도를 라디안으로 반환한다. + + +[기본 함수](@ref)는 복소수에서 잘 정의되어 있다: ```jldoctest julia> sqrt(1im) @@ -133,9 +128,7 @@ julia> sinh(1 + 2im) -0.4890562590412937 + 1.4031192506220405im ``` -Note that mathematical functions typically return real values when applied to real numbers and -complex values when applied to complex numbers. For example, [`sqrt`](@ref) behaves differently -when applied to `-1` versus `-1 + 0im` even though `-1 == -1 + 0im`: +수리 계산을 하는 함수에 실수 인자가 들어오면 실수를 반환하고 복소수가 들어오면 복소수를 반환한다. 이런 특성 때문에 [`sqrt`](@ref)는 `-1`이 들어올 때와 `-1 + 0im` 이 들어올 때 `-1 == -1 + 0im` 이어도 결과가 다르게 나오는 걸 확인할 수 있다. ```jldoctest julia> sqrt(-1) @@ -148,26 +141,22 @@ julia> sqrt(-1 + 0im) 0.0 + 1.0im ``` -The [literal numeric coefficient notation](@ref man-numeric-literal-coefficients) does not work when constructing a complex number -from variables. Instead, the multiplication must be explicitly written out: +변수에 저장된 값으로 복소수를 만들 때는 [리터럴 계수 표현법](@ref man-numeric-literal-coefficients)대신 직접적으로 곱셈을 써줘야 한다: ```jldoctest julia> a = 1; b = 2; a + b*im 1 + 2im ``` -However, this is *not* recommended. Instead, use the more efficient [`complex`](@ref) function to construct -a complex value directly from its real and imaginary parts: +하지만 위처럼 복소수를 만드는 것은 추천하지 않는다. [`complex`](@ref)를 사용하는 것이 복소수를 만들 때 효율적이이다. +이렇게 만들면 곱셈과 덧셈 연산자를 사용하지 않는다. ```jldoctest julia> a = 1; b = 2; complex(a, b) 1 + 2im ``` -This construction avoids the multiplication and addition operations. - -[`Inf`](@ref) and [`NaN`](@ref) propagate through complex numbers in the real and imaginary parts -of a complex number as described in the [Special floating-point values](@ref) section: +[특별한 부동 소수점 값들](@ref)에서 소개한 [`Inf`](@ref)과 [`NaN`](@ref)을 복소수에서도 사용할 수 있다: ```jldoctest julia> 1 + Inf*im @@ -177,18 +166,17 @@ julia> 1 + NaN*im 1.0 + NaN*im ``` -## Rational Numbers +## 유리수 -Julia has a rational number type to represent exact ratios of integers. Rationals are constructed -using the [`//`](@ref) operator: +Julia는 정수의 비로 유리수를 표현한다. +유리수는 [`//`](@ref)연산자로 만들 수 있다: ```jldoctest julia> 2//3 2//3 ``` -If the numerator and denominator of a rational have common factors, they are reduced to lowest -terms such that the denominator is non-negative: +분모와 분자가 공통 분모를 가지고 있다면, 이들은 자동으로 상쇄된다: ```jldoctest julia> 6//9 @@ -204,10 +192,8 @@ julia> -4//-12 1//3 ``` -This normalized form for a ratio of integers is unique, so equality of rational values can be -tested by checking for equality of the numerator and denominator. The standardized numerator and -denominator of a rational value can be extracted using the [`numerator`](@ref) and [`denominator`](@ref) -functions: +분자가 분모가 서로인 상태는 유일하며, 두 유리수가 같은지 보려면 각 분자와 분모가 같은지 보면 된다. +유리수의 분자와 분모는 [`numerator`](@ref)와 [`denominator`](@ref)함수로 확인할 수 있다: ```jldoctest julia> numerator(2//3) @@ -217,8 +203,7 @@ julia> denominator(2//3) 3 ``` -Direct comparison of the numerator and denominator is generally not necessary, since the standard -arithmetic and comparison operations are defined for rational values: +비교연산자는 유리수에 대하여 정의되어 있으므로 분자와 분모를 직접 비교할 일은 적을 것이다: ```jldoctest julia> 2//3 == 6//9 @@ -246,15 +231,14 @@ julia> 6//5 / 10//7 21//25 ``` -Rationals can easily be converted to floating-point numbers: +유리수는 쉽게 실수형으로 변환할 수 있다: ```jldoctest julia> float(3//4) 0.75 ``` -Conversion from rational to floating-point respects the following identity for any integral values -of `a` and `b`, with the exception of the case `a == 0` and `b == 0`: +유리수를 실수와 비교할 때는 유리수가 실수로 형 변환을 하고 비교하도록 설계되었다(단, `a == 0`이고 `b == 0`인 경우 제외): ```jldoctest julia> a = 1; b = 2; @@ -263,7 +247,7 @@ julia> isequal(float(a//b), a/b) true ``` -Constructing infinite rational values is acceptable: +유리수를 사용하면 무한대를 다음과 같이 정의할 수 있다: ```jldoctest julia> 5//0 @@ -276,7 +260,7 @@ julia> typeof(ans) Rational{Int64} ``` -Trying to construct a [`NaN`](@ref) rational value, however, is invalid: +하지만 유리수에서 [`NaN`](@ref)를 정의할 수는 없다: ```jldoctest julia> 0//0 @@ -285,7 +269,7 @@ Stacktrace: [...] ``` -As usual, the promotion system makes interactions with other numeric types effortless: +유리수는 타입 승격 시스템(promotion system)으로 쉽게 다른 타입의 숫자와 상호작용 할 수 있다: ```jldoctest julia> 3//5 + 1 From 46a23ddf87c261fa43c37b93a3981f3f3326e5ec Mon Sep 17 00:00:00 2001 From: Dohyeon Lee Date: Sun, 23 Aug 2020 21:58:38 +0900 Subject: [PATCH 128/153] =?UTF-8?q?"index.md"=EC=99=80=20"array.md"=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20-index:=20=EC=82=AC=EC=86=8C=ED=95=9C=20?= =?UTF-8?q?=EB=B2=88=EC=97=AD=20-array:=20"=ED=88=AC=ED=94=8C"->"=ED=8A=9C?= =?UTF-8?q?=ED=94=8C"=20=EB=B3=80=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/index.md | 2 +- src/manual/arrays.md | 23 ++++++++++++----------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/index.md b/src/index.md index aaf1586..fe6040d 100644 --- a/src/index.md +++ b/src/index.md @@ -40,7 +40,7 @@ url = "https://raw.githubusercontent.com/JuliaLang/docs.julialang.org/assets/$(f import Markdown Markdown.parse(""" !!! note - The documentation is also available in PDF format: [$file]($url). + 이 문서를 PDF 형태로 보실 수 있습니다: [$file]($url). """) ``` diff --git a/src/manual/arrays.md b/src/manual/arrays.md index 16a7051..cc2a159 100644 --- a/src/manual/arrays.md +++ b/src/manual/arrays.md @@ -17,7 +17,8 @@ Julia 컴파일러는 타입 추론을 통해 스칼라 배열 인덱싱에 최 줄리아는 함수에 인자를 줄 때 "공유를 통한 전달([pass-by-sharing](https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing))을 한다. 몇몇 프로그래밍 언어는 배열을 값으로 전달하여([pass-by-value](https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_value)), 원치않는 수정을 막지만 무분별한 값의 복사로 인해 속도 지연을 겪을 수 있다. 줄리아는 관습적으로 `!`울 함수 이름의 마지막에 붙여 값이 수정되거나 삭제될 수 있음을 미연에 알려준다([`sort`](@ref)와 [`sort!`](@ref)를 비교해보자). -함수내에서 오브젝트를 수정하지 않으려면 명시적으로 복사를 해야한다. 이렇게 오브젝트를 수정하지 않는 함수는 `!`이 붙여진 동일 이름의 함수와 같은 역할을 하면서 복사된 오브젝트를 반환한다. +함수내에서 객체를 수정하지 않으려면 명시적으로 복사를 해야한다. +이렇게 객체를 수정하지 않는 함수는 `!`이 붙여진 동일 이름의 함수와 같은 역할을 하면서 복사된 객체를 반환한다. ## 기본 함수 @@ -26,18 +27,18 @@ Julia 컴파일러는 타입 추론을 통해 스칼라 배열 인덱싱에 최 | [`eltype(A)`](@ref) | `A` 의 원소 타입 | | [`length(A)`](@ref) | `A` 의 원소 갯수 | | [`ndims(A)`](@ref) | `A` 의 차원수 | -| [`size(A)`](@ref) | `A` 의 크기 투플 | +| [`size(A)`](@ref) | `A` 의 크기 튜플 | | [`size(A,n)`](@ref) | `A` 의 `n` 차원의 크기 | -| [`axes(A)`](@ref) | `A` 의 유효한 인덱스 투플 | +| [`axes(A)`](@ref) | `A` 의 유효한 인덱스 튜플 | | [`axes(A,n)`](@ref) | `A` 의 유효 인덱스 `n`차원 범위(range) | | [`eachindex(A)`](@ref) | `A` 의 모든 위치를 방문하는 효율적인 반복자(iterator) | | [`stride(A,k)`](@ref) | `k` 차원 방향의 스트라이드 (연속한 원소 간의 선형 인덱스 거리) | -| [`strides(A)`](@ref) | 모든 차원의 스트라이드 투플 | +| [`strides(A)`](@ref) | 모든 차원의 스트라이드 튜플 | ## 생성과 초기화 배열을 생성하고 초기화 하는 많은 함수가 있다. -다음에 나열된 함수들에서, `dims...` 인수는 차원의 크기들을 나타내는 투플 하나를 받거나, 혹은 각 차원의 크기를 여러 인수로 받을 수 있다. +다음에 나열된 함수들에서, `dims...` 인수는 차원의 크기들을 나타내는 튜플 하나를 받거나, 혹은 각 차원의 크기를 여러 인수로 받을 수 있다. 이 함수들의 대부분은 첫번째 인수로 배열의 원소 타입 `T`를 받을 수 있다. `T`가 생략되었다면 [`Float64`](@ref)가 기본값이다. @@ -430,7 +431,7 @@ julia> x 1. 스칼라 인덱스. 다음을 포함한다: * 부울이 아닌 정수. - * [`CartesianIndex{N}`](@ref). 여러 차원에 걸쳐있는 정수의 `N`투플처럼 행동한다. (자세한 내용은 아래를 참조.) + * [`CartesianIndex{N}`](@ref). 여러 차원에 걸쳐있는 정수의 `N`튜플처럼 행동한다. (자세한 내용은 아래를 참조.) 2. 스칼라 인덱스의 배열. 다음을 포함한다: * 정수 벡터와 다차원 정수 배열. * `[]`와 같은 빈 배열. 아무 원소도 선택하지 않는다. @@ -487,7 +488,7 @@ julia> A[:, 3] ### 직교 인덱스(Cartesian indices) -`CartesianIndex{N}` 객체는 여러 차원을 포괄하는 정수의 `N`투플처럼 동작하는 스칼라 인덱스를 나타낸다. +`CartesianIndex{N}` 객체는 여러 차원을 포괄하는 정수의 `N`튜플처럼 동작하는 스칼라 인덱스를 나타낸다. ```jldoctest cartesianindex julia> A = reshape(1:32, 4, 4, 2); @@ -808,8 +809,8 @@ julia> broadcast(+, a, b) 사실, `f.(args...)`는 `broadcast(f, args...)`와 동일하며, 어떤 함수든 [점 문법](@ref man-vectorized)을 통하여 편리하게 브로드캐스팅 할 수 있는 문법을 제공한다. 중첩된 "점 호출" `f.(...)`은 (`.+` 등의 연산자도 포함하여) 하나의 `broadcast` 호출로 [자동으로 융합](@ref man-dot-operators)한다. -추가적으로, [`broadcast`](@ref)는 배열에 국한되지 않고 (함수 문서 참조) 투플 또한 지원하며, -배열, 투플, [`Ref`](@ref)([`Ptr`](@ref) 제외)가 아닌 모든 값은 "스칼라"로 취급한다. +추가적으로, [`broadcast`](@ref)는 배열에 국한되지 않고 (함수 문서 참조) 튜플 또한 지원하며, +배열, 튜플, [`Ref`](@ref)([`Ptr`](@ref) 제외)가 아닌 모든 값은 "스칼라"로 취급한다. ```jldoctest julia> convert.(Float32, [1, 2]) @@ -839,13 +840,13 @@ Julia에서 기본 배열 타입은 추상 타입인 [`AbstractArray{T,N}`](@ref `AbstractArray` 타입은 배열과 비슷한 모든 것을 포함하며, 이들의 구현은 전통적인 배열과는 차이가 많이 날 수도 있다. 예를 들어, 원소를 저장하지 않고 요청에 따라서 계산할 수도 있다. -다만 모든 구체적인 `AbstractArray{T,N}` 타입은 일반적으로 적어도 (`Int` 투플을 리턴하는) [`size(A)`](@ref), +다만 모든 구체적인 `AbstractArray{T,N}` 타입은 일반적으로 적어도 (`Int` 튜플을 리턴하는) [`size(A)`](@ref), [`getindex(A,i)`](@ref), 그리고 [`getindex(A,i1,...,iN)`](@ref getindex)를 구현해야 한다. 변경 가능한 배열은 [`setindex!`](@ref)도 구현해야 한다. 이러한 연산들은 대략 상수 시간 복잡도, 엄밀히 말해 Õ(1) 복잡도를 가지도록 구현하는 것이 좋다. 그렇지 않으면 어떤 배열 함수는 생각 이상으로 느릴지도 모른다. 구체적 타입은 [`copy`](@ref)등의 out-of-place 연산에서 유사한 배열을 할당하는데에 쓰일 수 있는 [`similar(A,T=eltype(A),dims=size(A))`](@ref)메소드를 제공해야 한다. -`AbstractArray{T,N}`가 내부적으로 어떻게 표현이 되든, `T` 는 *정수* 인덱싱이 리턴하는 객체(`A` 가 빈 배열이 아닌 경우 `A[1, ..., 1]`)의 타입이며, `N`은 [`size`](@ref)가 리턴하는 투플의 길이여야 한다. +`AbstractArray{T,N}`가 내부적으로 어떻게 표현이 되든, `T` 는 *정수* 인덱싱이 리턴하는 객체(`A` 가 빈 배열이 아닌 경우 `A[1, ..., 1]`)의 타입이며, `N`은 [`size`](@ref)가 리턴하는 튜플의 길이여야 한다. For more details on defining custom `AbstractArray` implementations, see the [array interface guide in the interfaces chapter](@ref man-interface-array). From 8ef403f9e351b17d2dcba9227087a258e1036e6c Mon Sep 17 00:00:00 2001 From: Dohyeon Lee Date: Sun, 23 Aug 2020 22:00:31 +0900 Subject: [PATCH 129/153] tmp commit for functions.md and math-op.md --- src/manual/functions.md | 11 +- src/manual/mathematical-operations.md | 314 ++++++++++++-------------- 2 files changed, 153 insertions(+), 172 deletions(-) diff --git a/src/manual/functions.md b/src/manual/functions.md index c8bde0f..d81c5fe 100644 --- a/src/manual/functions.md +++ b/src/manual/functions.md @@ -674,11 +674,14 @@ julia> ["a", "list", "of", "strings"] .|> [uppercase, reverse, titlecase, length 7 ``` -## [Dot Syntax for Vectorizing Functions](@id man-vectorized) +## [배열에서 사용하는 Dot 문법](@id man-vectorized) -In technical-computing languages, it is common to have "vectorized" versions of functions, which -simply apply a given function `f(x)` to each element of an array `A` to yield a new array via -`f(A)`. This kind of syntax is convenient for data processing, but in other languages vectorization +수치 계산용 언어에서 같은 이름의 함수를 벡터 버전에서 자동으로사용할 수 있게 하는 것은 흔하다. +즉, `f(A)`는 `A`의 모든 원소에 대해 `f(x)`를 반복 계산하여 새로운 배열을 반환할거란 것이다. +이런 문법은 데이터 처리를 편리하게 해주지만 몇몇 언어는 성능 문제를 겪는다: 만약 반복문이 느리면 벡터 버전의 함수는 저급 언어의 반복문을 수동으로 호출해 상황을 해결하는 경우가 있다. +Julia는 성능 향상을 위해 벡터 버전의 함수를 직접 작성할 필요가 거의 없다. + + This kind of syntax is convenient for data processing, but in other languages vectorization is also often required for performance: if loops are slow, the "vectorized" version of a function can call fast library code written in a low-level language. In Julia, vectorized functions are *not* required for performance, and indeed it is often beneficial to write your own loops (see diff --git a/src/manual/mathematical-operations.md b/src/manual/mathematical-operations.md index 6ba2588..a0b5de1 100644 --- a/src/manual/mathematical-operations.md +++ b/src/manual/mathematical-operations.md @@ -1,38 +1,35 @@ -# Mathematical Operations and Elementary Functions +# 산술 연산과 기본 함수 -Julia provides a complete collection of basic arithmetic and bitwise operators across all of its -numeric primitive types, as well as providing portable, efficient implementations of a comprehensive -collection of standard mathematical functions. +Julia가 제공하는 숫자형 타입은 산술 연산자와 비트 연산자, 다양한 수학적 함수를 지원한다. -## Arithmetic Operators +## 산술 연산자 -The following [arithmetic operators](https://en.wikipedia.org/wiki/Arithmetic#Arithmetic_operations) -are supported on all primitive numeric types: +다음 [산술 연산자](https://ko.wikipedia.org/wiki/%EC%82%B0%EC%88%A0#%EC%82%AC%EC%B9%99%EC%97%B0%EC%82%B0)들은 모든 숫자형 타입에 사용할 수 있다: -| Expression | Name | Description | +| 표현식 | 이름 | 설명 | |:---------- |:-------------- |:-------------------------------------- | -| `+x` | unary plus | the identity operation | -| `-x` | unary minus | maps values to their additive inverses | -| `x + y` | binary plus | performs addition | -| `x - y` | binary minus | performs subtraction | -| `x * y` | times | performs multiplication | -| `x / y` | divide | performs division | -| `x ÷ y` | integer divide | x / y, truncated to an integer | -| `x \ y` | inverse divide | equivalent to `y / x` | -| `x ^ y` | power | raises `x` to the `y`th power | -| `x % y` | remainder | equivalent to `rem(x,y)` | - -as well as the negation on [`Bool`](@ref) types: - -| Expression | Name | Description | +| `+x` | 단항 덧셈 | 항등 연산 | +| `-x` | 단항 뺄셈 | 덧셈의 역원 반환 | +| `x + y` | 덧셈 | 일반적인 덧셈 | +| `x - y` | 곱셈 | 일반적인 뺄셈 | +| `x * y` | 곱셈 | 일반적인 곱셈 | +| `x / y` | 나눗셈 | 일반적인 나눗셈 | +| `x ÷ y` | 정수 나눗셈(몫) | `x / y`의 몫 반환 | +| `x \ y` | 역 나눗셈 | `y / x`와 동일 | +| `x ^ y` | 제곱 | `x` 의 `y`제곱을 반환 | +| `x % y` | 나머지 | `rem(x,y)`와 동일(나머지를 반환) | + + +[`Bool`](@ref) 타입에 대한 부정 연산도 가능하다: + +| 표현식 | 이름 | 설명 | |:---------- |:-------- |:---------------------------------------- | -| `!x` | negation | changes `true` to `false` and vice versa | +| `!x` | 부정 연산 | `true`를 `false`로 바꾸거나 혹은 그 반대 | -Julia's promotion system makes arithmetic operations on mixtures of argument types "just work" -naturally and automatically. See [Conversion and Promotion](@ref conversion-and-promotion) for details of the promotion -system. +줄리아의 타입 치환 시스템은 산술 연산이 자연스럽게 작동하게 한다. +자세한 것은 [Conversion and Promotion](@ref conversion-and-promotion)을 참고하라. -Here are some simple examples using arithmetic operators: +산술 연산자를 활용한 간단한 예제다: ```jldoctest julia> 1 + 2 + 3 @@ -45,26 +42,24 @@ julia> 3*2/12 0.5 ``` -(By convention, we tend to space operators more tightly if they get applied before other nearby -operators. For instance, we would generally write `-x + 2` to reflect that first `x` gets negated, -and then `2` is added to that result.) +(일반적으로 근처 다른 연산자보다 먼저 적용되는 경우 간격을 밀접하게 두는 경우가 있다. +예를 들어 `x`를 음수로 먼저 변환하고 `2`를 반환하는 코드는 편의상 `-x + 2`로 쓴다) -## Bitwise Operators +## 비트 연산자 -The following [bitwise operators](https://en.wikipedia.org/wiki/Bitwise_operation#Bitwise_operators) -are supported on all primitive integer types: +[비트 연산자](https://ko.wikipedia.org/wiki/%EB%B9%84%ED%8A%B8_%EC%97%B0%EC%82%B0)는 모든 기본 정수형 타입을 지원한다: | Expression | Name | |:---------- |:------------------------------------------------------------------------ | -| `~x` | bitwise not | -| `x & y` | bitwise and | -| `x \| y` | bitwise or | -| `x ⊻ y` | bitwise xor (exclusive or) | +| `~x` | 비트 부정 | +| `x & y` | 비트 and 연산 | +| `x \| y` | 비트 or 연산 | +| `x ⊻ y` | 비트 xor 연산 (exclusive or) | | `x >>> y` | [logical shift](https://en.wikipedia.org/wiki/Logical_shift) right | | `x >> y` | [arithmetic shift](https://en.wikipedia.org/wiki/Arithmetic_shift) right | | `x << y` | logical/arithmetic shift left | -Here are some examples with bitwise operators: +비트 연산자를 활용한 간단한 예제다: ```jldoctest julia> ~123 @@ -89,12 +84,12 @@ julia> ~UInt8(123) 0x84 ``` -## Updating operators +## 업데이트 연산자 -Every binary arithmetic and bitwise operator also has an updating version that assigns the result -of the operation back into its left operand. The updating version of the binary operator is formed -by placing a `=` immediately after the operator. For example, writing `x += 3` is equivalent to -writing `x = x + 3`: +산술 연산자와 비트 연산자는 그에 대응하는 업데이트 연산자가 있습니다. +업데이트 연산자는 변수의 값과 새롭게 제시된 피연산자로 계산한 후 결과를 다시 해당 변수에 저장합니다. +업데이트 연산자는 기존 연산자 기호 우측에 `=`를 붙임으로써 만들 수 있습니다. +예를 들어 `x += 3`는 `x = x + 3`와 같은 의미가 됩니다: ```jldoctest julia> x = 1 @@ -107,15 +102,14 @@ julia> x 4 ``` -The updating versions of all the binary arithmetic and bitwise operators are: +각 산술/비트 연산자에 대응하는 업데이트 연산자는 아래와 같습니다: ``` += -= *= /= \= ÷= %= ^= &= |= ⊻= >>>= >>= <<= ``` !!! note - An updating operator rebinds the variable on the left-hand side. As a result, the type of the - variable may change. + Julia는 상황에 따라 타입을 바꾸기 때문에, 업데이트 연산자가 변수의 타입을 바꿀 수 있다. ```jldoctest julia> x = 0x01; typeof(x) @@ -128,17 +122,11 @@ The updating versions of all the binary arithmetic and bitwise operators are: Int64 ``` -## [Vectorized "dot" operators](@id man-dot-operators) +## [배열에서의 연산("dot" 연산자)](@id man-dot-operators) -For *every* binary operation like `^`, there is a corresponding -"dot" operation `.^` that is *automatically* defined -to perform `^` element-by-element on arrays. For example, -`[1,2,3] ^ 3` is not defined, since there is no standard -mathematical meaning to "cubing" a (non-square) array, but -`[1,2,3] .^ 3` is defined as computing the elementwise -(or "vectorized") result `[1^3, 2^3, 3^3]`. Similarly for unary -operators like `!` or `√`, there is a corresponding `.√` that -applies the operator elementwise. +`^`와 같은 모든 이진 연산자는 배열의 원소별 연산을 위한 "dot" 연산자 `.^`가 있다. +따라서 `[1,2,3]`의 모든 원소를 세제곱 하고 싶다면 `[1,2,3] ^ 3`이 아니라 `[1,2,3] .^ 3`로 작성해야 한다. +`!`같은 단항 연산자도 사용할 수 있다(`.!`). ```jldoctest julia> [1,2,3] .^ 3 @@ -146,49 +134,44 @@ julia> [1,2,3] .^ 3 1 8 27 + +julia> .![true,false,true] +3-element BitArray{1}: + 0 + 1 + 0 ``` -More specifically, `a .^ b` is parsed as the ["dot" call](@ref man-vectorized) -`(^).(a,b)`, which performs a [broadcast](@ref Broadcasting) operation: -it can combine arrays and scalars, arrays of the same size (performing -the operation elementwise), and even arrays of different shapes (e.g. -combining row and column vectors to produce a matrix). Moreover, like -all vectorized "dot calls," these "dot operators" are -*fusing*. For example, if you compute `2 .* A.^2 .+ sin.(A)` (or -equivalently `@. 2A^2 + sin(A)`, using the [`@.`](@ref @__dot__) macro) for -an array `A`, it performs a *single* loop over `A`, computing `2a^2 + sin(a)` -for each element of `A`. In particular, nested dot calls like `f.(g.(x))` -are fused, and "adjacent" binary operators like `x .+ 3 .* x.^2` are -equivalent to nested dot calls `(+).(x, (*).(3, (^).(x, 2)))`. +보다 구체적으로, `a .^ b`는 `(^).(a,b)`로 해석되고, 여기서 [`.`](@ref man-vectorized)은 [broadcast](@ref Broadcasting) 연산을 한다: broadcast 연산은 배열과 스칼라, 배열과 배열(모양이 달라도 됨)을 원소별 연산이 가능하게 같은 모양의 배열로 "적절히" 바꿔준다(예를 들어 row 벡터와 column 백터가 들어오면 행렬을 생성한다). +또한 "dot" 연산자는 근처 다른 "dot" 연산자와 결합하여 반복문을 한번만 돌리도록 설계되었다. +만약 `2 .* A.^2 .+ sin.(A)`(혹은 [`@.`](@ref @__dot__) macro)을 사용하여 `@. 2A^2 + sin(A)`를 계산한다면, Julia는 `A`의 모든 원소에 대해 `2a^2 + sin(a)`를 계산한다. +`f.(g.(x))`같은 nested dot 호출도 이런 최적화가 일어나기 때문에 `x .+ 3 .* x.^2`와 `(+).(x, (*).(3, (^).(x, 2)))`같은 함수 꼴로 사용해도 성능상 차이가 발생하지 않는다. Furthermore, "dotted" updating operators like `a .+= b` (or `@. a += b`) are parsed as `a .= a .+ b`, where `.=` is a fused *in-place* assignment operation (see the [dot syntax documentation](@ref man-vectorized)). -Note the dot syntax is also applicable to user-defined operators. -For example, if you define `⊗(A,B) = kron(A,B)` to give a convenient -infix syntax `A ⊗ B` for Kronecker products ([`kron`](@ref)), then -`[A,B] .⊗ [C,D]` will compute `[A⊗C, B⊗D]` with no additional coding. +dot 연산자는 사용자 정의 연산자에서도 활용할 수 있다. +예를 들어 `⊗(A,B) = kron(A,B)`를 정의했다면 `[A,B] .⊗ [C,D]`은 `[A⊗C, B⊗D]`를 계산한다. -Combining dot operators with numeric literals can be ambiguous. -For example, it is not clear whether `1.+x` means `1. + x` or `1 .+ x`. -Therefore this syntax is disallowed, and spaces must be used around -the operator in such cases. +dot 연산자를 숫자형 리터럴과 혼용하는 것은 해석의 모호성을 야기할 수 있다. +예를 들어 `1.+x`은 `1. + x`인지 `1 .+ x`인지 확실하지 않다. +따라서 이런 문법은 지원하지 않으며, 불가피하게 사용할 시 여백으로 문법을 명확히 해야한다. -## Numeric Comparisons +## 비교 연산 -Standard comparison operations are defined for all the primitive numeric types: +모든 기본 숫자형 타입은 비교연산을 지원한다(복소수 예외): -| Operator | Name | +| 연산자 | 설명 | |:---------------------------- |:------------------------ | -| [`==`](@ref) | equality | -| [`!=`](@ref), [`≠`](@ref !=) | inequality | -| [`<`](@ref) | less than | -| [`<=`](@ref), [`≤`](@ref <=) | less than or equal to | -| [`>`](@ref) | greater than | -| [`>=`](@ref), [`≥`](@ref >=) | greater than or equal to | +| [`==`](@ref) | 상등 | +| [`!=`](@ref), [`≠`](@ref !=) | 상등 부정 | +| [`<`](@ref) | 작다 | +| [`<=`](@ref), [`≤`](@ref <=) | 작거나 같다 | +| [`>`](@ref) | 크다 | +| [`>=`](@ref), [`≥`](@ref >=) | 크거나 같다 | -Here are some simple examples: +아래 예제로 사용법을 볼 수 있다: ```jldoctest julia> 1 == 1 @@ -225,16 +208,16 @@ julia> 3 < -0.5 false ``` -Integers are compared in the standard manner -- by comparison of bits. Floating-point numbers -are compared according to the [IEEE 754 standard](https://en.wikipedia.org/wiki/IEEE_754-2008): +정수에서 비교연산은 같은 위치의 비트를 비교하는 방식으로 이뤄진다. +반면 실수는 [IEEE 754 standard](https://ko.wikipedia.org/wiki/IEEE_754)의 규칙에 따라 비교한다: - * Finite numbers are ordered in the usual manner. - * Positive zero is equal but not greater than negative zero. - * `Inf` is equal to itself and greater than everything else except `NaN`. - * `-Inf` is equal to itself and less then everything else except `NaN`. - * `NaN` is not equal to, not less than, and not greater than anything, including itself. + * 유한한 수는 일반적인 방식으로 이뤄진다. + * +0과 -0은 서로 같다. + * `Inf` 는 `NaN`와 자신을 제외한 수보다 크고, 자기 자신과는 같다. + * `Inf` 는 `NaN`와 자신을 제외한 수보다 작고, 자기 자신과는 같다. + * `NaN` 는 자신을 포함한 그 어떤 수와 같지 않고, 크지도 않고, 작지도 않다. -The last point is potentially surprising and thus worth noting: +마지막 규칙은 다른 규칙보다 극단적이라, 실제 계산에서 예상치 못한 결과를 야기할 수 있다: ```jldoctest julia> NaN == NaN @@ -250,24 +233,23 @@ julia> NaN > NaN false ``` -and can cause especial headaches with [arrays](@ref man-multi-dim-arrays): +이러한 문제는 특히 [배열](@ref man-multi-dim-arrays)을 다룰 때 골머리를 썩게 할 것이다: ```jldoctest julia> [1 NaN] == [1 NaN] false ``` -Julia provides additional functions to test numbers for special values, which can be useful in -situations like hash key comparisons: +Julia는 해시값처럼 특수한 값에도 비교연산을 사용할 수 있도록 함수를 지원한다: -| Function | Tests if | +| 함수 | 반환값이 참인 조건 | |:----------------------- |:------------------------- | -| [`isequal(x, y)`](@ref) | `x` and `y` are identical | -| [`isfinite(x)`](@ref) | `x` is a finite number | -| [`isinf(x)`](@ref) | `x` is infinite | -| [`isnan(x)`](@ref) | `x` is not a number | +| [`isequal(x, y)`](@ref) | `x`와 `y` 가 같은 때 | +| [`isfinite(x)`](@ref) | `x`가 유한한 수일 대 | +| [`isinf(x)`](@ref) | `x`가 무한한 수일 때 | +| [`isnan(x)`](@ref) | `x`가 숫자가 아닐 때 | -[`isequal`](@ref) considers `NaN`s equal to each other: +[`isequal`](@ref)에서 `NaN`이 서로 같다고 나온다: ```jldoctest julia> isequal(NaN, NaN) @@ -280,7 +262,7 @@ julia> isequal(NaN, NaN32) true ``` -`isequal` can also be used to distinguish signed zeros: +`isequal`은 +0과 -0을 구분할 때도 사용할 수 있다: ```jldoctest julia> -0.0 == 0.0 @@ -290,25 +272,25 @@ julia> isequal(-0.0, 0.0) false ``` -Mixed-type comparisons between signed integers, unsigned integers, and floats can be tricky. A -great deal of care has been taken to ensure that Julia does them correctly. +정수의 signed나 unsigned 혹은 실수 사이의 비교연산은 까다롭습니다. +Julia는 타입 충돌 없이 이런 것들이 잘 작동하게 보장합니다. -For other types, `isequal` defaults to calling [`==`](@ref), so if you want to define -equality for your own types then you only need to add a [`==`](@ref) method. If you define -your own equality function, you should probably define a corresponding [`hash`](@ref) method -to ensure that `isequal(x,y)` implies `hash(x) == hash(y)`. +서로 다른 타입에서 `isequal`을 사용하면 [`==`](@ref)을 호출하게 되어있습니다. +여러분이 나만의 타입에서 동일성을 정의하고 싶다면 [`==`](@ref) method를 정의하면 됩니다. +여기에 [`hash`](@ref) method도 정의하면 `isequal(x,y)`은 `hash(x) == hash(y)`을 반환합니다. -### Chaining comparisons +### 비교연산 이어쓰기 -Unlike most languages, with the [notable exception of Python](https://en.wikipedia.org/wiki/Python_syntax_and_semantics#Comparison_operators), -comparisons can be arbitrarily chained: +대부분의 언어가 지원하지 않지만, [Python의 비교연산 문법](https://en.wikipedia.org/wiki/Python_syntax_and_semantics#Comparison_operators)처럼 비교연산을 이어쓸 수 있다: ```jldoctest julia> 1 < 2 <= 2 < 3 == 3 > 2 >= 1 == 1 < 3 != 5 true ``` -Chaining comparisons is often quite convenient in numerical code. Chained comparisons use the +비교연산 이어쓰기는 코드 구성을 깔끔하게 한다. +비교연산 이어쓰기는 `&&`을 사용하여 비교연산을 한 것과 똑같이 작동하며, 원소별 연산끼리는 [`&`](@ref)연산이 적용된다.(???) +Chained comparisons use the `&&` operator for scalar comparisons, and the [`&`](@ref) operator for elementwise comparisons, which allows them to work on arrays. For example, `0 .< A .< 1` gives a boolean array whose entries are true where the corresponding elements of `A` are between 0 and 1. @@ -337,48 +319,46 @@ comparison is undefined. It is strongly recommended not to use expressions with as printing) in chained comparisons. If side effects are required, the short-circuit `&&` operator should be used explicitly (see [Short-Circuit Evaluation](@ref)). -### Elementary Functions +### 기본 함수 -Julia provides a comprehensive collection of mathematical functions and operators. These mathematical -operations are defined over as broad a class of numerical values as permit sensible definitions, -including integers, floating-point numbers, rationals, and complex numbers, -wherever such definitions make sense. +Julia는 수치 계산을 위한 함수와 연산자를 전폭적으로 지원한다. +이런 연산은 서로 다른 타입의 숫자(정수, 실수, 유리수 등)가 충돌없이 수학적인 결과와 맞아 떨어지게끔 되어있다. -Moreover, these functions (like any Julia function) can be applied in "vectorized" fashion to -arrays and other collections with the [dot syntax](@ref man-vectorized) `f.(A)`, -e.g. `sin.(A)` will compute the sine of each element of an array `A`. +이런 함수 모두 [dot 문법](@ref man-vectorized)을 지원한다. +예를 들어 `sin.(A)`는 array의 모든 `A`의 원소의 sin값을 구한다. -## Operator Precedence and Associativity +## 연산자 우선순위와 결합성 -Julia applies the following order and associativity of operations, from highest precedence to lowest: +아래 표는 높은 우선 순위부터 낮은 우선순위별로 연산자를 나열하고, [연산자 결합성](@https://en.wikipedia.org/wiki/Operator_associativity)을 확인할 수 있다: -| Category | Operators | Associativity | +| 분류 | 연산자 | 결합성 | |:-------------- |:------------------------------------------------------------------------------------------------- |:-------------------------- | -| Syntax | `.` followed by `::` | Left | -| Exponentiation | `^` | Right | -| Unary | `+ - √` | Right[^1] | -| Bitshifts | `<< >> >>>` | Left | -| Fractions | `//` | Left | -| Multiplication | `* / % & \ ÷` | Left[^2] | -| Addition | `+ - \| ⊻` | Left[^2] | -| Syntax | `: ..` | Left | -| Syntax | `\|>` | Left | -| Syntax | `<\|` | Right | -| Comparisons | `> < >= <= == === != !== <:` | Non-associative | -| Control flow | `&&` followed by `\|\|` followed by `?` | Right | -| Pair | `=>` | Right | -| Assignments | `= += -= *= /= //= \= ^= ÷= %= \|= &= ⊻= <<= >>= >>>=` | Right | +| 문법 | `.` followed by `::` | 왼쪽 | +| 제곱 | `^` | 오른쪽 | +| 단항 연산 | `+ - √` | 오른쪽[^1] | +| Bitshifts | `<< >> >>>` | 왼쪽 | +| 분수 | `//` | 왼쪽 | +| 곱셈, 나눗셈 | `* / % & \ ÷` | 왼쪽[^2] | +| 덧셈, 뺄셈 | `+ - \| ⊻` | 왼쪽[^2] | +| 문법 | `: ..` | 왼쪽 | +| 문법 | `\|>` | 왼쪽 | +| 문법 | `<\|` | 오른쪽 | +| 비교 연산 | `> < >= <= == === != !== <:` | 결합성 없음 | +| 제어 흐름 | `&&` followed by `\|\|` followed by `?` | 오른쪽 | +| Pair | `=>` | 오른쪽 | +| 할당 | `= += -= *= /= //= \= ^= ÷= %= \|= &= ⊻= <<= >>= >>>=` | 오른쪽 | [^1]: - The unary operators `+` and `-` require explicit parentheses around their argument to disambiguate them from the operator `++`, etc. Other compositions of unary operators are parsed with right-associativity, e. g., `√√-a` as `√(√(-a))`. + 단항연산자 `+` 와 `-`를 연속해서 사용하는 경우, 업데이트 연산자(`++`)와 구별하기 위해 괄호를 명시적으로 사용해야 한다. 다른 단항 연산자와 같이 사용하는 경우엔 right-associativity + `+` and `-` require explicit parentheses around their argument to disambiguate them from the operator `++`, etc. Other compositions of unary operators are parsed with right-associativity, e. g., `√√-a` as `√(√(-a))`. [^2]: The operators `+`, `++` and `*` are non-associative. `a + b + c` is parsed as `+(a, b, c)` not `+(+(a, b), c)`. However, the fallback methods for `+(a, b, c, d...)` and `*(a, b, c, d...)` both default to left-associative evaluation. -For a complete list of *every* Julia operator's precedence, see the top of this file: +모든 Julia 연산자의 우선순위 목록을 보고 싶다면, 다음 파일의 최상단 코드를 참고하라: [`src/julia-parser.scm`](https://github.com/JuliaLang/julia/blob/master/src/julia-parser.scm) -You can also find the numerical precedence for any given operator via the built-in function `Base.operator_precedence`, where higher numbers take precedence: +`Base.operator_precedence`을 통해서도 우선순위를 확인할 수 있다. 반환값이 높을수록 더 우선순위가 더 높다: ```jldoctest julia> Base.operator_precedence(:+), Base.operator_precedence(:*), Base.operator_precedence(:.) @@ -388,7 +368,7 @@ julia> Base.operator_precedence(:sin), Base.operator_precedence(:+=), Base.opera (0, 1, 1) ``` -A symbol representing the operator associativity can also be found by calling the built-in function `Base.operator_associativity`: +연산자 결합성 확인은 `Base.operator_associativity`로 확인할 수 있다: ```jldoctest julia> Base.operator_associativity(:-), Base.operator_associativity(:+), Base.operator_associativity(:^) @@ -398,8 +378,8 @@ julia> Base.operator_associativity(:⊗), Base.operator_associativity(:sin), Bas (:left, :none, :right) ``` -Note that symbols such as `:sin` return precedence `0`. This value represents invalid operators and not -operators of lowest precedence. Similarly, such operators are assigned associativity `:none`. +`:sin`의 경우 우선순위가 `0`임을 확인할 수 있는데, `0`은 최하위 우선순위가 아니라 유효하지 않은 연사자를 나타낸다. +이와 비슷한 이유로 이런 연산자는 연산자 결합성이 `:none`임을 볼 수 있다. ## Numerical Conversions @@ -458,9 +438,9 @@ Stacktrace: See [Conversion and Promotion](@ref conversion-and-promotion) for how to define your own conversions and promotions. -### Rounding functions +### Rounding 함수 -| Function | Description | Return type | +| 함수 | 설명 | 반환값 | |:--------------------- |:-------------------------------- |:----------- | | [`round(x)`](@ref) | round `x` to the nearest integer | `typeof(x)` | | [`round(T, x)`](@ref) | round `x` to the nearest integer | `T` | @@ -471,9 +451,9 @@ See [Conversion and Promotion](@ref conversion-and-promotion) for how to define | [`trunc(x)`](@ref) | round `x` towards zero | `typeof(x)` | | [`trunc(T, x)`](@ref) | round `x` towards zero | `T` | -### Division functions +### 나눗셈 함수 -| Function | Description | +| 함수 | 설명 | |:------------------------- |:--------------------------------------------------------------------------------------------------------- | | [`div(x,y)`](@ref), `x÷y` | truncated division; quotient rounded towards zero | | [`fld(x,y)`](@ref) | floored division; quotient rounded towards `-Inf` | @@ -487,20 +467,20 @@ See [Conversion and Promotion](@ref conversion-and-promotion) for how to define | [`gcd(x,y...)`](@ref) | greatest positive common divisor of `x`, `y`,... | | [`lcm(x,y...)`](@ref) | least positive common multiple of `x`, `y`,... | -### Sign and absolute value functions +### 부호 함수와 절댓값 함수 -| Function | Description | +| 함수 | 설명 | |:----------------------- |:---------------------------------------------------------- | -| [`abs(x)`](@ref) | a positive value with the magnitude of `x` | -| [`abs2(x)`](@ref) | the squared magnitude of `x` | -| [`sign(x)`](@ref) | indicates the sign of `x`, returning -1, 0, or +1 | -| [`signbit(x)`](@ref) | indicates whether the sign bit is on (true) or off (false) | +| [`abs(x)`](@ref) | `x`의 절댓값 | +| [`abs2(x)`](@ref) | `x`절댓값의 제곱 | +| [`sign(x)`](@ref) | `x`의 부호. -1, 0, 혹은 +1를 반환 | +| [`signbit(x)`](@ref) | sign bit가 1인지(true) 혹은 0인지(false)인지 반환 | | [`copysign(x,y)`](@ref) | a value with the magnitude of `x` and the sign of `y` | | [`flipsign(x,y)`](@ref) | a value with the magnitude of `x` and the sign of `x*y` | -### Powers, logs and roots +### 지수, 로그, 루트 함수 -| Function | Description | +| 함수 | 설명 | |:------------------------ |:-------------------------------------------------------------------------- | | [`sqrt(x)`](@ref), `√x` | square root of `x` | | [`cbrt(x)`](@ref), `∛x` | cube root of `x` | @@ -520,9 +500,9 @@ For an overview of why functions like [`hypot`](@ref), [`expm1`](@ref), and [`lo are necessary and useful, see John D. Cook's excellent pair of blog posts on the subject: [expm1, log1p, erfc](https://www.johndcook.com/blog/2010/06/07/math-library-functions-that-seem-unnecessary/), and [hypot](https://www.johndcook.com/blog/2010/06/02/whats-so-hard-about-finding-a-hypotenuse/). -### Trigonometric and hyperbolic functions +### 삼각 함수와 쌍곡선 함수 -All the standard trigonometric and hyperbolic functions are also defined: +Julia는 모든 삼각 함수와 쌍곡선 함수를 지원한다: ``` sin cos tan cot sec csc @@ -532,22 +512,20 @@ asinh acosh atanh acoth asech acsch sinc cosc ``` -These are all single-argument functions, with [`atan`](@ref) also accepting two arguments -corresponding to a traditional [`atan2`](https://en.wikipedia.org/wiki/Atan2) function. +이 함수들은 인자를 하나만 받지만, 예외적으로 [`atan`](@ref)는 2개를 받을 수 있으며 이는 [`atan2`](https://en.wikipedia.org/wiki/Atan2)에 대응한다. -Additionally, [`sinpi(x)`](@ref) and [`cospi(x)`](@ref) are provided for more accurate computations -of [`sin(pi*x)`](@ref) and [`cos(pi*x)`](@ref) respectively. +추가로 [`sinpi(x)`](@ref)와 [`cospi(x)`](@ref)는 [`sin(pi*x)`](@ref), [`cos(pi*x)`](@ref)와 결과는 비슷지만 더 정확한 결과를 산출할 수 있다. -In order to compute trigonometric functions with degrees instead of radians, suffix the function -with `d`. For example, [`sind(x)`](@ref) computes the sine of `x` where `x` is specified in degrees. -The complete list of trigonometric functions with degree variants is: +삼각 함수 단위에 호도법(radian)대신 도(°)를 사용하려면 접미사 `d`를 붙인다. +예를 들어 [`sind(x)`](@ref)는 `x`°의 sin값을 구한다. +아래는 접미사 `d`를 사용한 모든 삼각 함수를 나열했다: ``` sind cosd tand cotd secd cscd asind acosd atand acotd asecd acscd ``` -### Special functions +### 특수 함수 -Many other special mathematical functions are provided by the package +이외에도 다양한 수치 계산용 함수를 패키지로 받을 수 있다 [SpecialFunctions.jl](https://github.com/JuliaMath/SpecialFunctions.jl). From ac382244a70c3894643a8e3cbd5cdb6f2bf6919f Mon Sep 17 00:00:00 2001 From: Dohyeon Lee Date: Thu, 27 Aug 2020 13:46:47 +0900 Subject: [PATCH 130/153] =?UTF-8?q?=ED=95=A8=EC=88=98(=EC=9D=BC=EB=B6=80),?= =?UTF-8?q?=20=EC=9A=B4=EC=98=81=EC=B2=B4=EC=A0=9C(=EC=A0=84=EB=B6=80),=20?= =?UTF-8?q?=EA=B8=B0=EC=B4=88=20=EC=97=B0=EC=82=B0(=EC=9D=BC=EB=B6=80)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/manual/functions.md | 22 ++++++---------- .../handling-operating-system-variation.md | 19 ++++++-------- src/manual/mathematical-operations.md | 25 ++++++++----------- 3 files changed, 25 insertions(+), 41 deletions(-) diff --git a/src/manual/functions.md b/src/manual/functions.md index d81c5fe..f99fbd9 100644 --- a/src/manual/functions.md +++ b/src/manual/functions.md @@ -676,18 +676,12 @@ julia> ["a", "list", "of", "strings"] .|> [uppercase, reverse, titlecase, length ## [배열에서 사용하는 Dot 문법](@id man-vectorized) -수치 계산용 언어에서 같은 이름의 함수를 벡터 버전에서 자동으로사용할 수 있게 하는 것은 흔하다. -즉, `f(A)`는 `A`의 모든 원소에 대해 `f(x)`를 반복 계산하여 새로운 배열을 반환할거란 것이다. -이런 문법은 데이터 처리를 편리하게 해주지만 몇몇 언어는 성능 문제를 겪는다: 만약 반복문이 느리면 벡터 버전의 함수는 저급 언어의 반복문을 수동으로 호출해 상황을 해결하는 경우가 있다. -Julia는 성능 향상을 위해 벡터 버전의 함수를 직접 작성할 필요가 거의 없다. - - This kind of syntax is convenient for data processing, but in other languages vectorization -is also often required for performance: if loops are slow, the "vectorized" version of a function -can call fast library code written in a low-level language. In Julia, vectorized functions are -*not* required for performance, and indeed it is often beneficial to write your own loops (see -[Performance Tips](@ref man-performance-tips)), but they can still be convenient. Therefore, *any* Julia function -`f` can be applied elementwise to any array (or other collection) with the syntax `f.(A)`. -For example, `sin` can be applied to all elements in the vector `A` like so: +수치 계산용 언어에서는 함수의 스칼라 버전이 존재하면 벡터 버전이 자동 지원되는 것은 흔하다. +즉 `f(x)`가 있으면 이를 행렬의 모든 원소에 적용하는 `f(A)`가 지원되기 마련이다. +이런 문법은 데이터 처리를 편리하게 하지만, 몇몇 언어는 성능면에서 문제를 겪어 사용자가 직접 저급 언어의 라이브러리를 사용해 벡터 버전의 함수를 만들기도 한다. +Julia는 성능 향상을 위해 이런 노력을 할 필요가 없다. +모든 Julia 함수 `f`는 `f.(A)`이란 문법을 사용해 원소별 연산이 가능하다. +예를 들어 `sin`로 벡터 `A`를 쉽게 계산할 수 있다: ```jldoctest julia> A = [1.0, 2.0, 3.0] @@ -703,9 +697,7 @@ julia> sin.(A) 0.1411200080598672 ``` -Of course, you can omit the dot if you write a specialized "vector" method of `f`, e.g. via `f(A::AbstractArray) = map(f, A)`, -and this is just as efficient as `f.(A)`. But that approach requires you to decide in advance -which functions you want to vectorize. +물론 사용자가 `f(A::AbstractArray) = map(f, A)`와 같이 직접 벡터 함수를 만드는 것도 가능하고 `f.(A)`만큼 효율적이다. More generally, `f.(args...)` is actually equivalent to `broadcast(f, args...)`, which allows you to operate on multiple arrays (even of different shapes), or a mix of arrays and scalars (see diff --git a/src/manual/handling-operating-system-variation.md b/src/manual/handling-operating-system-variation.md index 026d7df..8c3a644 100644 --- a/src/manual/handling-operating-system-variation.md +++ b/src/manual/handling-operating-system-variation.md @@ -1,10 +1,8 @@ -# Handling Operating System Variation +# 운영체제 변수 다루기 -When writing cross-platform applications or libraries, it is often necessary to allow for -differences between operating systems. The variable `Sys.KERNEL` can be used to handle such -cases. There are several functions in the `Sys` module intended to make this easier, such as -`isunix`, `islinux`, `isapple`, `isbsd`, `isfreebsd`, and `iswindows`. These may be used -as follows: +크로스 플랫폼(cross-plaform) 어플리케이션이나 라이브러리 설계는 운영체제 간의 작동방식을 다르게 할 필요가 생기기도 하다. +`Sys.KERNEL` 변수는 이런 상황을 다룰 때 사용한다. +`Sys` 모듈은 `Sys.KERNEL`변수를 더 편리하게 사용하기 위해 `isunix`, `islinux`, `isapple`, `isbsd`, `isfreebsd`, `iswindows`같은 함수를 지원한다: ```julia if Sys.iswindows() @@ -12,9 +10,9 @@ if Sys.iswindows() end ``` -Note that `islinux`, `isapple`, and `isfreebsd` are mutually exclusive subsets of `isunix`. -Additionally, there is a macro `@static` which makes it possible to use these functions to -conditionally hide invalid code, as demonstrated in the following examples. +`islinux`, `isapple`,`isfreebsd`은 `isunix`의 상호 배타적 부분 집합이다. + +`@static` 매크로를 사용하여 특정 조건을 만족하지 않으면 함수를 실행하지 못하게 할 수 있다: Simple blocks: @@ -32,8 +30,7 @@ else end ``` -When chaining conditionals (including `if`/`elseif`/`end`), the `@static` must be repeated for -each level (parentheses optional, but recommended for readability): +조건문을 여럿 사용하는 경우 (`if`/`elseif`/`end`포함) `@static`을 각 단계마다 작성해야 한다 (괄호는 필요없지만 가독성을 위해 추천한다): ```julia @static Sys.iswindows() ? :a : (@static Sys.isapple() ? :b : :c) diff --git a/src/manual/mathematical-operations.md b/src/manual/mathematical-operations.md index a0b5de1..d3b0957 100644 --- a/src/manual/mathematical-operations.md +++ b/src/manual/mathematical-operations.md @@ -149,7 +149,7 @@ julia> .![true,false,true] Furthermore, "dotted" updating operators like `a .+= b` (or `@. a += b`) are parsed as `a .= a .+ b`, where `.=` is a fused *in-place* assignment operation -(see the [dot syntax documentation](@ref man-vectorized)). +([dot 문법 문서](@ref man-vectorized)을 참고하라). dot 연산자는 사용자 정의 연산자에서도 활용할 수 있다. 예를 들어 `⊗(A,B) = kron(A,B)`를 정의했다면 `[A,B] .⊗ [C,D]`은 `[A⊗C, B⊗D]`를 계산한다. @@ -289,11 +289,9 @@ true ``` 비교연산 이어쓰기는 코드 구성을 깔끔하게 한다. -비교연산 이어쓰기는 `&&`을 사용하여 비교연산을 한 것과 똑같이 작동하며, 원소별 연산끼리는 [`&`](@ref)연산이 적용된다.(???) -Chained comparisons use the -`&&` operator for scalar comparisons, and the [`&`](@ref) operator for elementwise comparisons, -which allows them to work on arrays. For example, `0 .< A .< 1` gives a boolean array whose entries -are true where the corresponding elements of `A` are between 0 and 1. +비교연산 이어쓰기는 `&&`사용하여 연산을 한것과 똑같이 작용하고, 원소별 연산에서는 [`&`](@ref)을 사용한 것과 동일하다. +쉽게 말하면 우리가 수학적으로 예상한 것과 똑같이 나온다는 것이다. +그 예로 `0 .< A .< 1`는 각 원소가 0과 1 사이에 있는지에 대한 참/거짓을 행렬로 반환한다. Note the evaluation behavior of chained comparisons: @@ -313,11 +311,10 @@ julia> v(1) > v(2) <= v(3) false ``` -The middle expression is only evaluated once, rather than twice as it would be if the expression -were written as `v(1) < v(2) && v(2) <= v(3)`. However, the order of evaluations in a chained -comparison is undefined. It is strongly recommended not to use expressions with side effects (such -as printing) in chained comparisons. If side effects are required, the short-circuit `&&` operator -should be used explicitly (see [Short-Circuit Evaluation](@ref)). +첫번째 결과에서 중간값이 한번만 계산됨을 확인할 수 있다. +이를 통해 `v(1) < v(2) && v(2) <= v(3)`로 계산했을 때보다 적은 계산량을 가지고, 비교연산 이어쓰기에서는 기존 프로그래밍 언어와 달리 계산 순서는 미리 예측할 수 없다는 걸 확인할 수 있다. +따라서 비교연산 이어쓰기에서는 계산 순서가 중요한 연산(예시: 입출력)을 하지말자. +이런 부작용을 감안하고 써야한다면 `&&`연산자를 활용하자. ([Short-Circuit Evaluation](@ref)을 참고하라). ### 기본 함수 @@ -349,11 +346,9 @@ Julia는 수치 계산을 위한 함수와 연산자를 전폭적으로 지원 | 할당 | `= += -= *= /= //= \= ^= ÷= %= \|= &= ⊻= <<= >>= >>>=` | 오른쪽 | [^1]: - 단항연산자 `+` 와 `-`를 연속해서 사용하는 경우, 업데이트 연산자(`++`)와 구별하기 위해 괄호를 명시적으로 사용해야 한다. 다른 단항 연산자와 같이 사용하는 경우엔 right-associativity - `+` and `-` require explicit parentheses around their argument to disambiguate them from the operator `++`, etc. Other compositions of unary operators are parsed with right-associativity, e. g., `√√-a` as `√(√(-a))`. + 단항연산자 `+` 와 `-`를 연속해서 사용하는 경우, 업데이트 연산자(`++`)와 구별하기 위해 괄호를 명시적으로 사용해야 한다. 다른 단항 연산자와 같이 사용하는 경우엔 right-associativity 규칙에 따라 구문을 분석한다(예시: `√√-a`를 `√(√(-a))`로 분석). [^2]: - The operators `+`, `++` and `*` are non-associative. `a + b + c` is parsed as `+(a, b, c)` not `+(+(a, b), - c)`. However, the fallback methods for `+(a, b, c, d...)` and `*(a, b, c, d...)` both default to left-associative evaluation. + The operators `+`, `++` and `*` are non-associative. `a + b + c` is parsed as `+(a, b, c)` not `+(+(a, b), c)`. However, the fallback methods for `+(a, b, c, d...)` and `*(a, b, c, d...)` both default to left-associative evaluation. 모든 Julia 연산자의 우선순위 목록을 보고 싶다면, 다음 파일의 최상단 코드를 참고하라: [`src/julia-parser.scm`](https://github.com/JuliaLang/julia/blob/master/src/julia-parser.scm) From d696ec10e1a0d81c0effe9147a341d54ea6d9526 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Thu, 27 Aug 2020 21:48:06 +0900 Subject: [PATCH 131/153] =?UTF-8?q?pdf=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- codex/manual/asynchronous-programming.md | 337 ++++++ codex/manual/distributed-computing.md | 1404 ++++++++++++++++++++++ codex/manual/multi-threading.md | 351 ++++++ make.jl | 250 ++-- src/index.md | 5 +- src/manual/asynchronous-programming.md | 337 ++++++ src/manual/distributed-computing.md | 1404 ++++++++++++++++++++++ src/manual/multi-threading.md | 351 ++++++ tools/documenter.sty | 98 ++ tools/latex.jl | 70 ++ 10 files changed, 4495 insertions(+), 112 deletions(-) create mode 100644 codex/manual/asynchronous-programming.md create mode 100644 codex/manual/distributed-computing.md create mode 100644 codex/manual/multi-threading.md create mode 100644 src/manual/asynchronous-programming.md create mode 100644 src/manual/distributed-computing.md create mode 100644 src/manual/multi-threading.md create mode 100644 tools/documenter.sty create mode 100644 tools/latex.jl diff --git a/codex/manual/asynchronous-programming.md b/codex/manual/asynchronous-programming.md new file mode 100644 index 0000000..1791d4b --- /dev/null +++ b/codex/manual/asynchronous-programming.md @@ -0,0 +1,337 @@ +# [Asynchronous Programming](@id man-asynchronous) + +When a program needs to interact with the outside world, for example communicating +with another machine over the internet, operations in the program may need to +happen in an unpredictable order. +Say your program needs to download a file. We would like to initiate the download +operation, perform other operations while we wait for it to complete, and then +resume the code that needs the downloaded file when it is available. +This sort of scenario falls in the domain of asynchronous programming, sometimes +also referred to as concurrent programming (since, conceptually, multiple things +are happening at once). + +To address these scenarios, Julia provides [`Task`](@ref)s (also known by several other +names, such as symmetric coroutines, lightweight threads, cooperative multitasking, +or one-shot continuations). +When a piece of computing work (in practice, executing a particular function) is designated as +a [`Task`](@ref), it becomes possible to interrupt it by switching to another [`Task`](@ref). +The original [`Task`](@ref) can later be resumed, at which point it will pick up right where it +left off. At first, this may seem similar to a function call. However there are two key differences. +First, switching tasks does not use any space, so any number of task switches can occur without +consuming the call stack. Second, switching among tasks can occur in any order, unlike function +calls, where the called function must finish executing before control returns to the calling function. + +## Basic `Task` operations + +You can think of a `Task` as a handle to a unit of computational work to be performed. +It has a create-start-run-finish lifecycle. +Tasks are created by calling the `Task` constructor on a 0-argument function to run, +or using the [`@task`](@ref) macro: + +```julia-repl +julia> t = @task begin; sleep(5); println("done"); end +Task (runnable) @0x00007f13a40c0eb0 +``` + +`@task x` is equivalent to `Task(()->x)`. + +This task will wait for five seconds, and then print `done`. However, it has not +started running yet. We can run it whenever we're ready by calling [`schedule`](@ref): + +```julia-repl +julia> schedule(t); +``` + +If you try this in the REPL, you will see that `schedule` returns immediately. +That is because it simply adds `t` to an internal queue of tasks to run. +Then, the REPL will print the next prompt and wait for more input. +Waiting for keyboard input provides an opportunity for other tasks to run, +so at that point `t` will start. +`t` calls [`sleep`](@ref), which sets a timer and stops execution. +If other tasks have been scheduled, they could run then. +After five seconds, the timer fires and restarts `t`, and you will see `done` +printed. `t` is then finished. + +The [`wait`](@ref) function blocks the calling task until some other task finishes. +So for example if you type + +```julia-repl +julia> schedule(t); wait(t) +``` + +instead of only calling `schedule`, you will see a five second pause before +the next input prompt appears. That is because the REPL is waiting for `t` +to finish before proceeding. + +It is common to want to create a task and schedule it right away, so the +macro [`@async`](@ref) is provided for that purpose --- `@async x` is +equivalent to `schedule(@task x)`. + +## Communicating with Channels + +In some problems, +the various pieces of required work are not naturally related by function calls; there is no obvious +"caller" or "callee" among the jobs that need to be done. An example is the producer-consumer +problem, where one complex procedure is generating values and another complex procedure is consuming +them. The consumer cannot simply call a producer function to get a value, because the producer +may have more values to generate and so might not yet be ready to return. With tasks, the producer +and consumer can both run as long as they need to, passing values back and forth as necessary. + +Julia provides a [`Channel`](@ref) mechanism for solving this problem. +A [`Channel`](@ref) is a waitable first-in first-out queue which can have +multiple tasks reading from and writing to it. + +Let's define a producer task, which produces values via the [`put!`](@ref) call. +To consume values, we need to schedule the producer to run in a new task. A special [`Channel`](@ref) +constructor which accepts a 1-arg function as an argument can be used to run a task bound to a channel. +We can then [`take!`](@ref) values repeatedly from the channel object: + +```jldoctest producer +julia> function producer(c::Channel) + put!(c, "start") + for n=1:4 + put!(c, 2n) + end + put!(c, "stop") + end; + +julia> chnl = Channel(producer); + +julia> take!(chnl) +"start" + +julia> take!(chnl) +2 + +julia> take!(chnl) +4 + +julia> take!(chnl) +6 + +julia> take!(chnl) +8 + +julia> take!(chnl) +"stop" +``` + +One way to think of this behavior is that `producer` was able to return multiple times. Between +calls to [`put!`](@ref), the producer's execution is suspended and the consumer has control. + +The returned [`Channel`](@ref) can be used as an iterable object in a `for` loop, in which case the +loop variable takes on all the produced values. The loop is terminated when the channel is closed. + +```jldoctest producer +julia> for x in Channel(producer) + println(x) + end +start +2 +4 +6 +8 +stop +``` + +Note that we did not have to explicitly close the channel in the producer. This is because +the act of binding a [`Channel`](@ref) to a [`Task`](@ref) associates the open lifetime of +a channel with that of the bound task. The channel object is closed automatically when the task +terminates. Multiple channels can be bound to a task, and vice-versa. + +While the [`Task`](@ref) constructor expects a 0-argument function, the [`Channel`](@ref) +method that creates a task-bound channel expects a function that accepts a single argument of +type [`Channel`](@ref). A common pattern is for the producer to be parameterized, in which case a partial +function application is needed to create a 0 or 1 argument [anonymous function](@ref man-anonymous-functions). + +For [`Task`](@ref) objects this can be done either directly or by use of a convenience macro: + +```julia +function mytask(myarg) + ... +end + +taskHdl = Task(() -> mytask(7)) +# or, equivalently +taskHdl = @task mytask(7) +``` + +To orchestrate more advanced work distribution patterns, [`bind`](@ref) and [`schedule`](@ref) +can be used in conjunction with [`Task`](@ref) and [`Channel`](@ref) +constructors to explicitly link a set of channels with a set of producer/consumer tasks. + +### More on Channels + +A channel can be visualized as a pipe, i.e., it has a write end and a read end : + + * Multiple writers in different tasks can write to the same channel concurrently via [`put!`](@ref) + calls. + * Multiple readers in different tasks can read data concurrently via [`take!`](@ref) calls. + * As an example: + + ```julia + # Given Channels c1 and c2, + c1 = Channel(32) + c2 = Channel(32) + + # and a function `foo` which reads items from c1, processes the item read + # and writes a result to c2, + function foo() + while true + data = take!(c1) + [...] # process data + put!(c2, result) # write out result + end + end + + # we can schedule `n` instances of `foo` to be active concurrently. + for _ in 1:n + @async foo() + end + ``` + * Channels are created via the `Channel{T}(sz)` constructor. The channel will only hold objects + of type `T`. If the type is not specified, the channel can hold objects of any type. `sz` refers + to the maximum number of elements that can be held in the channel at any time. For example, `Channel(32)` + creates a channel that can hold a maximum of 32 objects of any type. A `Channel{MyType}(64)` can + hold up to 64 objects of `MyType` at any time. + * If a [`Channel`](@ref) is empty, readers (on a [`take!`](@ref) call) will block until data is available. + * If a [`Channel`](@ref) is full, writers (on a [`put!`](@ref) call) will block until space becomes available. + * [`isready`](@ref) tests for the presence of any object in the channel, while [`wait`](@ref) + waits for an object to become available. + * A [`Channel`](@ref) is in an open state initially. This means that it can be read from and written to + freely via [`take!`](@ref) and [`put!`](@ref) calls. [`close`](@ref) closes a [`Channel`](@ref). + On a closed [`Channel`](@ref), [`put!`](@ref) will fail. For example: + + ```julia-repl + julia> c = Channel(2); + + julia> put!(c, 1) # `put!` on an open channel succeeds + 1 + + julia> close(c); + + julia> put!(c, 2) # `put!` on a closed channel throws an exception. + ERROR: InvalidStateException("Channel is closed.",:closed) + Stacktrace: + [...] + ``` + + * [`take!`](@ref) and [`fetch`](@ref) (which retrieves but does not remove the value) on a closed + channel successfully return any existing values until it is emptied. Continuing the above example: + + ```julia-repl + julia> fetch(c) # Any number of `fetch` calls succeed. + 1 + + julia> fetch(c) + 1 + + julia> take!(c) # The first `take!` removes the value. + 1 + + julia> take!(c) # No more data available on a closed channel. + ERROR: InvalidStateException("Channel is closed.",:closed) + Stacktrace: + [...] + ``` + +Consider a simple example using channels for inter-task communication. We start 4 tasks to process +data from a single `jobs` channel. Jobs, identified by an id (`job_id`), are written to the channel. +Each task in this simulation reads a `job_id`, waits for a random amount of time and writes back +a tuple of `job_id` and the simulated time to the results channel. Finally all the `results` are +printed out. + +```julia-repl +julia> const jobs = Channel{Int}(32); + +julia> const results = Channel{Tuple}(32); + +julia> function do_work() + for job_id in jobs + exec_time = rand() + sleep(exec_time) # simulates elapsed time doing actual work + # typically performed externally. + put!(results, (job_id, exec_time)) + end + end; + +julia> function make_jobs(n) + for i in 1:n + put!(jobs, i) + end + end; + +julia> n = 12; + +julia> @async make_jobs(n); # feed the jobs channel with "n" jobs + +julia> for i in 1:4 # start 4 tasks to process requests in parallel + @async do_work() + end + +julia> @elapsed while n > 0 # print out results + job_id, exec_time = take!(results) + println("$job_id finished in $(round(exec_time; digits=2)) seconds") + global n = n - 1 + end +4 finished in 0.22 seconds +3 finished in 0.45 seconds +1 finished in 0.5 seconds +7 finished in 0.14 seconds +2 finished in 0.78 seconds +5 finished in 0.9 seconds +9 finished in 0.36 seconds +6 finished in 0.87 seconds +8 finished in 0.79 seconds +10 finished in 0.64 seconds +12 finished in 0.5 seconds +11 finished in 0.97 seconds +0.029772311 +``` + +## More task operations + +Task operations are built on a low-level primitive called [`yieldto`](@ref). +`yieldto(task, value)` suspends the current task, switches to the specified `task`, and causes +that task's last [`yieldto`](@ref) call to return the specified `value`. Notice that [`yieldto`](@ref) +is the only operation required to use task-style control flow; instead of calling and returning +we are always just switching to a different task. This is why this feature is also called "symmetric +coroutines"; each task is switched to and from using the same mechanism. + +[`yieldto`](@ref) is powerful, but most uses of tasks do not invoke it directly. Consider why +this might be. If you switch away from the current task, you will probably want to switch back +to it at some point, but knowing when to switch back, and knowing which task has the responsibility +of switching back, can require considerable coordination. For example, [`put!`](@ref) and [`take!`](@ref) +are blocking operations, which, when used in the context of channels maintain state to remember +who the consumers are. Not needing to manually keep track of the consuming task is what makes [`put!`](@ref) +easier to use than the low-level [`yieldto`](@ref). + +In addition to [`yieldto`](@ref), a few other basic functions are needed to use tasks effectively. + + * [`current_task`](@ref) gets a reference to the currently-running task. + * [`istaskdone`](@ref) queries whether a task has exited. + * [`istaskstarted`](@ref) queries whether a task has run yet. + * [`task_local_storage`](@ref) manipulates a key-value store specific to the current task. + +## Tasks and events + +Most task switches occur as a result of waiting for events such as I/O requests, and are performed +by a scheduler included in Julia Base. The scheduler maintains a queue of runnable tasks, +and executes an event loop that restarts tasks based on external events such as message arrival. + +The basic function for waiting for an event is [`wait`](@ref). Several objects implement [`wait`](@ref); +for example, given a `Process` object, [`wait`](@ref) will wait for it to exit. [`wait`](@ref) +is often implicit; for example, a [`wait`](@ref) can happen inside a call to [`read`](@ref) +to wait for data to be available. + +In all of these cases, [`wait`](@ref) ultimately operates on a [`Condition`](@ref) object, which +is in charge of queueing and restarting tasks. When a task calls [`wait`](@ref) on a [`Condition`](@ref), +the task is marked as non-runnable, added to the condition's queue, and switches to the scheduler. +The scheduler will then pick another task to run, or block waiting for external events. If all +goes well, eventually an event handler will call [`notify`](@ref) on the condition, which causes +tasks waiting for that condition to become runnable again. + +A task created explicitly by calling [`Task`](@ref) is initially not known to the scheduler. This +allows you to manage tasks manually using [`yieldto`](@ref) if you wish. However, when such +a task waits for an event, it still gets restarted automatically when the event happens, as you +would expect. diff --git a/codex/manual/distributed-computing.md b/codex/manual/distributed-computing.md new file mode 100644 index 0000000..e5b6e78 --- /dev/null +++ b/codex/manual/distributed-computing.md @@ -0,0 +1,1404 @@ +# Multi-processing and Distributed Computing + +An implementation of distributed memory parallel computing is provided by module `Distributed` +as part of the standard library shipped with Julia. + +Most modern computers possess more than one CPU, and several computers can be combined together +in a cluster. Harnessing the power of these multiple CPUs allows many computations to be completed +more quickly. There are two major factors that influence performance: the speed of the CPUs themselves, +and the speed of their access to memory. In a cluster, it's fairly obvious that a given CPU will +have fastest access to the RAM within the same computer (node). Perhaps more surprisingly, similar +issues are relevant on a typical multicore laptop, due to differences in the speed of main memory +and the [cache](https://www.akkadia.org/drepper/cpumemory.pdf). Consequently, a good multiprocessing +environment should allow control over the "ownership" of a chunk of memory by a particular CPU. +Julia provides a multiprocessing environment based on message passing to allow programs to run +on multiple processes in separate memory domains at once. + +Julia's implementation of message passing is different from other environments such as MPI[^1]. +Communication in Julia is generally "one-sided", meaning that the programmer needs to explicitly +manage only one process in a two-process operation. Furthermore, these operations typically do +not look like "message send" and "message receive" but rather resemble higher-level operations +like calls to user functions. + +Distributed programming in Julia is built on two primitives: *remote references* and *remote calls*. +A remote reference is an object that can be used from any process to refer to an object stored +on a particular process. A remote call is a request by one process to call a certain function +on certain arguments on another (possibly the same) process. + +Remote references come in two flavors: [`Future`](@ref Distributed.Future) and [`RemoteChannel`](@ref). + +A remote call returns a [`Future`](@ref Distributed.Future) to its result. Remote calls return immediately; the process +that made the call proceeds to its next operation while the remote call happens somewhere else. +You can wait for a remote call to finish by calling [`wait`](@ref) on the returned [`Future`](@ref Distributed.Future), +and you can obtain the full value of the result using [`fetch`](@ref). + +On the other hand, [`RemoteChannel`](@ref) s are rewritable. For example, multiple processes can +co-ordinate their processing by referencing the same remote `Channel`. + +Each process has an associated identifier. The process providing the interactive Julia prompt +always has an `id` equal to 1. The processes used by default for parallel operations are referred +to as "workers". When there is only one process, process 1 is considered a worker. Otherwise, +workers are considered to be all processes other than process 1. As a result, adding 2 or more +processes is required to gain benefits from parallel processing methods like [`pmap`](@ref). Adding +a single process is beneficial if you just wish to do other things in the main process while a long +computation is running on the worker. + +Let's try this out. Starting with `julia -p n` provides `n` worker processes on the local machine. +Generally it makes sense for `n` to equal the number of CPU threads (logical cores) on the machine. Note that the `-p` +argument implicitly loads module `Distributed`. + + +```julia +$ ./julia -p 2 + +julia> r = remotecall(rand, 2, 2, 2) +Future(2, 1, 4, nothing) + +julia> s = @spawnat 2 1 .+ fetch(r) +Future(2, 1, 5, nothing) + +julia> fetch(s) +2×2 Array{Float64,2}: + 1.18526 1.50912 + 1.16296 1.60607 +``` + +The first argument to [`remotecall`](@ref) is the function to call. Most parallel programming +in Julia does not reference specific processes or the number of processes available, but [`remotecall`](@ref) +is considered a low-level interface providing finer control. The second argument to [`remotecall`](@ref) +is the `id` of the process that will do the work, and the remaining arguments will be passed to +the function being called. + +As you can see, in the first line we asked process 2 to construct a 2-by-2 random matrix, and +in the second line we asked it to add 1 to it. The result of both calculations is available in +the two futures, `r` and `s`. The [`@spawnat`](@ref) macro evaluates the expression in the second +argument on the process specified by the first argument. + +Occasionally you might want a remotely-computed value immediately. This typically happens when +you read from a remote object to obtain data needed by the next local operation. The function +[`remotecall_fetch`](@ref) exists for this purpose. It is equivalent to `fetch(remotecall(...))` +but is more efficient. + +```julia-repl +julia> remotecall_fetch(getindex, 2, r, 1, 1) +0.18526337335308085 +``` + +Remember that [`getindex(r,1,1)`](@ref) is [equivalent](@ref man-array-indexing) to `r[1,1]`, so this call fetches +the first element of the future `r`. + +To make things easier, the symbol `:any` can be passed to [`@spawnat`](@ref), which picks where to do +the operation for you: + +```julia-repl +julia> r = @spawnat :any rand(2,2) +Future(2, 1, 4, nothing) + +julia> s = @spawnat :any 1 .+ fetch(r) +Future(3, 1, 5, nothing) + +julia> fetch(s) +2×2 Array{Float64,2}: + 1.38854 1.9098 + 1.20939 1.57158 +``` + +Note that we used `1 .+ fetch(r)` instead of `1 .+ r`. This is because we do not know where the +code will run, so in general a [`fetch`](@ref) might be required to move `r` to the process +doing the addition. In this case, [`@spawnat`](@ref) is smart enough to perform the computation +on the process that owns `r`, so the [`fetch`](@ref) will be a no-op (no work is done). + +(It is worth noting that [`@spawnat`](@ref) is not built-in but defined in Julia as a [macro](@ref man-macros). +It is possible to define your own such constructs.) + +An important thing to remember is that, once fetched, a [`Future`](@ref Distributed.Future) will cache its value +locally. Further [`fetch`](@ref) calls do not entail a network hop. Once all referencing [`Future`](@ref Distributed.Future)s +have fetched, the remote stored value is deleted. + +[`@async`](@ref) is similar to [`@spawnat`](@ref), but only runs tasks on the local process. We +use it to create a "feeder" task for each process. Each task picks the next index that needs to +be computed, then waits for its process to finish, then repeats until we run out of indices. Note +that the feeder tasks do not begin to execute until the main task reaches the end of the [`@sync`](@ref) +block, at which point it surrenders control and waits for all the local tasks to complete before +returning from the function. +As for v0.7 and beyond, the feeder tasks are able to share state via `nextidx` because +they all run on the same process. +Even if `Tasks` are scheduled cooperatively, locking may still be required in some contexts, as in +[asynchronous I/O](@ref faq-async-io). +This means context switches only occur at well-defined points: in this case, +when [`remotecall_fetch`](@ref) is called. This is the current state of implementation and it may change +for future Julia versions, as it is intended to make it possible to run up to N `Tasks` on M `Process`, aka +[M:N Threading](https://en.wikipedia.org/wiki/Thread_(computing)#Models). Then a lock acquiring\releasing +model for `nextidx` will be needed, as it is not safe to let multiple processes read-write a resource at +the same time. + + + +## [Code Availability and Loading Packages](@id code-availability) + +Your code must be available on any process that runs it. For example, type the following into +the Julia prompt: + +```julia-repl +julia> function rand2(dims...) + return 2*rand(dims...) + end + +julia> rand2(2,2) +2×2 Array{Float64,2}: + 0.153756 0.368514 + 1.15119 0.918912 + +julia> fetch(@spawnat :any rand2(2,2)) +ERROR: RemoteException(2, CapturedException(UndefVarError(Symbol("#rand2")) +Stacktrace: +[...] +``` + +Process 1 knew about the function `rand2`, but process 2 did not. + +Most commonly you'll be loading code from files or packages, and you have a considerable amount +of flexibility in controlling which processes load code. Consider a file, `DummyModule.jl`, +containing the following code: + +```julia +module DummyModule + +export MyType, f + +mutable struct MyType + a::Int +end + +f(x) = x^2+1 + +println("loaded") + +end +``` + +In order to refer to `MyType` across all processes, `DummyModule.jl` needs to be loaded on +every process. Calling `include("DummyModule.jl")` loads it only on a single process. To +load it on every process, use the [`@everywhere`](@ref) macro (starting Julia with `julia -p +2`): + +```julia-repl +julia> @everywhere include("DummyModule.jl") +loaded + From worker 3: loaded + From worker 2: loaded +``` + +As usual, this does not bring `DummyModule` into scope on any of the process, which requires +`using` or `import`. Moreover, when `DummyModule` is brought into scope on one process, it +is not on any other: + +```julia-repl +julia> using .DummyModule + +julia> MyType(7) +MyType(7) + +julia> fetch(@spawnat 2 MyType(7)) +ERROR: On worker 2: +UndefVarError: MyType not defined +⋮ + +julia> fetch(@spawnat 2 DummyModule.MyType(7)) +MyType(7) +``` + +However, it's still possible, for instance, to send a `MyType` to a process which has loaded +`DummyModule` even if it's not in scope: + +```julia-repl +julia> put!(RemoteChannel(2), MyType(7)) +RemoteChannel{Channel{Any}}(2, 1, 13) +``` + +A file can also be preloaded on multiple processes at startup with the `-L` flag, and a +driver script can be used to drive the computation: + +``` +julia -p -L file1.jl -L file2.jl driver.jl +``` + +The Julia process running the driver script in the example above has an `id` equal to 1, just +like a process providing an interactive prompt. + +Finally, if `DummyModule.jl` is not a standalone file but a package, then `using +DummyModule` will _load_ `DummyModule.jl` on all processes, but only bring it into scope on +the process where `using` was called. + +## Starting and managing worker processes + +The base Julia installation has in-built support for two types of clusters: + + * A local cluster specified with the `-p` option as shown above. + * A cluster spanning machines using the `--machine-file` option. This uses a passwordless `ssh` login + to start Julia worker processes (from the same path as the current host) on the specified machines. Each machine definition + takes the form `[count*][user@]host[:port] [bind_addr[:port]]`. `user` defaults to current user, + `port` to the standard ssh port. `count` is the number of workers to spawn on the node, and defaults + to 1. The optional `bind-to bind_addr[:port]` specifies the IP address and port that other workers + should use to connect to this worker. + +Functions [`addprocs`](@ref), [`rmprocs`](@ref), [`workers`](@ref), and others are available +as a programmatic means of adding, removing and querying the processes in a cluster. + +```julia-repl +julia> using Distributed + +julia> addprocs(2) +2-element Array{Int64,1}: + 2 + 3 +``` + +Module `Distributed` must be explicitly loaded on the master process before invoking [`addprocs`](@ref). +It is automatically made available on the worker processes. + +Note that workers do not run a `~/.julia/config/startup.jl` startup script, nor do they synchronize +their global state (such as global variables, new method definitions, and loaded modules) with any +of the other running processes. You may use `addprocs(exeflags="--project")` to initialize a worker with +a particular environment, and then `@everywhere using ` or `@everywhere include("file.jl")`. + +Other types of clusters can be supported by writing your own custom `ClusterManager`, as described +below in the [ClusterManagers](@ref) section. + +## Data Movement + +Sending messages and moving data constitute most of the overhead in a distributed program. Reducing +the number of messages and the amount of data sent is critical to achieving performance and scalability. +To this end, it is important to understand the data movement performed by Julia's various distributed +programming constructs. + +[`fetch`](@ref) can be considered an explicit data movement operation, since it directly asks +that an object be moved to the local machine. [`@spawnat`](@ref) (and a few related constructs) +also moves data, but this is not as obvious, hence it can be called an implicit data movement +operation. Consider these two approaches to constructing and squaring a random matrix: + +Method 1: + +```julia-repl +julia> A = rand(1000,1000); + +julia> Bref = @spawnat :any A^2; + +[...] + +julia> fetch(Bref); +``` + +Method 2: + +```julia-repl +julia> Bref = @spawnat :any rand(1000,1000)^2; + +[...] + +julia> fetch(Bref); +``` + +The difference seems trivial, but in fact is quite significant due to the behavior of [`@spawnat`](@ref). +In the first method, a random matrix is constructed locally, then sent to another process where +it is squared. In the second method, a random matrix is both constructed and squared on another +process. Therefore the second method sends much less data than the first. + +In this toy example, the two methods are easy to distinguish and choose from. However, in a real +program designing data movement might require more thought and likely some measurement. For example, +if the first process needs matrix `A` then the first method might be better. Or, if computing +`A` is expensive and only the current process has it, then moving it to another process might +be unavoidable. Or, if the current process has very little to do between the [`@spawnat`](@ref) +and `fetch(Bref)`, it might be better to eliminate the parallelism altogether. Or imagine `rand(1000,1000)` +is replaced with a more expensive operation. Then it might make sense to add another [`@spawnat`](@ref) +statement just for this step. + +## Global variables +Expressions executed remotely via `@spawnat`, or closures specified for remote execution using +`remotecall` may refer to global variables. Global bindings under module `Main` are treated +a little differently compared to global bindings in other modules. Consider the following code +snippet: + +```julia-repl +A = rand(10,10) +remotecall_fetch(()->sum(A), 2) +``` + +In this case [`sum`](@ref) MUST be defined in the remote process. +Note that `A` is a global variable defined in the local workspace. Worker 2 does not have a variable called +`A` under `Main`. The act of shipping the closure `()->sum(A)` to worker 2 results in `Main.A` being defined +on 2. `Main.A` continues to exist on worker 2 even after the call `remotecall_fetch` returns. Remote calls +with embedded global references (under `Main` module only) manage globals as follows: + +- New global bindings are created on destination workers if they are referenced as part of a remote call. + +- Global constants are declared as constants on remote nodes too. + +- Globals are re-sent to a destination worker only in the context of a remote call, and then only + if its value has changed. Also, the cluster does not synchronize global bindings across nodes. + For example: + + ```julia + A = rand(10,10) + remotecall_fetch(()->sum(A), 2) # worker 2 + A = rand(10,10) + remotecall_fetch(()->sum(A), 3) # worker 3 + A = nothing + ``` + + Executing the above snippet results in `Main.A` on worker 2 having a different value from + `Main.A` on worker 3, while the value of `Main.A` on node 1 is set to `nothing`. + +As you may have realized, while memory associated with globals may be collected when they are reassigned +on the master, no such action is taken on the workers as the bindings continue to be valid. +[`clear!`](@ref) can be used to manually reassign specific globals on remote nodes to `nothing` once +they are no longer required. This will release any memory associated with them as part of a regular garbage +collection cycle. + +Thus programs should be careful referencing globals in remote calls. In fact, it is preferable to avoid them +altogether if possible. If you must reference globals, consider using `let` blocks to localize global variables. + +For example: + +```julia-repl +julia> A = rand(10,10); + +julia> remotecall_fetch(()->A, 2); + +julia> B = rand(10,10); + +julia> let B = B + remotecall_fetch(()->B, 2) + end; + +julia> @fetchfrom 2 InteractiveUtils.varinfo() +name size summary +––––––––– ––––––––– –––––––––––––––––––––– +A 800 bytes 10×10 Array{Float64,2} +Base Module +Core Module +Main Module +``` + +As can be seen, global variable `A` is defined on worker 2, but `B` is captured as a local variable +and hence a binding for `B` does not exist on worker 2. + + +## Parallel Map and Loops + +Fortunately, many useful parallel computations do not require data movement. A common example +is a Monte Carlo simulation, where multiple processes can handle independent simulation trials +simultaneously. We can use [`@spawnat`](@ref) to flip coins on two processes. First, write the following +function in `count_heads.jl`: + +```julia +function count_heads(n) + c::Int = 0 + for i = 1:n + c += rand(Bool) + end + c +end +``` + +The function `count_heads` simply adds together `n` random bits. Here is how we can perform some +trials on two machines, and add together the results: + +```julia-repl +julia> @everywhere include_string(Main, $(read("count_heads.jl", String)), "count_heads.jl") + +julia> a = @spawnat :any count_heads(100000000) +Future(2, 1, 6, nothing) + +julia> b = @spawnat :any count_heads(100000000) +Future(3, 1, 7, nothing) + +julia> fetch(a)+fetch(b) +100001564 +``` + +This example demonstrates a powerful and often-used parallel programming pattern. Many iterations +run independently over several processes, and then their results are combined using some function. +The combination process is called a *reduction*, since it is generally tensor-rank-reducing: a +vector of numbers is reduced to a single number, or a matrix is reduced to a single row or column, +etc. In code, this typically looks like the pattern `x = f(x,v[i])`, where `x` is the accumulator, +`f` is the reduction function, and the `v[i]` are the elements being reduced. It is desirable +for `f` to be associative, so that it does not matter what order the operations are performed +in. + +Notice that our use of this pattern with `count_heads` can be generalized. We used two explicit +[`@spawnat`](@ref) statements, which limits the parallelism to two processes. To run on any number +of processes, we can use a *parallel for loop*, running in distributed memory, which can be written +in Julia using [`@distributed`](@ref) like this: + +```julia +nheads = @distributed (+) for i = 1:200000000 + Int(rand(Bool)) +end +``` + +This construct implements the pattern of assigning iterations to multiple processes, and combining +them with a specified reduction (in this case `(+)`). The result of each iteration is taken as +the value of the last expression inside the loop. The whole parallel loop expression itself evaluates +to the final answer. + +Note that although parallel for loops look like serial for loops, their behavior is dramatically +different. In particular, the iterations do not happen in a specified order, and writes to variables +or arrays will not be globally visible since iterations run on different processes. Any variables +used inside the parallel loop will be copied and broadcast to each process. + +For example, the following code will not work as intended: + +```julia +a = zeros(100000) +@distributed for i = 1:100000 + a[i] = i +end +``` + +This code will not initialize all of `a`, since each process will have a separate copy of it. +Parallel for loops like these must be avoided. Fortunately, [Shared Arrays](@ref man-shared-arrays) can be used +to get around this limitation: + +```julia +using SharedArrays + +a = SharedArray{Float64}(10) +@distributed for i = 1:10 + a[i] = i +end +``` + +Using "outside" variables in parallel loops is perfectly reasonable if the variables are read-only: + +```julia +a = randn(1000) +@distributed (+) for i = 1:100000 + f(a[rand(1:end)]) +end +``` + +Here each iteration applies `f` to a randomly-chosen sample from a vector `a` shared by all processes. + +As you could see, the reduction operator can be omitted if it is not needed. In that case, the +loop executes asynchronously, i.e. it spawns independent tasks on all available workers and returns +an array of [`Future`](@ref Distributed.Future) immediately without waiting for completion. The caller can wait for +the [`Future`](@ref Distributed.Future) completions at a later point by calling [`fetch`](@ref) on them, or wait +for completion at the end of the loop by prefixing it with [`@sync`](@ref), like `@sync @distributed for`. + +In some cases no reduction operator is needed, and we merely wish to apply a function to all integers +in some range (or, more generally, to all elements in some collection). This is another useful +operation called *parallel map*, implemented in Julia as the [`pmap`](@ref) function. For example, +we could compute the singular values of several large random matrices in parallel as follows: + +```julia-repl +julia> M = Matrix{Float64}[rand(1000,1000) for i = 1:10]; + +julia> pmap(svdvals, M); +``` + +Julia's [`pmap`](@ref) is designed for the case where each function call does a large amount +of work. In contrast, `@distributed for` can handle situations where each iteration is tiny, perhaps +merely summing two numbers. Only worker processes are used by both [`pmap`](@ref) and `@distributed for` +for the parallel computation. In case of `@distributed for`, the final reduction is done on the calling +process. + +## Remote References and AbstractChannels + +Remote references always refer to an implementation of an `AbstractChannel`. + +A concrete implementation of an `AbstractChannel` (like `Channel`), is required to implement +[`put!`](@ref), [`take!`](@ref), [`fetch`](@ref), [`isready`](@ref) and [`wait`](@ref). +The remote object referred to by a [`Future`](@ref Distributed.Future) is stored in a `Channel{Any}(1)`, i.e., a +`Channel` of size 1 capable of holding objects of `Any` type. + +[`RemoteChannel`](@ref), which is rewritable, can point to any type and size of channels, or any +other implementation of an `AbstractChannel`. + +The constructor `RemoteChannel(f::Function, pid)()` allows us to construct references to channels +holding more than one value of a specific type. `f` is a function executed on `pid` and it must +return an `AbstractChannel`. + +For example, `RemoteChannel(()->Channel{Int}(10), pid)`, will return a reference to a channel +of type `Int` and size 10. The channel exists on worker `pid`. + +Methods [`put!`](@ref), [`take!`](@ref), [`fetch`](@ref), [`isready`](@ref) and [`wait`](@ref) +on a [`RemoteChannel`](@ref) are proxied onto the backing store on the remote process. + +[`RemoteChannel`](@ref) can thus be used to refer to user implemented `AbstractChannel` objects. +A simple example of this is provided in `dictchannel.jl` in the +[Examples repository](https://github.com/JuliaAttic/Examples), which uses a dictionary as its +remote store. + + +## Channels and RemoteChannels + + * A [`Channel`](@ref) is local to a process. Worker 2 cannot directly refer to a [`Channel`](@ref) on worker 3 and + vice-versa. A [`RemoteChannel`](@ref), however, can put and take values across workers. + * A [`RemoteChannel`](@ref) can be thought of as a *handle* to a [`Channel`](@ref). + * The process id, `pid`, associated with a [`RemoteChannel`](@ref) identifies the process where + the backing store, i.e., the backing [`Channel`](@ref) exists. + * Any process with a reference to a [`RemoteChannel`](@ref) can put and take items from the channel. + Data is automatically sent to (or retrieved from) the process a [`RemoteChannel`](@ref) is associated + with. + * Serializing a [`Channel`](@ref) also serializes any data present in the channel. Deserializing it therefore + effectively makes a copy of the original object. + * On the other hand, serializing a [`RemoteChannel`](@ref) only involves the serialization of an + identifier that identifies the location and instance of [`Channel`](@ref) referred to by the handle. A + deserialized [`RemoteChannel`](@ref) object (on any worker), therefore also points to the same + backing store as the original. + +The channels example from above can be modified for interprocess communication, +as shown below. + +We start 4 workers to process a single `jobs` remote channel. Jobs, identified by an id (`job_id`), +are written to the channel. Each remotely executing task in this simulation reads a `job_id`, +waits for a random amount of time and writes back a tuple of `job_id`, time taken and its own +`pid` to the results channel. Finally all the `results` are printed out on the master process. + +```julia-repl +julia> addprocs(4); # add worker processes + +julia> const jobs = RemoteChannel(()->Channel{Int}(32)); + +julia> const results = RemoteChannel(()->Channel{Tuple}(32)); + +julia> @everywhere function do_work(jobs, results) # define work function everywhere + while true + job_id = take!(jobs) + exec_time = rand() + sleep(exec_time) # simulates elapsed time doing actual work + put!(results, (job_id, exec_time, myid())) + end + end + +julia> function make_jobs(n) + for i in 1:n + put!(jobs, i) + end + end; + +julia> n = 12; + +julia> @async make_jobs(n); # feed the jobs channel with "n" jobs + +julia> for p in workers() # start tasks on the workers to process requests in parallel + remote_do(do_work, p, jobs, results) + end + +julia> @elapsed while n > 0 # print out results + job_id, exec_time, where = take!(results) + println("$job_id finished in $(round(exec_time; digits=2)) seconds on worker $where") + global n = n - 1 + end +1 finished in 0.18 seconds on worker 4 +2 finished in 0.26 seconds on worker 5 +6 finished in 0.12 seconds on worker 4 +7 finished in 0.18 seconds on worker 4 +5 finished in 0.35 seconds on worker 5 +4 finished in 0.68 seconds on worker 2 +3 finished in 0.73 seconds on worker 3 +11 finished in 0.01 seconds on worker 3 +12 finished in 0.02 seconds on worker 3 +9 finished in 0.26 seconds on worker 5 +8 finished in 0.57 seconds on worker 4 +10 finished in 0.58 seconds on worker 2 +0.055971741 +``` + +### Remote References and Distributed Garbage Collection + +Objects referred to by remote references can be freed only when *all* held references +in the cluster are deleted. + +The node where the value is stored keeps track of which of the workers have a reference to it. +Every time a [`RemoteChannel`](@ref) or a (unfetched) [`Future`](@ref Distributed.Future) is serialized to a worker, +the node pointed to by the reference is notified. And every time a [`RemoteChannel`](@ref) or +a (unfetched) [`Future`](@ref Distributed.Future) is garbage collected locally, the node owning the value is again +notified. This is implemented in an internal cluster aware serializer. Remote references are only +valid in the context of a running cluster. Serializing and deserializing references to and from +regular `IO` objects is not supported. + +The notifications are done via sending of "tracking" messages--an "add reference" message when +a reference is serialized to a different process and a "delete reference" message when a reference +is locally garbage collected. + +Since [`Future`](@ref Distributed.Future)s are write-once and cached locally, the act of [`fetch`](@ref)ing a +[`Future`](@ref Distributed.Future) also updates reference tracking information on the node owning the value. + +The node which owns the value frees it once all references to it are cleared. + +With [`Future`](@ref Distributed.Future)s, serializing an already fetched [`Future`](@ref Distributed.Future) to a different node also +sends the value since the original remote store may have collected the value by this time. + +It is important to note that *when* an object is locally garbage collected depends on the size +of the object and the current memory pressure in the system. + +In case of remote references, the size of the local reference object is quite small, while the +value stored on the remote node may be quite large. Since the local object may not be collected +immediately, it is a good practice to explicitly call [`finalize`](@ref) on local instances +of a [`RemoteChannel`](@ref), or on unfetched [`Future`](@ref Distributed.Future)s. Since calling [`fetch`](@ref) +on a [`Future`](@ref Distributed.Future) also removes its reference from the remote store, this is not required on +fetched [`Future`](@ref Distributed.Future)s. Explicitly calling [`finalize`](@ref) results in an immediate message +sent to the remote node to go ahead and remove its reference to the value. + +Once finalized, a reference becomes invalid and cannot be used in any further calls. + + +## Local invocations + +Data is necessarily copied over to the remote node for execution. This is the case for both +remotecalls and when data is stored to a[`RemoteChannel`](@ref) / [`Future`](@ref Distributed.Future) on +a different node. As expected, this results in a copy of the serialized objects +on the remote node. However, when the destination node is the local node, i.e. +the calling process id is the same as the remote node id, it is executed +as a local call. It is usually (not always) executed in a different task - but there is no +serialization/deserialization of data. Consequently, the call refers to the same object instances +as passed - no copies are created. This behavior is highlighted below: + +```julia-repl +julia> using Distributed; + +julia> rc = RemoteChannel(()->Channel(3)); # RemoteChannel created on local node + +julia> v = [0]; + +julia> for i in 1:3 + v[1] = i # Reusing `v` + put!(rc, v) + end; + +julia> result = [take!(rc) for _ in 1:3]; + +julia> println(result); +Array{Int64,1}[[3], [3], [3]] + +julia> println("Num Unique objects : ", length(unique(map(objectid, result)))); +Num Unique objects : 1 + +julia> addprocs(1); + +julia> rc = RemoteChannel(()->Channel(3), workers()[1]); # RemoteChannel created on remote node + +julia> v = [0]; + +julia> for i in 1:3 + v[1] = i + put!(rc, v) + end; + +julia> result = [take!(rc) for _ in 1:3]; + +julia> println(result); +Array{Int64,1}[[1], [2], [3]] + +julia> println("Num Unique objects : ", length(unique(map(objectid, result)))); +Num Unique objects : 3 +``` + +As can be seen, [`put!`](@ref) on a locally owned [`RemoteChannel`](@ref) with the same +object `v` modifed between calls results in the same single object instance stored. As +opposed to copies of `v` being created when the node owning `rc` is a different node. + +It is to be noted that this is generally not an issue. It is something to be factored in only +if the object is both being stored locally and modifed post the call. In such cases it may be +appropriate to store a `deepcopy` of the object. + +This is also true for remotecalls on the local node as seen in the following example: + +```julia-repl +julia> using Distributed; addprocs(1); + +julia> v = [0]; + +julia> v2 = remotecall_fetch(x->(x[1] = 1; x), myid(), v); # Executed on local node + +julia> println("v=$v, v2=$v2, ", v === v2); +v=[1], v2=[1], true + +julia> v = [0]; + +julia> v2 = remotecall_fetch(x->(x[1] = 1; x), workers()[1], v); # Executed on remote node + +julia> println("v=$v, v2=$v2, ", v === v2); +v=[0], v2=[1], false +``` + +As can be seen once again, a remote call onto the local node behaves just like a direct invocation. +The call modifies local objects passed as arguments. In the remote invocation, it operates on +a copy of the arguments. + +To repeat, in general this is not an issue. If the local node is also being used as a compute +node, and the arguments used post the call, this behavior needs to be factored in and if required +deep copies of arguments must be passed to the call invoked on the local node. Calls on remote nodes +will always operate on copies of arguments. + + + +## [Shared Arrays](@id man-shared-arrays) + +Shared Arrays use system shared memory to map the same array across many processes. While there +are some similarities to a [`DArray`](https://github.com/JuliaParallel/DistributedArrays.jl), the +behavior of a [`SharedArray`](@ref) is quite different. In a [`DArray`](https://github.com/JuliaParallel/DistributedArrays.jl), +each process has local access to just a chunk of the data, and no two processes share the same +chunk; in contrast, in a [`SharedArray`](@ref) each "participating" process has access to the +entire array. A [`SharedArray`](@ref) is a good choice when you want to have a large amount of +data jointly accessible to two or more processes on the same machine. + +Shared Array support is available via module `SharedArrays` which must be explicitly loaded on +all participating workers. + +[`SharedArray`](@ref) indexing (assignment and accessing values) works just as with regular arrays, +and is efficient because the underlying memory is available to the local process. Therefore, +most algorithms work naturally on [`SharedArray`](@ref)s, albeit in single-process mode. In cases +where an algorithm insists on an [`Array`](@ref) input, the underlying array can be retrieved +from a [`SharedArray`](@ref) by calling [`sdata`](@ref). For other `AbstractArray` types, [`sdata`](@ref) +just returns the object itself, so it's safe to use [`sdata`](@ref) on any `Array`-type object. + +The constructor for a shared array is of the form: + +```julia +SharedArray{T,N}(dims::NTuple; init=false, pids=Int[]) +``` + +which creates an `N`-dimensional shared array of a bits type `T` and size `dims` across the processes specified +by `pids`. Unlike distributed arrays, a shared array is accessible only from those participating +workers specified by the `pids` named argument (and the creating process too, if it is on the +same host). Note that only elements that are [`isbits`](@ref) are supported in a SharedArray. + +If an `init` function, of signature `initfn(S::SharedArray)`, is specified, it is called on all +the participating workers. You can specify that each worker runs the `init` function on a distinct +portion of the array, thereby parallelizing initialization. + +Here's a brief example: + +```julia-repl +julia> using Distributed + +julia> addprocs(3) +3-element Array{Int64,1}: + 2 + 3 + 4 + +julia> @everywhere using SharedArrays + +julia> S = SharedArray{Int,2}((3,4), init = S -> S[localindices(S)] = repeat([myid()], length(localindices(S)))) +3×4 SharedArray{Int64,2}: + 2 2 3 4 + 2 3 3 4 + 2 3 4 4 + +julia> S[3,2] = 7 +7 + +julia> S +3×4 SharedArray{Int64,2}: + 2 2 3 4 + 2 3 3 4 + 2 7 4 4 +``` + +[`SharedArrays.localindices`](@ref) provides disjoint one-dimensional ranges of indices, and is sometimes +convenient for splitting up tasks among processes. You can, of course, divide the work any way +you wish: + +```julia-repl +julia> S = SharedArray{Int,2}((3,4), init = S -> S[indexpids(S):length(procs(S)):length(S)] = repeat([myid()], length( indexpids(S):length(procs(S)):length(S)))) +3×4 SharedArray{Int64,2}: + 2 2 2 2 + 3 3 3 3 + 4 4 4 4 +``` + +Since all processes have access to the underlying data, you do have to be careful not to set up +conflicts. For example: + +```julia +@sync begin + for p in procs(S) + @async begin + remotecall_wait(fill!, p, S, p) + end + end +end +``` + +would result in undefined behavior. Because each process fills the *entire* array with its own +`pid`, whichever process is the last to execute (for any particular element of `S`) will have +its `pid` retained. + +As a more extended and complex example, consider running the following "kernel" in parallel: + +```julia +q[i,j,t+1] = q[i,j,t] + u[i,j,t] +``` + +In this case, if we try to split up the work using a one-dimensional index, we are likely to run +into trouble: if `q[i,j,t]` is near the end of the block assigned to one worker and `q[i,j,t+1]` +is near the beginning of the block assigned to another, it's very likely that `q[i,j,t]` will +not be ready at the time it's needed for computing `q[i,j,t+1]`. In such cases, one is better +off chunking the array manually. Let's split along the second dimension. +Define a function that returns the `(irange, jrange)` indices assigned to this worker: + +```julia-repl +julia> @everywhere function myrange(q::SharedArray) + idx = indexpids(q) + if idx == 0 # This worker is not assigned a piece + return 1:0, 1:0 + end + nchunks = length(procs(q)) + splits = [round(Int, s) for s in range(0, stop=size(q,2), length=nchunks+1)] + 1:size(q,1), splits[idx]+1:splits[idx+1] + end +``` + +Next, define the kernel: + +```julia-repl +julia> @everywhere function advection_chunk!(q, u, irange, jrange, trange) + @show (irange, jrange, trange) # display so we can see what's happening + for t in trange, j in jrange, i in irange + q[i,j,t+1] = q[i,j,t] + u[i,j,t] + end + q + end +``` + +We also define a convenience wrapper for a `SharedArray` implementation + +```julia-repl +julia> @everywhere advection_shared_chunk!(q, u) = + advection_chunk!(q, u, myrange(q)..., 1:size(q,3)-1) +``` + +Now let's compare three different versions, one that runs in a single process: + +```julia-repl +julia> advection_serial!(q, u) = advection_chunk!(q, u, 1:size(q,1), 1:size(q,2), 1:size(q,3)-1); +``` + +one that uses [`@distributed`](@ref): + +```julia-repl +julia> function advection_parallel!(q, u) + for t = 1:size(q,3)-1 + @sync @distributed for j = 1:size(q,2) + for i = 1:size(q,1) + q[i,j,t+1]= q[i,j,t] + u[i,j,t] + end + end + end + q + end; +``` + +and one that delegates in chunks: + +```julia-repl +julia> function advection_shared!(q, u) + @sync begin + for p in procs(q) + @async remotecall_wait(advection_shared_chunk!, p, q, u) + end + end + q + end; +``` + +If we create `SharedArray`s and time these functions, we get the following results (with `julia -p 4`): + +```julia-repl +julia> q = SharedArray{Float64,3}((500,500,500)); + +julia> u = SharedArray{Float64,3}((500,500,500)); +``` + +Run the functions once to JIT-compile and [`@time`](@ref) them on the second run: + +```julia-repl +julia> @time advection_serial!(q, u); +(irange,jrange,trange) = (1:500,1:500,1:499) + 830.220 milliseconds (216 allocations: 13820 bytes) + +julia> @time advection_parallel!(q, u); + 2.495 seconds (3999 k allocations: 289 MB, 2.09% gc time) + +julia> @time advection_shared!(q,u); + From worker 2: (irange,jrange,trange) = (1:500,1:125,1:499) + From worker 4: (irange,jrange,trange) = (1:500,251:375,1:499) + From worker 3: (irange,jrange,trange) = (1:500,126:250,1:499) + From worker 5: (irange,jrange,trange) = (1:500,376:500,1:499) + 238.119 milliseconds (2264 allocations: 169 KB) +``` + +The biggest advantage of `advection_shared!` is that it minimizes traffic among the workers, allowing +each to compute for an extended time on the assigned piece. + +### Shared Arrays and Distributed Garbage Collection + +Like remote references, shared arrays are also dependent on garbage collection on the creating +node to release references from all participating workers. Code which creates many short lived +shared array objects would benefit from explicitly finalizing these objects as soon as possible. +This results in both memory and file handles mapping the shared segment being released sooner. + +## ClusterManagers + +The launching, management and networking of Julia processes into a logical cluster is done via +cluster managers. A `ClusterManager` is responsible for + + * launching worker processes in a cluster environment + * managing events during the lifetime of each worker + * optionally, providing data transport + +A Julia cluster has the following characteristics: + + * The initial Julia process, also called the `master`, is special and has an `id` of 1. + * Only the `master` process can add or remove worker processes. + * All processes can directly communicate with each other. + +Connections between workers (using the in-built TCP/IP transport) is established in the following +manner: + + * [`addprocs`](@ref) is called on the master process with a `ClusterManager` object. + * [`addprocs`](@ref) calls the appropriate [`launch`](@ref) method which spawns required number + of worker processes on appropriate machines. + * Each worker starts listening on a free port and writes out its host and port information to [`stdout`](@ref). + * The cluster manager captures the [`stdout`](@ref) of each worker and makes it available to the + master process. + * The master process parses this information and sets up TCP/IP connections to each worker. + * Every worker is also notified of other workers in the cluster. + * Each worker connects to all workers whose `id` is less than the worker's own `id`. + * In this way a mesh network is established, wherein every worker is directly connected with every + other worker. + +While the default transport layer uses plain [`TCPSocket`](@ref), it is possible for a Julia cluster to +provide its own transport. + +Julia provides two in-built cluster managers: + + * `LocalManager`, used when [`addprocs()`](@ref) or [`addprocs(np::Integer)`](@ref) are called + * `SSHManager`, used when [`addprocs(hostnames::Array)`](@ref) is called with a list of hostnames + +`LocalManager` is used to launch additional workers on the same host, thereby leveraging multi-core +and multi-processor hardware. + +Thus, a minimal cluster manager would need to: + + * be a subtype of the abstract `ClusterManager` + * implement [`launch`](@ref), a method responsible for launching new workers + * implement [`manage`](@ref), which is called at various events during a worker's lifetime (for + example, sending an interrupt signal) + +[`addprocs(manager::FooManager)`](@ref addprocs) requires `FooManager` to implement: + +```julia +function launch(manager::FooManager, params::Dict, launched::Array, c::Condition) + [...] +end + +function manage(manager::FooManager, id::Integer, config::WorkerConfig, op::Symbol) + [...] +end +``` + +As an example let us see how the `LocalManager`, the manager responsible for starting workers +on the same host, is implemented: + +```julia +struct LocalManager <: ClusterManager + np::Integer +end + +function launch(manager::LocalManager, params::Dict, launched::Array, c::Condition) + [...] +end + +function manage(manager::LocalManager, id::Integer, config::WorkerConfig, op::Symbol) + [...] +end +``` + +The [`launch`](@ref) method takes the following arguments: + + * `manager::ClusterManager`: the cluster manager that [`addprocs`](@ref) is called with + * `params::Dict`: all the keyword arguments passed to [`addprocs`](@ref) + * `launched::Array`: the array to append one or more `WorkerConfig` objects to + * `c::Condition`: the condition variable to be notified as and when workers are launched + +The [`launch`](@ref) method is called asynchronously in a separate task. The termination of +this task signals that all requested workers have been launched. Hence the [`launch`](@ref) +function MUST exit as soon as all the requested workers have been launched. + +Newly launched workers are connected to each other and the master process in an all-to-all manner. +Specifying the command line argument `--worker[=]` results in the launched processes +initializing themselves as workers and connections being set up via TCP/IP sockets. + +All workers in a cluster share the same [cookie](@ref man-cluster-cookie) as the master. When the cookie is +unspecified, i.e, with the `--worker` option, the worker tries to read it from its standard input. + `LocalManager` and `SSHManager` both pass the cookie to newly launched workers via their + standard inputs. + +By default a worker will listen on a free port at the address returned by a call to [`getipaddr()`](@ref). +A specific address to listen on may be specified by optional argument `--bind-to bind_addr[:port]`. +This is useful for multi-homed hosts. + +As an example of a non-TCP/IP transport, an implementation may choose to use MPI, in which case +`--worker` must NOT be specified. Instead, newly launched workers should call `init_worker(cookie)` +before using any of the parallel constructs. + +For every worker launched, the [`launch`](@ref) method must add a `WorkerConfig` object (with +appropriate fields initialized) to `launched` + +```julia +mutable struct WorkerConfig + # Common fields relevant to all cluster managers + io::Union{IO, Nothing} + host::Union{AbstractString, Nothing} + port::Union{Integer, Nothing} + + # Used when launching additional workers at a host + count::Union{Int, Symbol, Nothing} + exename::Union{AbstractString, Cmd, Nothing} + exeflags::Union{Cmd, Nothing} + + # External cluster managers can use this to store information at a per-worker level + # Can be a dict if multiple fields need to be stored. + userdata::Any + + # SSHManager / SSH tunnel connections to workers + tunnel::Union{Bool, Nothing} + bind_addr::Union{AbstractString, Nothing} + sshflags::Union{Cmd, Nothing} + max_parallel::Union{Integer, Nothing} + + # Used by Local/SSH managers + connect_at::Any + + [...] +end +``` + +Most of the fields in `WorkerConfig` are used by the inbuilt managers. Custom cluster managers +would typically specify only `io` or `host` / `port`: + + * If `io` is specified, it is used to read host/port information. A Julia worker prints out its + bind address and port at startup. This allows Julia workers to listen on any free port available + instead of requiring worker ports to be configured manually. + * If `io` is not specified, `host` and `port` are used to connect. + * `count`, `exename` and `exeflags` are relevant for launching additional workers from a worker. + For example, a cluster manager may launch a single worker per node, and use that to launch additional + workers. + + * `count` with an integer value `n` will launch a total of `n` workers. + * `count` with a value of `:auto` will launch as many workers as the number of CPU threads (logical cores) on that machine. + * `exename` is the name of the `julia` executable including the full path. + * `exeflags` should be set to the required command line arguments for new workers. + * `tunnel`, `bind_addr`, `sshflags` and `max_parallel` are used when a ssh tunnel is required to + connect to the workers from the master process. + * `userdata` is provided for custom cluster managers to store their own worker-specific information. + +`manage(manager::FooManager, id::Integer, config::WorkerConfig, op::Symbol)` is called at different +times during the worker's lifetime with appropriate `op` values: + + * with `:register`/`:deregister` when a worker is added / removed from the Julia worker pool. + * with `:interrupt` when `interrupt(workers)` is called. The `ClusterManager` should signal the + appropriate worker with an interrupt signal. + * with `:finalize` for cleanup purposes. + +### Cluster Managers with Custom Transports + +Replacing the default TCP/IP all-to-all socket connections with a custom transport layer is a +little more involved. Each Julia process has as many communication tasks as the workers it is +connected to. For example, consider a Julia cluster of 32 processes in an all-to-all mesh network: + + * Each Julia process thus has 31 communication tasks. + * Each task handles all incoming messages from a single remote worker in a message-processing loop. + * The message-processing loop waits on an `IO` object (for example, a [`TCPSocket`](@ref) in the default + implementation), reads an entire message, processes it and waits for the next one. + * Sending messages to a process is done directly from any Julia task--not just communication tasks--again, + via the appropriate `IO` object. + +Replacing the default transport requires the new implementation to set up connections to remote +workers and to provide appropriate `IO` objects that the message-processing loops can wait on. +The manager-specific callbacks to be implemented are: + +```julia +connect(manager::FooManager, pid::Integer, config::WorkerConfig) +kill(manager::FooManager, pid::Int, config::WorkerConfig) +``` + +The default implementation (which uses TCP/IP sockets) is implemented as `connect(manager::ClusterManager, pid::Integer, config::WorkerConfig)`. + +`connect` should return a pair of `IO` objects, one for reading data sent from worker `pid`, and +the other to write data that needs to be sent to worker `pid`. Custom cluster managers can use +an in-memory `BufferStream` as the plumbing to proxy data between the custom, possibly non-`IO` +transport and Julia's in-built parallel infrastructure. + +A `BufferStream` is an in-memory [`IOBuffer`](@ref) which behaves like an `IO`--it is a stream which can +be handled asynchronously. + +The folder `clustermanager/0mq` in the [Examples repository](https://github.com/JuliaAttic/Examples) +contains an example of using ZeroMQ to connect Julia workers +in a star topology with a 0MQ broker in the middle. Note: The Julia processes are still all *logically* +connected to each other--any worker can message any other worker directly without any awareness +of 0MQ being used as the transport layer. + +When using custom transports: + + * Julia workers must NOT be started with `--worker`. Starting with `--worker` will result in the + newly launched workers defaulting to the TCP/IP socket transport implementation. + * For every incoming logical connection with a worker, `Base.process_messages(rd::IO, wr::IO)()` + must be called. This launches a new task that handles reading and writing of messages from/to + the worker represented by the `IO` objects. + * `init_worker(cookie, manager::FooManager)` *must* be called as part of worker process initialization. + * Field `connect_at::Any` in `WorkerConfig` can be set by the cluster manager when [`launch`](@ref) + is called. The value of this field is passed in all [`connect`](@ref) callbacks. Typically, + it carries information on *how to connect* to a worker. For example, the TCP/IP socket transport + uses this field to specify the `(host, port)` tuple at which to connect to a worker. + +`kill(manager, pid, config)` is called to remove a worker from the cluster. On the master process, +the corresponding `IO` objects must be closed by the implementation to ensure proper cleanup. +The default implementation simply executes an `exit()` call on the specified remote worker. + +The Examples folder `clustermanager/simple` is an example that shows a simple implementation using UNIX domain +sockets for cluster setup. + +### Network Requirements for LocalManager and SSHManager + +Julia clusters are designed to be executed on already secured environments on infrastructure such +as local laptops, departmental clusters, or even the cloud. This section covers network security +requirements for the inbuilt `LocalManager` and `SSHManager`: + + * The master process does not listen on any port. It only connects out to the workers. + * Each worker binds to only one of the local interfaces and listens on an ephemeral port number + assigned by the OS. + * `LocalManager`, used by `addprocs(N)`, by default binds only to the loopback interface. This means + that workers started later on remote hosts (or by anyone with malicious intentions) are unable + to connect to the cluster. An `addprocs(4)` followed by an `addprocs(["remote_host"])` will fail. + Some users may need to create a cluster comprising their local system and a few remote systems. + This can be done by explicitly requesting `LocalManager` to bind to an external network interface + via the `restrict` keyword argument: `addprocs(4; restrict=false)`. + * `SSHManager`, used by `addprocs(list_of_remote_hosts)`, launches workers on remote hosts via SSH. + By default SSH is only used to launch Julia workers. Subsequent master-worker and worker-worker + connections use plain, unencrypted TCP/IP sockets. The remote hosts must have passwordless login + enabled. Additional SSH flags or credentials may be specified via keyword argument `sshflags`. + * `addprocs(list_of_remote_hosts; tunnel=true, sshflags=)` is useful when + we wish to use SSH connections for master-worker too. A typical scenario for this is a local laptop + running the Julia REPL (i.e., the master) with the rest of the cluster on the cloud, say on Amazon + EC2. In this case only port 22 needs to be opened at the remote cluster coupled with SSH client + authenticated via public key infrastructure (PKI). Authentication credentials can be supplied + via `sshflags`, for example ```sshflags=`-i ` ```. + + In an all-to-all topology (the default), all workers connect to each other via plain TCP sockets. + The security policy on the cluster nodes must thus ensure free connectivity between workers for + the ephemeral port range (varies by OS). + + Securing and encrypting all worker-worker traffic (via SSH) or encrypting individual messages + can be done via a custom `ClusterManager`. + + * If you specify `multiplex=true` as an option to `addprocs`, SSH multiplexing is used to create + a tunnel between the master and workers. If you have configured SSH multiplexing on your own and + the connection has already been established, SSH multiplexing is used regardless of `multiplex` + option. If multiplexing is enabled, forwarding is set by using the existing connection + (`-O forward` option in ssh). This is beneficial if your servers require password authentication; + you can avoid authentication in Julia by logging in to the server ahead of `addprocs`. The control + socket will be located at `~/.ssh/julia-%r@%h:%p` during the session unless the existing multiplexing + connection is used. Note that bandwidth may be limited if you create multiple processes on a node + and enable multiplexing, because in that case processes share a single multiplexing TCP connection. + +### [Cluster Cookie](@id man-cluster-cookie) + +All processes in a cluster share the same cookie which, by default, is a randomly generated string +on the master process: + + * [`cluster_cookie()`](@ref) returns the cookie, while `cluster_cookie(cookie)()` sets + it and returns the new cookie. + * All connections are authenticated on both sides to ensure that only workers started by the master + are allowed to connect to each other. + * The cookie may be passed to the workers at startup via argument `--worker=`. If argument + `--worker` is specified without the cookie, the worker tries to read the cookie from its + standard input ([`stdin`](@ref)). The `stdin` is closed immediately after the cookie is retrieved. + * `ClusterManager`s can retrieve the cookie on the master by calling [`cluster_cookie()`](@ref). + Cluster managers not using the default TCP/IP transport (and hence not specifying `--worker`) + must call `init_worker(cookie, manager)` with the same cookie as on the master. + +Note that environments requiring higher levels of security can implement this via a custom `ClusterManager`. +For example, cookies can be pre-shared and hence not specified as a startup argument. + +## Specifying Network Topology (Experimental) + +The keyword argument `topology` passed to `addprocs` is used to specify how the workers must be +connected to each other: + + * `:all_to_all`, the default: all workers are connected to each other. + * `:master_worker`: only the driver process, i.e. `pid` 1, has connections to the workers. + * `:custom`: the `launch` method of the cluster manager specifies the connection topology via the + fields `ident` and `connect_idents` in `WorkerConfig`. A worker with a cluster-manager-provided + identity `ident` will connect to all workers specified in `connect_idents`. + +Keyword argument `lazy=true|false` only affects `topology` option `:all_to_all`. If `true`, the cluster +starts off with the master connected to all workers. Specific worker-worker connections are established +at the first remote invocation between two workers. This helps in reducing initial resources allocated for +intra-cluster communication. Connections are setup depending on the runtime requirements of a parallel +program. Default value for `lazy` is `true`. + +Currently, sending a message between unconnected workers results in an error. This behaviour, +as with the functionality and interface, should be considered experimental in nature and may change +in future releases. + +## Noteworthy external packages + +Outside of Julia parallelism there are plenty of external packages that should be mentioned. +For example [MPI.jl](https://github.com/JuliaParallel/MPI.jl) is a Julia wrapper for the `MPI` protocol, or +[DistributedArrays.jl](https://github.com/JuliaParallel/Distributedarrays.jl), as presented in [Shared Arrays](@ref). +A mention must be made of Julia's GPU programming ecosystem, which includes: + +1. Low-level (C kernel) based operations [OpenCL.jl](https://github.com/JuliaGPU/OpenCL.jl) and [CUDAdrv.jl](https://github.com/JuliaGPU/CUDAdrv.jl) which are respectively an OpenCL interface and a CUDA wrapper. + +2. Low-level (Julia Kernel) interfaces like [CUDAnative.jl](https://github.com/JuliaGPU/CUDAnative.jl) which is a Julia native CUDA implementation. + +3. High-level vendor-specific abstractions like [CuArrays.jl](https://github.com/JuliaGPU/CuArrays.jl) and [CLArrays.jl](https://github.com/JuliaGPU/CLArrays.jl) + +4. High-level libraries like [ArrayFire.jl](https://github.com/JuliaComputing/ArrayFire.jl) and [GPUArrays.jl](https://github.com/JuliaGPU/GPUArrays.jl) + + +In the following example we will use both `DistributedArrays.jl` and `CuArrays.jl` to distribute an array across multiple +processes by first casting it through `distribute()` and `CuArray()`. + +Remember when importing `DistributedArrays.jl` to import it across all processes using [`@everywhere`](@ref) + + +```julia-repl +$ ./julia -p 4 + +julia> addprocs() + +julia> @everywhere using DistributedArrays + +julia> using CuArrays + +julia> B = ones(10_000) ./ 2; + +julia> A = ones(10_000) .* π; + +julia> C = 2 .* A ./ B; + +julia> all(C .≈ 4*π) +true + +julia> typeof(C) +Array{Float64,1} + +julia> dB = distribute(B); + +julia> dA = distribute(A); + +julia> dC = 2 .* dA ./ dB; + +julia> all(dC .≈ 4*π) +true + +julia> typeof(dC) +DistributedArrays.DArray{Float64,1,Array{Float64,1}} + +julia> cuB = CuArray(B); + +julia> cuA = CuArray(A); + +julia> cuC = 2 .* cuA ./ cuB; + +julia> all(cuC .≈ 4*π); +true + +julia> typeof(cuC) +CuArray{Float64,1} +``` +Keep in mind that some Julia features are not currently supported by CUDAnative.jl[^2] , especially some functions like `sin` will need to be replaced with `CUDAnative.sin`(cc: @maleadt). + +In the following example we will use both `DistributedArrays.jl` and `CuArrays.jl` to distribute an array across multiple +processes and call a generic function on it. + +```julia +function power_method(M, v) + for i in 1:100 + v = M*v + v /= norm(v) + end + + return v, norm(M*v) / norm(v) # or (M*v) ./ v +end +``` + +`power_method` repeatedly creates a new vector and normalizes it. We have not specified any type signature in +function declaration, let's see if it works with the aforementioned datatypes: + +```julia-repl +julia> M = [2. 1; 1 1]; + +julia> v = rand(2) +2-element Array{Float64,1}: +0.40395 +0.445877 + +julia> power_method(M,v) +([0.850651, 0.525731], 2.618033988749895) + +julia> cuM = CuArray(M); + +julia> cuv = CuArray(v); + +julia> curesult = power_method(cuM, cuv); + +julia> typeof(curesult) +CuArray{Float64,1} + +julia> dM = distribute(M); + +julia> dv = distribute(v); + +julia> dC = power_method(dM, dv); + +julia> typeof(dC) +Tuple{DistributedArrays.DArray{Float64,1,Array{Float64,1}},Float64} +``` + +To end this short exposure to external packages, we can consider `MPI.jl`, a Julia wrapper +of the MPI protocol. As it would take too long to consider every inner function, it would be better +to simply appreciate the approach used to implement the protocol. + +Consider this toy script which simply calls each subprocess, instantiate its rank and when the master +process is reached, performs the ranks' sum + +```julia +import MPI + +MPI.Init() + +comm = MPI.COMM_WORLD +MPI.Barrier(comm) + +root = 0 +r = MPI.Comm_rank(comm) + +sr = MPI.Reduce(r, MPI.SUM, root, comm) + +if(MPI.Comm_rank(comm) == root) + @printf("sum of ranks: %s\n", sr) +end + +MPI.Finalize() +``` + +``` +mpirun -np 4 ./julia example.jl +``` + +[^1]: + In this context, MPI refers to the MPI-1 standard. Beginning with MPI-2, the MPI standards committee + introduced a new set of communication mechanisms, collectively referred to as Remote Memory Access + (RMA). The motivation for adding rma to the MPI standard was to facilitate one-sided communication + patterns. For additional information on the latest MPI standard, see . + +[^2]: + [Julia GPU man pages](http://juliagpu.github.io/CUDAnative.jl/stable/man/usage.html#Julia-support-1) diff --git a/codex/manual/multi-threading.md b/codex/manual/multi-threading.md new file mode 100644 index 0000000..952e7ac --- /dev/null +++ b/codex/manual/multi-threading.md @@ -0,0 +1,351 @@ +# [Multi-Threading](@id man-multithreading) + +Visit this [blog post](https://julialang.org/blog/2019/07/multithreading/) for a presentation +of Julia multi-threading features. + +## Starting Julia with multiple threads + +By default, Julia starts up with a single thread of execution. This can be verified by using the +command [`Threads.nthreads()`](@ref): + +```julia-repl +julia> Threads.nthreads() +1 +``` + +The number of execution threads is controlled either by using the +`-t`/`--threads` command line argument or by using the +[`JULIA_NUM_THREADS`](@ref JULIA_NUM_THREADS) environment variable. When both are +specified, then `-t`/`--threads` takes precedence. + +!!! compat "Julia 1.5" + The `-t`/`--threads` command line argument requires at least Julia 1.5. + In older versions you must use the environment variable instead. + +Lets start Julia with 4 threads: + +```bash +$ julia --threads 4 +``` + +Let's verify there are 4 threads at our disposal. + +```julia-repl +julia> Threads.nthreads() +4 +``` + +But we are currently on the master thread. To check, we use the function [`Threads.threadid`](@ref) + +```julia-repl +julia> Threads.threadid() +1 +``` + +!!! note + If you prefer to use the environment variable you can set it as follows in + Bash (Linux/macOS): + ```bash + export JULIA_NUM_THREADS=4 + ``` + C shell on Linux/macOS, CMD on Windows: + ```bash + set JULIA_NUM_THREADS=4 + ``` + Powershell on Windows: + ```powershell + $env:JULIA_NUM_THREADS=4 + ``` + Note that this must be done *before* starting Julia. + +!!! note + The number of threads specified with `-t`/`--threads` is propagated to worker processes + that are spawned using the `-p`/`--procs` or `--machine-file` command line options. + For example, `julia -p2 -t2` spawns 1 main process with 2 worker processes, and all + three processes have 2 threads enabled. For more fine grained control over worker + threads use [`addprocs`](@ref) and pass `-t`/`--threads` as `exeflags`. + +## Data-race freedom + +You are entirely responsible for ensuring that your program is data-race free, +and nothing promised here can be assumed if you do not observe that +requirement. The observed results may be highly unintuitive. + +The best way to ensure this is to acquire a lock around any access to data that +can be observed from multiple threads. For example, in most cases you should +use the following code pattern: + +```julia-repl +julia> lock(lk) do + use(a) + end + +julia> begin + lock(lk) + try + use(a) + finally + unlock(lk) + end + end +``` +where `lk` is a lock (e.g. `ReentrantLock()`) and `a` data. + +Additionally, Julia is not memory safe in the presence of a data race. Be very +careful about reading _any_ data if another thread might write to it! +Instead, always use the lock pattern above when changing data (such as assigning +to a global or closure variable) accessed by other threads. + +```julia +Thread 1: +global b = false +global a = rand() +global b = true + +Thread 2: +while !b; end +bad_read1(a) # it is NOT safe to access `a` here! + +Thread 3: +while !@isdefined(a); end +bad_read2(a) # it is NOT safe to access `a` here +``` + +## The `@threads` Macro + +Let's work a simple example using our native threads. Let us create an array of zeros: + +```jldoctest +julia> a = zeros(10) +10-element Vector{Float64}: + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 +``` + +Let us operate on this array simultaneously using 4 threads. We'll have each thread write its +thread ID into each location. + +Julia supports parallel loops using the [`Threads.@threads`](@ref) macro. This macro is affixed +in front of a `for` loop to indicate to Julia that the loop is a multi-threaded region: + +```julia-repl +julia> Threads.@threads for i = 1:10 + a[i] = Threads.threadid() + end +``` + +The iteration space is split among the threads, after which each thread writes its thread ID +to its assigned locations: + +```julia-repl +julia> a +10-element Array{Float64,1}: + 1.0 + 1.0 + 1.0 + 2.0 + 2.0 + 2.0 + 3.0 + 3.0 + 4.0 + 4.0 +``` + +Note that [`Threads.@threads`](@ref) does not have an optional reduction parameter like [`@distributed`](@ref). + +## Atomic Operations + +Julia supports accessing and modifying values *atomically*, that is, in a thread-safe way to avoid +[race conditions](https://en.wikipedia.org/wiki/Race_condition). A value (which must be of a primitive +type) can be wrapped as [`Threads.Atomic`](@ref) to indicate it must be accessed in this way. +Here we can see an example: + +```julia-repl +julia> i = Threads.Atomic{Int}(0); + +julia> ids = zeros(4); + +julia> old_is = zeros(4); + +julia> Threads.@threads for id in 1:4 + old_is[id] = Threads.atomic_add!(i, id) + ids[id] = id + end + +julia> old_is +4-element Array{Float64,1}: + 0.0 + 1.0 + 7.0 + 3.0 + +julia> ids +4-element Array{Float64,1}: + 1.0 + 2.0 + 3.0 + 4.0 +``` + +Had we tried to do the addition without the atomic tag, we might have gotten the +wrong answer due to a race condition. An example of what would happen if we didn't +avoid the race: + +```julia-repl +julia> using Base.Threads + +julia> nthreads() +4 + +julia> acc = Ref(0) +Base.RefValue{Int64}(0) + +julia> @threads for i in 1:1000 + acc[] += 1 + end + +julia> acc[] +926 + +julia> acc = Atomic{Int64}(0) +Atomic{Int64}(0) + +julia> @threads for i in 1:1000 + atomic_add!(acc, 1) + end + +julia> acc[] +1000 +``` + +!!! note + Not *all* primitive types can be wrapped in an `Atomic` tag. Supported types + are `Int8`, `Int16`, `Int32`, `Int64`, `Int128`, `UInt8`, `UInt16`, `UInt32`, + `UInt64`, `UInt128`, `Float16`, `Float32`, and `Float64`. Additionally, + `Int128` and `UInt128` are not supported on AAarch32 and ppc64le. + +## Side effects and mutable function arguments + +When using multi-threading we have to be careful when using functions that are not +[pure](https://en.wikipedia.org/wiki/Pure_function) as we might get a wrong answer. +For instance functions that have a +[name ending with `!`](@ref bang-convention) +by convention modify their arguments and thus are not pure. + +## @threadcall + +External libraries, such as those called via [`ccall`](@ref), pose a problem for +Julia's task-based I/O mechanism. +If a C library performs a blocking operation, that prevents the Julia scheduler +from executing any other tasks until the call returns. +(Exceptions are calls into custom C code that call back into Julia, which may then +yield, or C code that calls `jl_yield()`, the C equivalent of [`yield`](@ref).) + +The [`@threadcall`](@ref) macro provides a way to avoid stalling execution in such +a scenario. +It schedules a C function for execution in a separate thread. A threadpool with a +default size of 4 is used for this. The size of the threadpool is controlled via environment variable +`UV_THREADPOOL_SIZE`. While waiting for a free thread, and during function execution once a thread +is available, the requesting task (on the main Julia event loop) yields to other tasks. Note that +`@threadcall` does not return until the execution is complete. From a user point of view, it is +therefore a blocking call like other Julia APIs. + +It is very important that the called function does not call back into Julia, as it will segfault. + +`@threadcall` may be removed/changed in future versions of Julia. + +## Caveats + +At this time, most operations in the Julia runtime and standard libraries +can be used in a thread-safe manner, if the user code is data-race free. +However, in some areas work on stabilizing thread support is ongoing. +Multi-threaded programming has many inherent difficulties, and if a program +using threads exhibits unusual or undesirable behavior (e.g. crashes or +mysterious results), thread interactions should typically be suspected first. + +There are a few specific limitations and warnings to be aware of when using +threads in Julia: + + * Base collection types require manual locking if used simultaneously by + multiple threads where at least one thread modifies the collection + (common examples include `push!` on arrays, or inserting + items into a `Dict`). + * After a task starts running on a certain thread (e.g. via `@spawn`), it + will always be restarted on the same thread after blocking. In the future + this limitation will be removed, and tasks will migrate between threads. + * `@threads` currently uses a static schedule, using all threads and assigning + equal iteration counts to each. In the future the default schedule is likely + to change to be dynamic. + * The schedule used by `@spawn` is nondeterministic and should not be relied on. + * Compute-bound, non-memory-allocating tasks can prevent garbage collection from + running in other threads that are allocating memory. In these cases it may + be necessary to insert a manual call to `GC.safepoint()` to allow GC to run. + This limitation will be removed in the future. + * Avoid running top-level operations, e.g. `include`, or `eval` of type, + method, and module definitions in parallel. + * Be aware that finalizers registered by a library may break if threads are enabled. + This may require some transitional work across the ecosystem before threading + can be widely adopted with confidence. See the next section for further details. + +## Safe use of Finalizers + +Because finalizers can interrupt any code, they must be very careful in how +they interact with any global state. Unfortunately, the main reason that +finalizers are used is to update global state (a pure function is generally +rather pointless as a finalizer). This leads us to a bit of a conundrum. +There are a few approaches to dealing with this problem: + +1. When single-threaded, code could call the internal `jl_gc_enable_finalizers` + C function to prevent finalizers from being scheduled + inside a critical region. Internally, this is used inside some functions (such + as our C locks) to prevent recursion when doing certain operations (incremental + package loading, codegen, etc.). The combination of a lock and this flag + can be used to make finalizers safe. + +2. A second strategy, employed by Base in a couple places, is to explicitly + delay a finalizer until it may be able to acquire its lock non-recursively. + The following example demonstrates how this strategy could be applied to + `Distributed.finalize_ref`: + + ```julia + function finalize_ref(r::AbstractRemoteRef) + if r.where > 0 # Check if the finalizer is already run + if islocked(client_refs) || !trylock(client_refs) + # delay finalizer for later if we aren't free to acquire the lock + finalizer(finalize_ref, r) + return nothing + end + try # `lock` should always be followed by `try` + if r.where > 0 # Must check again here + # Do actual cleanup here + r.where = 0 + end + finally + unlock(client_refs) + end + end + nothing + end + ``` + +3. A related third strategy is to use a yield-free queue. We don't currently + have a lock-free queue implemented in Base, but + `Base.InvasiveLinkedListSynchronized{T}` is suitable. This can frequently be a + good strategy to use for code with event loops. For example, this strategy is + employed by `Gtk.jl` to manage lifetime ref-counting. In this approach, we + don't do any explicit work inside the `finalizer`, and instead add it to a queue + to run at a safer time. In fact, Julia's task scheduler already uses this, so + defining the finalizer as `x -> @spawn do_cleanup(x)` is one example of this + approach. Note however that this doesn't control which thread `do_cleanup` + runs on, so `do_cleanup` would still need to acquire a lock. That + doesn't need to be true if you implement your own queue, as you can explicitly + only drain that queue from your thread. diff --git a/make.jl b/make.jl index 4c5f977..51c1135 100644 --- a/make.jl +++ b/make.jl @@ -8,8 +8,7 @@ pushfirst!(DEPOT_PATH, joinpath(@__DIR__, "deps")) using Pkg Pkg.instantiate() -# using Documenter, DocumenterLaTeX -using Documenter +using Documenter, DocumenterLaTeX include("contrib/html_writer.jl") # Korean customize @@ -46,120 +45,160 @@ cd(joinpath(@__DIR__, "src")) do end end +# Korean text for makedocs +const t_sitename = "줄리아 언어" +const t_analytics = "UA-110655381-2" # juliakorea analytic ID +const t_html_canonical = "https://juliakorea.github.io/ko/latest/" + # Korean text in PAGES -const t_Home = "홈" -const t_Manual = "매뉴얼" +const t_Home = "홈" +const t_Manual = "매뉴얼" +const t_Julia_Documentation = "Julia Documentation" +const t_Base = "Base" +const t_Standard_Library = "Standard Library" +const t_Developer_Documentation = "Developer Documentation" + +Manual = [ + "manual/getting-started.md", + "manual/variables.md", + "manual/integers-and-floating-point-numbers.md", + "manual/mathematical-operations.md", + "manual/complex-and-rational-numbers.md", + "manual/strings.md", + "manual/functions.md", + "manual/control-flow.md", + "manual/variables-and-scoping.md", + "manual/types.md", + "manual/methods.md", + "manual/constructors.md", + "manual/conversion-and-promotion.md", + "manual/interfaces.md", + "manual/modules.md", + "manual/documentation.md", + "manual/metaprogramming.md", + "manual/arrays.md", + "manual/missing.md", + "manual/networking-and-streams.md", + "manual/parallel-computing.md", + "manual/asynchronous-programming.md", + "manual/multi-threading.md", + "manual/distributed-computing.md", + "manual/running-external-programs.md", + "manual/calling-c-and-fortran-code.md", + "manual/handling-operating-system-variation.md", + "manual/environment-variables.md", + "manual/embedding.md", + "manual/code-loading.md", + "manual/profile.md", + "manual/stacktraces.md", + "manual/performance-tips.md", + "manual/workflow-tips.md", + "manual/style-guide.md", + "manual/faq.md", + "manual/noteworthy-differences.md", + "manual/unicode-input.md", +] + +BaseDocs = [ + "base/base.md", + "base/collections.md", + "base/math.md", + "base/numbers.md", + "base/strings.md", + "base/arrays.md", + "base/parallel.md", + "base/multi-threading.md", + "base/constants.md", + "base/file.md", + "base/io-network.md", + "base/punctuation.md", + "base/sort.md", + "base/iterators.md", + "base/c.md", + "base/libc.md", + "base/stacktraces.md", + "base/simd-types.md", +] +StdlibDocs = [stdlib.targetfile for stdlib in STDLIB_DOCS] + +DevDocs = [ + "devdocs/reflection.md", + "Documentation of Julia's Internals" => [ + "devdocs/init.md", + "devdocs/ast.md", + "devdocs/types.md", + "devdocs/object.md", + "devdocs/eval.md", + "devdocs/callconv.md", + "devdocs/compiler.md", + "devdocs/functions.md", + "devdocs/cartesian.md", + "devdocs/meta.md", + "devdocs/subarrays.md", + "devdocs/isbitsunionarrays.md", + "devdocs/sysimg.md", + "devdocs/llvm.md", + "devdocs/stdio.md", + "devdocs/boundscheck.md", + "devdocs/locks.md", + "devdocs/offset-arrays.md", + "devdocs/require.md", + "devdocs/inference.md", + "devdocs/ssair.md", + "devdocs/gc-sa.md", + ], + "Developing/debugging Julia's C code" => [ + "devdocs/backtraces.md", + "devdocs/debuggingtips.md", + "devdocs/valgrind.md", + "devdocs/sanitizers.md", + ] +] + +# TRAVIS_TAG="1.5.1" julia make.jl pdf +const render_pdf = "pdf" in ARGS + +if render_pdf +include("tools/latex.jl") const PAGES = [ - t_Home => "index.md", + t_Manual => ["index.md", Manual...], + t_Base => BaseDocs, + t_Standard_Library => StdlibDocs, + t_Developer_Documentation => DevDocs, hide("NEWS.md"), - t_Manual => [ - "manual/getting-started.md", - "manual/variables.md", - "manual/integers-and-floating-point-numbers.md", - "manual/mathematical-operations.md", - "manual/complex-and-rational-numbers.md", - "manual/strings.md", - "manual/functions.md", - "manual/control-flow.md", - "manual/variables-and-scoping.md", - "manual/types.md", - "manual/methods.md", - "manual/constructors.md", - "manual/conversion-and-promotion.md", - "manual/interfaces.md", - "manual/modules.md", - "manual/documentation.md", - "manual/metaprogramming.md", - "manual/arrays.md", - "manual/missing.md", - "manual/networking-and-streams.md", - "manual/parallel-computing.md", - "manual/running-external-programs.md", - "manual/calling-c-and-fortran-code.md", - "manual/handling-operating-system-variation.md", - "manual/environment-variables.md", - "manual/embedding.md", - "manual/code-loading.md", - "manual/profile.md", - "manual/stacktraces.md", - "manual/performance-tips.md", - "manual/workflow-tips.md", - "manual/style-guide.md", - "manual/faq.md", - "manual/noteworthy-differences.md", - "manual/unicode-input.md", - ], - "Base" => [ - "base/base.md", - "base/collections.md", - "base/math.md", - "base/numbers.md", - "base/strings.md", - "base/arrays.md", - "base/parallel.md", - "base/multi-threading.md", - "base/constants.md", - "base/file.md", - "base/io-network.md", - "base/punctuation.md", - "base/sort.md", - "base/iterators.md", - "base/c.md", - "base/libc.md", - "base/stacktraces.md", - "base/simd-types.md", - ], - "Standard Library" => - [stdlib.targetfile for stdlib in STDLIB_DOCS], - "Developer Documentation" => [ - "devdocs/reflection.md", - "Documentation of Julia's Internals" => [ - "devdocs/init.md", - "devdocs/ast.md", - "devdocs/types.md", - "devdocs/object.md", - "devdocs/eval.md", - "devdocs/callconv.md", - "devdocs/compiler.md", - "devdocs/functions.md", - "devdocs/cartesian.md", - "devdocs/meta.md", - "devdocs/subarrays.md", - "devdocs/isbitsunionarrays.md", - "devdocs/sysimg.md", - "devdocs/llvm.md", - "devdocs/stdio.md", - "devdocs/boundscheck.md", - "devdocs/locks.md", - "devdocs/offset-arrays.md", - "devdocs/require.md", - "devdocs/inference.md", - "devdocs/ssair.md", - "devdocs/gc-sa.md", - ], - "Developing/debugging Julia's C code" => [ - "devdocs/backtraces.md", - "devdocs/debuggingtips.md", - "devdocs/valgrind.md", - "devdocs/sanitizers.md", - ] - ], ] +else +const PAGES = [ + t_Julia_Documentation => "index.md", + hide("NEWS.md"), + t_Manual => Manual, + t_Base => BaseDocs, + t_Standard_Library => StdlibDocs, + t_Developer_Documentation => DevDocs, +] +end for stdlib in STDLIB_DOCS @eval using $(stdlib.stdlib) end -const render_pdf = "pdf" in ARGS let r = r"buildroot=(.+)", i = findfirst(x -> occursin(r, x), ARGS) global const buildroot = i === nothing ? (@__DIR__) : first(match(r, ARGS[i]).captures) end -# Korean text for makedocs -const t_sitename = "줄리아 언어" -const t_analytics = "UA-110655381-2" # juliakorea analytic ID -const t_html_canonical = "https://juliakorea.github.io/ko/latest/" +const format = if render_pdf + LaTeX( + platform = "texplatform=docker" in ARGS ? "docker" : "native" + ) +else + Documenter.HTML( + prettyurls = !("local" in ARGS), + canonical = t_html_canonical, + analytics = t_analytics, + assets = ["assets/julia-manual.css", ], + ) +end makedocs( build = joinpath(pwd(), "local" in ARGS ? "_build_local" : "_build/html/ko/latest"), @@ -170,12 +209,7 @@ makedocs( linkcheck_ignore = ["https://bugs.kde.org/show_bug.cgi?id=136779"], # fails to load from nanosoldier? strict = false, # true, checkdocs = :none, - format = Documenter.HTML( - prettyurls = !("local" in ARGS), - canonical = t_html_canonical, - analytics = t_analytics, - assets = ["assets/julia-manual.css", ], - ), + format = format, sitename = t_sitename, authors = "The Julia Project", pages = PAGES, diff --git a/src/index.md b/src/index.md index fe6040d..4c3214a 100644 --- a/src/index.md +++ b/src/index.md @@ -33,10 +33,7 @@ Markdown.parse(String(take!(io))) - Julia 중국(juliacn) 문서 [http://docs.juliacn.com/latest/](https://translate.google.com/translate?sl=zh-CN&tl=ko&u=http%3A%2F%2Fdocs.juliacn.com%2Flatest%2F) ```@eval -release = isempty(VERSION.prerelease) -file = release ? "julia-$(VERSION).pdf" : - "julia-$(VERSION.major).$(VERSION.minor).$(VERSION.patch)-$(first(VERSION.prerelease)).pdf" -url = "https://raw.githubusercontent.com/JuliaLang/docs.julialang.org/assets/$(file)" +file = url = "julia-1.5.1.pdf" import Markdown Markdown.parse(""" !!! note diff --git a/src/manual/asynchronous-programming.md b/src/manual/asynchronous-programming.md new file mode 100644 index 0000000..1791d4b --- /dev/null +++ b/src/manual/asynchronous-programming.md @@ -0,0 +1,337 @@ +# [Asynchronous Programming](@id man-asynchronous) + +When a program needs to interact with the outside world, for example communicating +with another machine over the internet, operations in the program may need to +happen in an unpredictable order. +Say your program needs to download a file. We would like to initiate the download +operation, perform other operations while we wait for it to complete, and then +resume the code that needs the downloaded file when it is available. +This sort of scenario falls in the domain of asynchronous programming, sometimes +also referred to as concurrent programming (since, conceptually, multiple things +are happening at once). + +To address these scenarios, Julia provides [`Task`](@ref)s (also known by several other +names, such as symmetric coroutines, lightweight threads, cooperative multitasking, +or one-shot continuations). +When a piece of computing work (in practice, executing a particular function) is designated as +a [`Task`](@ref), it becomes possible to interrupt it by switching to another [`Task`](@ref). +The original [`Task`](@ref) can later be resumed, at which point it will pick up right where it +left off. At first, this may seem similar to a function call. However there are two key differences. +First, switching tasks does not use any space, so any number of task switches can occur without +consuming the call stack. Second, switching among tasks can occur in any order, unlike function +calls, where the called function must finish executing before control returns to the calling function. + +## Basic `Task` operations + +You can think of a `Task` as a handle to a unit of computational work to be performed. +It has a create-start-run-finish lifecycle. +Tasks are created by calling the `Task` constructor on a 0-argument function to run, +or using the [`@task`](@ref) macro: + +```julia-repl +julia> t = @task begin; sleep(5); println("done"); end +Task (runnable) @0x00007f13a40c0eb0 +``` + +`@task x` is equivalent to `Task(()->x)`. + +This task will wait for five seconds, and then print `done`. However, it has not +started running yet. We can run it whenever we're ready by calling [`schedule`](@ref): + +```julia-repl +julia> schedule(t); +``` + +If you try this in the REPL, you will see that `schedule` returns immediately. +That is because it simply adds `t` to an internal queue of tasks to run. +Then, the REPL will print the next prompt and wait for more input. +Waiting for keyboard input provides an opportunity for other tasks to run, +so at that point `t` will start. +`t` calls [`sleep`](@ref), which sets a timer and stops execution. +If other tasks have been scheduled, they could run then. +After five seconds, the timer fires and restarts `t`, and you will see `done` +printed. `t` is then finished. + +The [`wait`](@ref) function blocks the calling task until some other task finishes. +So for example if you type + +```julia-repl +julia> schedule(t); wait(t) +``` + +instead of only calling `schedule`, you will see a five second pause before +the next input prompt appears. That is because the REPL is waiting for `t` +to finish before proceeding. + +It is common to want to create a task and schedule it right away, so the +macro [`@async`](@ref) is provided for that purpose --- `@async x` is +equivalent to `schedule(@task x)`. + +## Communicating with Channels + +In some problems, +the various pieces of required work are not naturally related by function calls; there is no obvious +"caller" or "callee" among the jobs that need to be done. An example is the producer-consumer +problem, where one complex procedure is generating values and another complex procedure is consuming +them. The consumer cannot simply call a producer function to get a value, because the producer +may have more values to generate and so might not yet be ready to return. With tasks, the producer +and consumer can both run as long as they need to, passing values back and forth as necessary. + +Julia provides a [`Channel`](@ref) mechanism for solving this problem. +A [`Channel`](@ref) is a waitable first-in first-out queue which can have +multiple tasks reading from and writing to it. + +Let's define a producer task, which produces values via the [`put!`](@ref) call. +To consume values, we need to schedule the producer to run in a new task. A special [`Channel`](@ref) +constructor which accepts a 1-arg function as an argument can be used to run a task bound to a channel. +We can then [`take!`](@ref) values repeatedly from the channel object: + +```jldoctest producer +julia> function producer(c::Channel) + put!(c, "start") + for n=1:4 + put!(c, 2n) + end + put!(c, "stop") + end; + +julia> chnl = Channel(producer); + +julia> take!(chnl) +"start" + +julia> take!(chnl) +2 + +julia> take!(chnl) +4 + +julia> take!(chnl) +6 + +julia> take!(chnl) +8 + +julia> take!(chnl) +"stop" +``` + +One way to think of this behavior is that `producer` was able to return multiple times. Between +calls to [`put!`](@ref), the producer's execution is suspended and the consumer has control. + +The returned [`Channel`](@ref) can be used as an iterable object in a `for` loop, in which case the +loop variable takes on all the produced values. The loop is terminated when the channel is closed. + +```jldoctest producer +julia> for x in Channel(producer) + println(x) + end +start +2 +4 +6 +8 +stop +``` + +Note that we did not have to explicitly close the channel in the producer. This is because +the act of binding a [`Channel`](@ref) to a [`Task`](@ref) associates the open lifetime of +a channel with that of the bound task. The channel object is closed automatically when the task +terminates. Multiple channels can be bound to a task, and vice-versa. + +While the [`Task`](@ref) constructor expects a 0-argument function, the [`Channel`](@ref) +method that creates a task-bound channel expects a function that accepts a single argument of +type [`Channel`](@ref). A common pattern is for the producer to be parameterized, in which case a partial +function application is needed to create a 0 or 1 argument [anonymous function](@ref man-anonymous-functions). + +For [`Task`](@ref) objects this can be done either directly or by use of a convenience macro: + +```julia +function mytask(myarg) + ... +end + +taskHdl = Task(() -> mytask(7)) +# or, equivalently +taskHdl = @task mytask(7) +``` + +To orchestrate more advanced work distribution patterns, [`bind`](@ref) and [`schedule`](@ref) +can be used in conjunction with [`Task`](@ref) and [`Channel`](@ref) +constructors to explicitly link a set of channels with a set of producer/consumer tasks. + +### More on Channels + +A channel can be visualized as a pipe, i.e., it has a write end and a read end : + + * Multiple writers in different tasks can write to the same channel concurrently via [`put!`](@ref) + calls. + * Multiple readers in different tasks can read data concurrently via [`take!`](@ref) calls. + * As an example: + + ```julia + # Given Channels c1 and c2, + c1 = Channel(32) + c2 = Channel(32) + + # and a function `foo` which reads items from c1, processes the item read + # and writes a result to c2, + function foo() + while true + data = take!(c1) + [...] # process data + put!(c2, result) # write out result + end + end + + # we can schedule `n` instances of `foo` to be active concurrently. + for _ in 1:n + @async foo() + end + ``` + * Channels are created via the `Channel{T}(sz)` constructor. The channel will only hold objects + of type `T`. If the type is not specified, the channel can hold objects of any type. `sz` refers + to the maximum number of elements that can be held in the channel at any time. For example, `Channel(32)` + creates a channel that can hold a maximum of 32 objects of any type. A `Channel{MyType}(64)` can + hold up to 64 objects of `MyType` at any time. + * If a [`Channel`](@ref) is empty, readers (on a [`take!`](@ref) call) will block until data is available. + * If a [`Channel`](@ref) is full, writers (on a [`put!`](@ref) call) will block until space becomes available. + * [`isready`](@ref) tests for the presence of any object in the channel, while [`wait`](@ref) + waits for an object to become available. + * A [`Channel`](@ref) is in an open state initially. This means that it can be read from and written to + freely via [`take!`](@ref) and [`put!`](@ref) calls. [`close`](@ref) closes a [`Channel`](@ref). + On a closed [`Channel`](@ref), [`put!`](@ref) will fail. For example: + + ```julia-repl + julia> c = Channel(2); + + julia> put!(c, 1) # `put!` on an open channel succeeds + 1 + + julia> close(c); + + julia> put!(c, 2) # `put!` on a closed channel throws an exception. + ERROR: InvalidStateException("Channel is closed.",:closed) + Stacktrace: + [...] + ``` + + * [`take!`](@ref) and [`fetch`](@ref) (which retrieves but does not remove the value) on a closed + channel successfully return any existing values until it is emptied. Continuing the above example: + + ```julia-repl + julia> fetch(c) # Any number of `fetch` calls succeed. + 1 + + julia> fetch(c) + 1 + + julia> take!(c) # The first `take!` removes the value. + 1 + + julia> take!(c) # No more data available on a closed channel. + ERROR: InvalidStateException("Channel is closed.",:closed) + Stacktrace: + [...] + ``` + +Consider a simple example using channels for inter-task communication. We start 4 tasks to process +data from a single `jobs` channel. Jobs, identified by an id (`job_id`), are written to the channel. +Each task in this simulation reads a `job_id`, waits for a random amount of time and writes back +a tuple of `job_id` and the simulated time to the results channel. Finally all the `results` are +printed out. + +```julia-repl +julia> const jobs = Channel{Int}(32); + +julia> const results = Channel{Tuple}(32); + +julia> function do_work() + for job_id in jobs + exec_time = rand() + sleep(exec_time) # simulates elapsed time doing actual work + # typically performed externally. + put!(results, (job_id, exec_time)) + end + end; + +julia> function make_jobs(n) + for i in 1:n + put!(jobs, i) + end + end; + +julia> n = 12; + +julia> @async make_jobs(n); # feed the jobs channel with "n" jobs + +julia> for i in 1:4 # start 4 tasks to process requests in parallel + @async do_work() + end + +julia> @elapsed while n > 0 # print out results + job_id, exec_time = take!(results) + println("$job_id finished in $(round(exec_time; digits=2)) seconds") + global n = n - 1 + end +4 finished in 0.22 seconds +3 finished in 0.45 seconds +1 finished in 0.5 seconds +7 finished in 0.14 seconds +2 finished in 0.78 seconds +5 finished in 0.9 seconds +9 finished in 0.36 seconds +6 finished in 0.87 seconds +8 finished in 0.79 seconds +10 finished in 0.64 seconds +12 finished in 0.5 seconds +11 finished in 0.97 seconds +0.029772311 +``` + +## More task operations + +Task operations are built on a low-level primitive called [`yieldto`](@ref). +`yieldto(task, value)` suspends the current task, switches to the specified `task`, and causes +that task's last [`yieldto`](@ref) call to return the specified `value`. Notice that [`yieldto`](@ref) +is the only operation required to use task-style control flow; instead of calling and returning +we are always just switching to a different task. This is why this feature is also called "symmetric +coroutines"; each task is switched to and from using the same mechanism. + +[`yieldto`](@ref) is powerful, but most uses of tasks do not invoke it directly. Consider why +this might be. If you switch away from the current task, you will probably want to switch back +to it at some point, but knowing when to switch back, and knowing which task has the responsibility +of switching back, can require considerable coordination. For example, [`put!`](@ref) and [`take!`](@ref) +are blocking operations, which, when used in the context of channels maintain state to remember +who the consumers are. Not needing to manually keep track of the consuming task is what makes [`put!`](@ref) +easier to use than the low-level [`yieldto`](@ref). + +In addition to [`yieldto`](@ref), a few other basic functions are needed to use tasks effectively. + + * [`current_task`](@ref) gets a reference to the currently-running task. + * [`istaskdone`](@ref) queries whether a task has exited. + * [`istaskstarted`](@ref) queries whether a task has run yet. + * [`task_local_storage`](@ref) manipulates a key-value store specific to the current task. + +## Tasks and events + +Most task switches occur as a result of waiting for events such as I/O requests, and are performed +by a scheduler included in Julia Base. The scheduler maintains a queue of runnable tasks, +and executes an event loop that restarts tasks based on external events such as message arrival. + +The basic function for waiting for an event is [`wait`](@ref). Several objects implement [`wait`](@ref); +for example, given a `Process` object, [`wait`](@ref) will wait for it to exit. [`wait`](@ref) +is often implicit; for example, a [`wait`](@ref) can happen inside a call to [`read`](@ref) +to wait for data to be available. + +In all of these cases, [`wait`](@ref) ultimately operates on a [`Condition`](@ref) object, which +is in charge of queueing and restarting tasks. When a task calls [`wait`](@ref) on a [`Condition`](@ref), +the task is marked as non-runnable, added to the condition's queue, and switches to the scheduler. +The scheduler will then pick another task to run, or block waiting for external events. If all +goes well, eventually an event handler will call [`notify`](@ref) on the condition, which causes +tasks waiting for that condition to become runnable again. + +A task created explicitly by calling [`Task`](@ref) is initially not known to the scheduler. This +allows you to manage tasks manually using [`yieldto`](@ref) if you wish. However, when such +a task waits for an event, it still gets restarted automatically when the event happens, as you +would expect. diff --git a/src/manual/distributed-computing.md b/src/manual/distributed-computing.md new file mode 100644 index 0000000..e5b6e78 --- /dev/null +++ b/src/manual/distributed-computing.md @@ -0,0 +1,1404 @@ +# Multi-processing and Distributed Computing + +An implementation of distributed memory parallel computing is provided by module `Distributed` +as part of the standard library shipped with Julia. + +Most modern computers possess more than one CPU, and several computers can be combined together +in a cluster. Harnessing the power of these multiple CPUs allows many computations to be completed +more quickly. There are two major factors that influence performance: the speed of the CPUs themselves, +and the speed of their access to memory. In a cluster, it's fairly obvious that a given CPU will +have fastest access to the RAM within the same computer (node). Perhaps more surprisingly, similar +issues are relevant on a typical multicore laptop, due to differences in the speed of main memory +and the [cache](https://www.akkadia.org/drepper/cpumemory.pdf). Consequently, a good multiprocessing +environment should allow control over the "ownership" of a chunk of memory by a particular CPU. +Julia provides a multiprocessing environment based on message passing to allow programs to run +on multiple processes in separate memory domains at once. + +Julia's implementation of message passing is different from other environments such as MPI[^1]. +Communication in Julia is generally "one-sided", meaning that the programmer needs to explicitly +manage only one process in a two-process operation. Furthermore, these operations typically do +not look like "message send" and "message receive" but rather resemble higher-level operations +like calls to user functions. + +Distributed programming in Julia is built on two primitives: *remote references* and *remote calls*. +A remote reference is an object that can be used from any process to refer to an object stored +on a particular process. A remote call is a request by one process to call a certain function +on certain arguments on another (possibly the same) process. + +Remote references come in two flavors: [`Future`](@ref Distributed.Future) and [`RemoteChannel`](@ref). + +A remote call returns a [`Future`](@ref Distributed.Future) to its result. Remote calls return immediately; the process +that made the call proceeds to its next operation while the remote call happens somewhere else. +You can wait for a remote call to finish by calling [`wait`](@ref) on the returned [`Future`](@ref Distributed.Future), +and you can obtain the full value of the result using [`fetch`](@ref). + +On the other hand, [`RemoteChannel`](@ref) s are rewritable. For example, multiple processes can +co-ordinate their processing by referencing the same remote `Channel`. + +Each process has an associated identifier. The process providing the interactive Julia prompt +always has an `id` equal to 1. The processes used by default for parallel operations are referred +to as "workers". When there is only one process, process 1 is considered a worker. Otherwise, +workers are considered to be all processes other than process 1. As a result, adding 2 or more +processes is required to gain benefits from parallel processing methods like [`pmap`](@ref). Adding +a single process is beneficial if you just wish to do other things in the main process while a long +computation is running on the worker. + +Let's try this out. Starting with `julia -p n` provides `n` worker processes on the local machine. +Generally it makes sense for `n` to equal the number of CPU threads (logical cores) on the machine. Note that the `-p` +argument implicitly loads module `Distributed`. + + +```julia +$ ./julia -p 2 + +julia> r = remotecall(rand, 2, 2, 2) +Future(2, 1, 4, nothing) + +julia> s = @spawnat 2 1 .+ fetch(r) +Future(2, 1, 5, nothing) + +julia> fetch(s) +2×2 Array{Float64,2}: + 1.18526 1.50912 + 1.16296 1.60607 +``` + +The first argument to [`remotecall`](@ref) is the function to call. Most parallel programming +in Julia does not reference specific processes or the number of processes available, but [`remotecall`](@ref) +is considered a low-level interface providing finer control. The second argument to [`remotecall`](@ref) +is the `id` of the process that will do the work, and the remaining arguments will be passed to +the function being called. + +As you can see, in the first line we asked process 2 to construct a 2-by-2 random matrix, and +in the second line we asked it to add 1 to it. The result of both calculations is available in +the two futures, `r` and `s`. The [`@spawnat`](@ref) macro evaluates the expression in the second +argument on the process specified by the first argument. + +Occasionally you might want a remotely-computed value immediately. This typically happens when +you read from a remote object to obtain data needed by the next local operation. The function +[`remotecall_fetch`](@ref) exists for this purpose. It is equivalent to `fetch(remotecall(...))` +but is more efficient. + +```julia-repl +julia> remotecall_fetch(getindex, 2, r, 1, 1) +0.18526337335308085 +``` + +Remember that [`getindex(r,1,1)`](@ref) is [equivalent](@ref man-array-indexing) to `r[1,1]`, so this call fetches +the first element of the future `r`. + +To make things easier, the symbol `:any` can be passed to [`@spawnat`](@ref), which picks where to do +the operation for you: + +```julia-repl +julia> r = @spawnat :any rand(2,2) +Future(2, 1, 4, nothing) + +julia> s = @spawnat :any 1 .+ fetch(r) +Future(3, 1, 5, nothing) + +julia> fetch(s) +2×2 Array{Float64,2}: + 1.38854 1.9098 + 1.20939 1.57158 +``` + +Note that we used `1 .+ fetch(r)` instead of `1 .+ r`. This is because we do not know where the +code will run, so in general a [`fetch`](@ref) might be required to move `r` to the process +doing the addition. In this case, [`@spawnat`](@ref) is smart enough to perform the computation +on the process that owns `r`, so the [`fetch`](@ref) will be a no-op (no work is done). + +(It is worth noting that [`@spawnat`](@ref) is not built-in but defined in Julia as a [macro](@ref man-macros). +It is possible to define your own such constructs.) + +An important thing to remember is that, once fetched, a [`Future`](@ref Distributed.Future) will cache its value +locally. Further [`fetch`](@ref) calls do not entail a network hop. Once all referencing [`Future`](@ref Distributed.Future)s +have fetched, the remote stored value is deleted. + +[`@async`](@ref) is similar to [`@spawnat`](@ref), but only runs tasks on the local process. We +use it to create a "feeder" task for each process. Each task picks the next index that needs to +be computed, then waits for its process to finish, then repeats until we run out of indices. Note +that the feeder tasks do not begin to execute until the main task reaches the end of the [`@sync`](@ref) +block, at which point it surrenders control and waits for all the local tasks to complete before +returning from the function. +As for v0.7 and beyond, the feeder tasks are able to share state via `nextidx` because +they all run on the same process. +Even if `Tasks` are scheduled cooperatively, locking may still be required in some contexts, as in +[asynchronous I/O](@ref faq-async-io). +This means context switches only occur at well-defined points: in this case, +when [`remotecall_fetch`](@ref) is called. This is the current state of implementation and it may change +for future Julia versions, as it is intended to make it possible to run up to N `Tasks` on M `Process`, aka +[M:N Threading](https://en.wikipedia.org/wiki/Thread_(computing)#Models). Then a lock acquiring\releasing +model for `nextidx` will be needed, as it is not safe to let multiple processes read-write a resource at +the same time. + + + +## [Code Availability and Loading Packages](@id code-availability) + +Your code must be available on any process that runs it. For example, type the following into +the Julia prompt: + +```julia-repl +julia> function rand2(dims...) + return 2*rand(dims...) + end + +julia> rand2(2,2) +2×2 Array{Float64,2}: + 0.153756 0.368514 + 1.15119 0.918912 + +julia> fetch(@spawnat :any rand2(2,2)) +ERROR: RemoteException(2, CapturedException(UndefVarError(Symbol("#rand2")) +Stacktrace: +[...] +``` + +Process 1 knew about the function `rand2`, but process 2 did not. + +Most commonly you'll be loading code from files or packages, and you have a considerable amount +of flexibility in controlling which processes load code. Consider a file, `DummyModule.jl`, +containing the following code: + +```julia +module DummyModule + +export MyType, f + +mutable struct MyType + a::Int +end + +f(x) = x^2+1 + +println("loaded") + +end +``` + +In order to refer to `MyType` across all processes, `DummyModule.jl` needs to be loaded on +every process. Calling `include("DummyModule.jl")` loads it only on a single process. To +load it on every process, use the [`@everywhere`](@ref) macro (starting Julia with `julia -p +2`): + +```julia-repl +julia> @everywhere include("DummyModule.jl") +loaded + From worker 3: loaded + From worker 2: loaded +``` + +As usual, this does not bring `DummyModule` into scope on any of the process, which requires +`using` or `import`. Moreover, when `DummyModule` is brought into scope on one process, it +is not on any other: + +```julia-repl +julia> using .DummyModule + +julia> MyType(7) +MyType(7) + +julia> fetch(@spawnat 2 MyType(7)) +ERROR: On worker 2: +UndefVarError: MyType not defined +⋮ + +julia> fetch(@spawnat 2 DummyModule.MyType(7)) +MyType(7) +``` + +However, it's still possible, for instance, to send a `MyType` to a process which has loaded +`DummyModule` even if it's not in scope: + +```julia-repl +julia> put!(RemoteChannel(2), MyType(7)) +RemoteChannel{Channel{Any}}(2, 1, 13) +``` + +A file can also be preloaded on multiple processes at startup with the `-L` flag, and a +driver script can be used to drive the computation: + +``` +julia -p -L file1.jl -L file2.jl driver.jl +``` + +The Julia process running the driver script in the example above has an `id` equal to 1, just +like a process providing an interactive prompt. + +Finally, if `DummyModule.jl` is not a standalone file but a package, then `using +DummyModule` will _load_ `DummyModule.jl` on all processes, but only bring it into scope on +the process where `using` was called. + +## Starting and managing worker processes + +The base Julia installation has in-built support for two types of clusters: + + * A local cluster specified with the `-p` option as shown above. + * A cluster spanning machines using the `--machine-file` option. This uses a passwordless `ssh` login + to start Julia worker processes (from the same path as the current host) on the specified machines. Each machine definition + takes the form `[count*][user@]host[:port] [bind_addr[:port]]`. `user` defaults to current user, + `port` to the standard ssh port. `count` is the number of workers to spawn on the node, and defaults + to 1. The optional `bind-to bind_addr[:port]` specifies the IP address and port that other workers + should use to connect to this worker. + +Functions [`addprocs`](@ref), [`rmprocs`](@ref), [`workers`](@ref), and others are available +as a programmatic means of adding, removing and querying the processes in a cluster. + +```julia-repl +julia> using Distributed + +julia> addprocs(2) +2-element Array{Int64,1}: + 2 + 3 +``` + +Module `Distributed` must be explicitly loaded on the master process before invoking [`addprocs`](@ref). +It is automatically made available on the worker processes. + +Note that workers do not run a `~/.julia/config/startup.jl` startup script, nor do they synchronize +their global state (such as global variables, new method definitions, and loaded modules) with any +of the other running processes. You may use `addprocs(exeflags="--project")` to initialize a worker with +a particular environment, and then `@everywhere using ` or `@everywhere include("file.jl")`. + +Other types of clusters can be supported by writing your own custom `ClusterManager`, as described +below in the [ClusterManagers](@ref) section. + +## Data Movement + +Sending messages and moving data constitute most of the overhead in a distributed program. Reducing +the number of messages and the amount of data sent is critical to achieving performance and scalability. +To this end, it is important to understand the data movement performed by Julia's various distributed +programming constructs. + +[`fetch`](@ref) can be considered an explicit data movement operation, since it directly asks +that an object be moved to the local machine. [`@spawnat`](@ref) (and a few related constructs) +also moves data, but this is not as obvious, hence it can be called an implicit data movement +operation. Consider these two approaches to constructing and squaring a random matrix: + +Method 1: + +```julia-repl +julia> A = rand(1000,1000); + +julia> Bref = @spawnat :any A^2; + +[...] + +julia> fetch(Bref); +``` + +Method 2: + +```julia-repl +julia> Bref = @spawnat :any rand(1000,1000)^2; + +[...] + +julia> fetch(Bref); +``` + +The difference seems trivial, but in fact is quite significant due to the behavior of [`@spawnat`](@ref). +In the first method, a random matrix is constructed locally, then sent to another process where +it is squared. In the second method, a random matrix is both constructed and squared on another +process. Therefore the second method sends much less data than the first. + +In this toy example, the two methods are easy to distinguish and choose from. However, in a real +program designing data movement might require more thought and likely some measurement. For example, +if the first process needs matrix `A` then the first method might be better. Or, if computing +`A` is expensive and only the current process has it, then moving it to another process might +be unavoidable. Or, if the current process has very little to do between the [`@spawnat`](@ref) +and `fetch(Bref)`, it might be better to eliminate the parallelism altogether. Or imagine `rand(1000,1000)` +is replaced with a more expensive operation. Then it might make sense to add another [`@spawnat`](@ref) +statement just for this step. + +## Global variables +Expressions executed remotely via `@spawnat`, or closures specified for remote execution using +`remotecall` may refer to global variables. Global bindings under module `Main` are treated +a little differently compared to global bindings in other modules. Consider the following code +snippet: + +```julia-repl +A = rand(10,10) +remotecall_fetch(()->sum(A), 2) +``` + +In this case [`sum`](@ref) MUST be defined in the remote process. +Note that `A` is a global variable defined in the local workspace. Worker 2 does not have a variable called +`A` under `Main`. The act of shipping the closure `()->sum(A)` to worker 2 results in `Main.A` being defined +on 2. `Main.A` continues to exist on worker 2 even after the call `remotecall_fetch` returns. Remote calls +with embedded global references (under `Main` module only) manage globals as follows: + +- New global bindings are created on destination workers if they are referenced as part of a remote call. + +- Global constants are declared as constants on remote nodes too. + +- Globals are re-sent to a destination worker only in the context of a remote call, and then only + if its value has changed. Also, the cluster does not synchronize global bindings across nodes. + For example: + + ```julia + A = rand(10,10) + remotecall_fetch(()->sum(A), 2) # worker 2 + A = rand(10,10) + remotecall_fetch(()->sum(A), 3) # worker 3 + A = nothing + ``` + + Executing the above snippet results in `Main.A` on worker 2 having a different value from + `Main.A` on worker 3, while the value of `Main.A` on node 1 is set to `nothing`. + +As you may have realized, while memory associated with globals may be collected when they are reassigned +on the master, no such action is taken on the workers as the bindings continue to be valid. +[`clear!`](@ref) can be used to manually reassign specific globals on remote nodes to `nothing` once +they are no longer required. This will release any memory associated with them as part of a regular garbage +collection cycle. + +Thus programs should be careful referencing globals in remote calls. In fact, it is preferable to avoid them +altogether if possible. If you must reference globals, consider using `let` blocks to localize global variables. + +For example: + +```julia-repl +julia> A = rand(10,10); + +julia> remotecall_fetch(()->A, 2); + +julia> B = rand(10,10); + +julia> let B = B + remotecall_fetch(()->B, 2) + end; + +julia> @fetchfrom 2 InteractiveUtils.varinfo() +name size summary +––––––––– ––––––––– –––––––––––––––––––––– +A 800 bytes 10×10 Array{Float64,2} +Base Module +Core Module +Main Module +``` + +As can be seen, global variable `A` is defined on worker 2, but `B` is captured as a local variable +and hence a binding for `B` does not exist on worker 2. + + +## Parallel Map and Loops + +Fortunately, many useful parallel computations do not require data movement. A common example +is a Monte Carlo simulation, where multiple processes can handle independent simulation trials +simultaneously. We can use [`@spawnat`](@ref) to flip coins on two processes. First, write the following +function in `count_heads.jl`: + +```julia +function count_heads(n) + c::Int = 0 + for i = 1:n + c += rand(Bool) + end + c +end +``` + +The function `count_heads` simply adds together `n` random bits. Here is how we can perform some +trials on two machines, and add together the results: + +```julia-repl +julia> @everywhere include_string(Main, $(read("count_heads.jl", String)), "count_heads.jl") + +julia> a = @spawnat :any count_heads(100000000) +Future(2, 1, 6, nothing) + +julia> b = @spawnat :any count_heads(100000000) +Future(3, 1, 7, nothing) + +julia> fetch(a)+fetch(b) +100001564 +``` + +This example demonstrates a powerful and often-used parallel programming pattern. Many iterations +run independently over several processes, and then their results are combined using some function. +The combination process is called a *reduction*, since it is generally tensor-rank-reducing: a +vector of numbers is reduced to a single number, or a matrix is reduced to a single row or column, +etc. In code, this typically looks like the pattern `x = f(x,v[i])`, where `x` is the accumulator, +`f` is the reduction function, and the `v[i]` are the elements being reduced. It is desirable +for `f` to be associative, so that it does not matter what order the operations are performed +in. + +Notice that our use of this pattern with `count_heads` can be generalized. We used two explicit +[`@spawnat`](@ref) statements, which limits the parallelism to two processes. To run on any number +of processes, we can use a *parallel for loop*, running in distributed memory, which can be written +in Julia using [`@distributed`](@ref) like this: + +```julia +nheads = @distributed (+) for i = 1:200000000 + Int(rand(Bool)) +end +``` + +This construct implements the pattern of assigning iterations to multiple processes, and combining +them with a specified reduction (in this case `(+)`). The result of each iteration is taken as +the value of the last expression inside the loop. The whole parallel loop expression itself evaluates +to the final answer. + +Note that although parallel for loops look like serial for loops, their behavior is dramatically +different. In particular, the iterations do not happen in a specified order, and writes to variables +or arrays will not be globally visible since iterations run on different processes. Any variables +used inside the parallel loop will be copied and broadcast to each process. + +For example, the following code will not work as intended: + +```julia +a = zeros(100000) +@distributed for i = 1:100000 + a[i] = i +end +``` + +This code will not initialize all of `a`, since each process will have a separate copy of it. +Parallel for loops like these must be avoided. Fortunately, [Shared Arrays](@ref man-shared-arrays) can be used +to get around this limitation: + +```julia +using SharedArrays + +a = SharedArray{Float64}(10) +@distributed for i = 1:10 + a[i] = i +end +``` + +Using "outside" variables in parallel loops is perfectly reasonable if the variables are read-only: + +```julia +a = randn(1000) +@distributed (+) for i = 1:100000 + f(a[rand(1:end)]) +end +``` + +Here each iteration applies `f` to a randomly-chosen sample from a vector `a` shared by all processes. + +As you could see, the reduction operator can be omitted if it is not needed. In that case, the +loop executes asynchronously, i.e. it spawns independent tasks on all available workers and returns +an array of [`Future`](@ref Distributed.Future) immediately without waiting for completion. The caller can wait for +the [`Future`](@ref Distributed.Future) completions at a later point by calling [`fetch`](@ref) on them, or wait +for completion at the end of the loop by prefixing it with [`@sync`](@ref), like `@sync @distributed for`. + +In some cases no reduction operator is needed, and we merely wish to apply a function to all integers +in some range (or, more generally, to all elements in some collection). This is another useful +operation called *parallel map*, implemented in Julia as the [`pmap`](@ref) function. For example, +we could compute the singular values of several large random matrices in parallel as follows: + +```julia-repl +julia> M = Matrix{Float64}[rand(1000,1000) for i = 1:10]; + +julia> pmap(svdvals, M); +``` + +Julia's [`pmap`](@ref) is designed for the case where each function call does a large amount +of work. In contrast, `@distributed for` can handle situations where each iteration is tiny, perhaps +merely summing two numbers. Only worker processes are used by both [`pmap`](@ref) and `@distributed for` +for the parallel computation. In case of `@distributed for`, the final reduction is done on the calling +process. + +## Remote References and AbstractChannels + +Remote references always refer to an implementation of an `AbstractChannel`. + +A concrete implementation of an `AbstractChannel` (like `Channel`), is required to implement +[`put!`](@ref), [`take!`](@ref), [`fetch`](@ref), [`isready`](@ref) and [`wait`](@ref). +The remote object referred to by a [`Future`](@ref Distributed.Future) is stored in a `Channel{Any}(1)`, i.e., a +`Channel` of size 1 capable of holding objects of `Any` type. + +[`RemoteChannel`](@ref), which is rewritable, can point to any type and size of channels, or any +other implementation of an `AbstractChannel`. + +The constructor `RemoteChannel(f::Function, pid)()` allows us to construct references to channels +holding more than one value of a specific type. `f` is a function executed on `pid` and it must +return an `AbstractChannel`. + +For example, `RemoteChannel(()->Channel{Int}(10), pid)`, will return a reference to a channel +of type `Int` and size 10. The channel exists on worker `pid`. + +Methods [`put!`](@ref), [`take!`](@ref), [`fetch`](@ref), [`isready`](@ref) and [`wait`](@ref) +on a [`RemoteChannel`](@ref) are proxied onto the backing store on the remote process. + +[`RemoteChannel`](@ref) can thus be used to refer to user implemented `AbstractChannel` objects. +A simple example of this is provided in `dictchannel.jl` in the +[Examples repository](https://github.com/JuliaAttic/Examples), which uses a dictionary as its +remote store. + + +## Channels and RemoteChannels + + * A [`Channel`](@ref) is local to a process. Worker 2 cannot directly refer to a [`Channel`](@ref) on worker 3 and + vice-versa. A [`RemoteChannel`](@ref), however, can put and take values across workers. + * A [`RemoteChannel`](@ref) can be thought of as a *handle* to a [`Channel`](@ref). + * The process id, `pid`, associated with a [`RemoteChannel`](@ref) identifies the process where + the backing store, i.e., the backing [`Channel`](@ref) exists. + * Any process with a reference to a [`RemoteChannel`](@ref) can put and take items from the channel. + Data is automatically sent to (or retrieved from) the process a [`RemoteChannel`](@ref) is associated + with. + * Serializing a [`Channel`](@ref) also serializes any data present in the channel. Deserializing it therefore + effectively makes a copy of the original object. + * On the other hand, serializing a [`RemoteChannel`](@ref) only involves the serialization of an + identifier that identifies the location and instance of [`Channel`](@ref) referred to by the handle. A + deserialized [`RemoteChannel`](@ref) object (on any worker), therefore also points to the same + backing store as the original. + +The channels example from above can be modified for interprocess communication, +as shown below. + +We start 4 workers to process a single `jobs` remote channel. Jobs, identified by an id (`job_id`), +are written to the channel. Each remotely executing task in this simulation reads a `job_id`, +waits for a random amount of time and writes back a tuple of `job_id`, time taken and its own +`pid` to the results channel. Finally all the `results` are printed out on the master process. + +```julia-repl +julia> addprocs(4); # add worker processes + +julia> const jobs = RemoteChannel(()->Channel{Int}(32)); + +julia> const results = RemoteChannel(()->Channel{Tuple}(32)); + +julia> @everywhere function do_work(jobs, results) # define work function everywhere + while true + job_id = take!(jobs) + exec_time = rand() + sleep(exec_time) # simulates elapsed time doing actual work + put!(results, (job_id, exec_time, myid())) + end + end + +julia> function make_jobs(n) + for i in 1:n + put!(jobs, i) + end + end; + +julia> n = 12; + +julia> @async make_jobs(n); # feed the jobs channel with "n" jobs + +julia> for p in workers() # start tasks on the workers to process requests in parallel + remote_do(do_work, p, jobs, results) + end + +julia> @elapsed while n > 0 # print out results + job_id, exec_time, where = take!(results) + println("$job_id finished in $(round(exec_time; digits=2)) seconds on worker $where") + global n = n - 1 + end +1 finished in 0.18 seconds on worker 4 +2 finished in 0.26 seconds on worker 5 +6 finished in 0.12 seconds on worker 4 +7 finished in 0.18 seconds on worker 4 +5 finished in 0.35 seconds on worker 5 +4 finished in 0.68 seconds on worker 2 +3 finished in 0.73 seconds on worker 3 +11 finished in 0.01 seconds on worker 3 +12 finished in 0.02 seconds on worker 3 +9 finished in 0.26 seconds on worker 5 +8 finished in 0.57 seconds on worker 4 +10 finished in 0.58 seconds on worker 2 +0.055971741 +``` + +### Remote References and Distributed Garbage Collection + +Objects referred to by remote references can be freed only when *all* held references +in the cluster are deleted. + +The node where the value is stored keeps track of which of the workers have a reference to it. +Every time a [`RemoteChannel`](@ref) or a (unfetched) [`Future`](@ref Distributed.Future) is serialized to a worker, +the node pointed to by the reference is notified. And every time a [`RemoteChannel`](@ref) or +a (unfetched) [`Future`](@ref Distributed.Future) is garbage collected locally, the node owning the value is again +notified. This is implemented in an internal cluster aware serializer. Remote references are only +valid in the context of a running cluster. Serializing and deserializing references to and from +regular `IO` objects is not supported. + +The notifications are done via sending of "tracking" messages--an "add reference" message when +a reference is serialized to a different process and a "delete reference" message when a reference +is locally garbage collected. + +Since [`Future`](@ref Distributed.Future)s are write-once and cached locally, the act of [`fetch`](@ref)ing a +[`Future`](@ref Distributed.Future) also updates reference tracking information on the node owning the value. + +The node which owns the value frees it once all references to it are cleared. + +With [`Future`](@ref Distributed.Future)s, serializing an already fetched [`Future`](@ref Distributed.Future) to a different node also +sends the value since the original remote store may have collected the value by this time. + +It is important to note that *when* an object is locally garbage collected depends on the size +of the object and the current memory pressure in the system. + +In case of remote references, the size of the local reference object is quite small, while the +value stored on the remote node may be quite large. Since the local object may not be collected +immediately, it is a good practice to explicitly call [`finalize`](@ref) on local instances +of a [`RemoteChannel`](@ref), or on unfetched [`Future`](@ref Distributed.Future)s. Since calling [`fetch`](@ref) +on a [`Future`](@ref Distributed.Future) also removes its reference from the remote store, this is not required on +fetched [`Future`](@ref Distributed.Future)s. Explicitly calling [`finalize`](@ref) results in an immediate message +sent to the remote node to go ahead and remove its reference to the value. + +Once finalized, a reference becomes invalid and cannot be used in any further calls. + + +## Local invocations + +Data is necessarily copied over to the remote node for execution. This is the case for both +remotecalls and when data is stored to a[`RemoteChannel`](@ref) / [`Future`](@ref Distributed.Future) on +a different node. As expected, this results in a copy of the serialized objects +on the remote node. However, when the destination node is the local node, i.e. +the calling process id is the same as the remote node id, it is executed +as a local call. It is usually (not always) executed in a different task - but there is no +serialization/deserialization of data. Consequently, the call refers to the same object instances +as passed - no copies are created. This behavior is highlighted below: + +```julia-repl +julia> using Distributed; + +julia> rc = RemoteChannel(()->Channel(3)); # RemoteChannel created on local node + +julia> v = [0]; + +julia> for i in 1:3 + v[1] = i # Reusing `v` + put!(rc, v) + end; + +julia> result = [take!(rc) for _ in 1:3]; + +julia> println(result); +Array{Int64,1}[[3], [3], [3]] + +julia> println("Num Unique objects : ", length(unique(map(objectid, result)))); +Num Unique objects : 1 + +julia> addprocs(1); + +julia> rc = RemoteChannel(()->Channel(3), workers()[1]); # RemoteChannel created on remote node + +julia> v = [0]; + +julia> for i in 1:3 + v[1] = i + put!(rc, v) + end; + +julia> result = [take!(rc) for _ in 1:3]; + +julia> println(result); +Array{Int64,1}[[1], [2], [3]] + +julia> println("Num Unique objects : ", length(unique(map(objectid, result)))); +Num Unique objects : 3 +``` + +As can be seen, [`put!`](@ref) on a locally owned [`RemoteChannel`](@ref) with the same +object `v` modifed between calls results in the same single object instance stored. As +opposed to copies of `v` being created when the node owning `rc` is a different node. + +It is to be noted that this is generally not an issue. It is something to be factored in only +if the object is both being stored locally and modifed post the call. In such cases it may be +appropriate to store a `deepcopy` of the object. + +This is also true for remotecalls on the local node as seen in the following example: + +```julia-repl +julia> using Distributed; addprocs(1); + +julia> v = [0]; + +julia> v2 = remotecall_fetch(x->(x[1] = 1; x), myid(), v); # Executed on local node + +julia> println("v=$v, v2=$v2, ", v === v2); +v=[1], v2=[1], true + +julia> v = [0]; + +julia> v2 = remotecall_fetch(x->(x[1] = 1; x), workers()[1], v); # Executed on remote node + +julia> println("v=$v, v2=$v2, ", v === v2); +v=[0], v2=[1], false +``` + +As can be seen once again, a remote call onto the local node behaves just like a direct invocation. +The call modifies local objects passed as arguments. In the remote invocation, it operates on +a copy of the arguments. + +To repeat, in general this is not an issue. If the local node is also being used as a compute +node, and the arguments used post the call, this behavior needs to be factored in and if required +deep copies of arguments must be passed to the call invoked on the local node. Calls on remote nodes +will always operate on copies of arguments. + + + +## [Shared Arrays](@id man-shared-arrays) + +Shared Arrays use system shared memory to map the same array across many processes. While there +are some similarities to a [`DArray`](https://github.com/JuliaParallel/DistributedArrays.jl), the +behavior of a [`SharedArray`](@ref) is quite different. In a [`DArray`](https://github.com/JuliaParallel/DistributedArrays.jl), +each process has local access to just a chunk of the data, and no two processes share the same +chunk; in contrast, in a [`SharedArray`](@ref) each "participating" process has access to the +entire array. A [`SharedArray`](@ref) is a good choice when you want to have a large amount of +data jointly accessible to two or more processes on the same machine. + +Shared Array support is available via module `SharedArrays` which must be explicitly loaded on +all participating workers. + +[`SharedArray`](@ref) indexing (assignment and accessing values) works just as with regular arrays, +and is efficient because the underlying memory is available to the local process. Therefore, +most algorithms work naturally on [`SharedArray`](@ref)s, albeit in single-process mode. In cases +where an algorithm insists on an [`Array`](@ref) input, the underlying array can be retrieved +from a [`SharedArray`](@ref) by calling [`sdata`](@ref). For other `AbstractArray` types, [`sdata`](@ref) +just returns the object itself, so it's safe to use [`sdata`](@ref) on any `Array`-type object. + +The constructor for a shared array is of the form: + +```julia +SharedArray{T,N}(dims::NTuple; init=false, pids=Int[]) +``` + +which creates an `N`-dimensional shared array of a bits type `T` and size `dims` across the processes specified +by `pids`. Unlike distributed arrays, a shared array is accessible only from those participating +workers specified by the `pids` named argument (and the creating process too, if it is on the +same host). Note that only elements that are [`isbits`](@ref) are supported in a SharedArray. + +If an `init` function, of signature `initfn(S::SharedArray)`, is specified, it is called on all +the participating workers. You can specify that each worker runs the `init` function on a distinct +portion of the array, thereby parallelizing initialization. + +Here's a brief example: + +```julia-repl +julia> using Distributed + +julia> addprocs(3) +3-element Array{Int64,1}: + 2 + 3 + 4 + +julia> @everywhere using SharedArrays + +julia> S = SharedArray{Int,2}((3,4), init = S -> S[localindices(S)] = repeat([myid()], length(localindices(S)))) +3×4 SharedArray{Int64,2}: + 2 2 3 4 + 2 3 3 4 + 2 3 4 4 + +julia> S[3,2] = 7 +7 + +julia> S +3×4 SharedArray{Int64,2}: + 2 2 3 4 + 2 3 3 4 + 2 7 4 4 +``` + +[`SharedArrays.localindices`](@ref) provides disjoint one-dimensional ranges of indices, and is sometimes +convenient for splitting up tasks among processes. You can, of course, divide the work any way +you wish: + +```julia-repl +julia> S = SharedArray{Int,2}((3,4), init = S -> S[indexpids(S):length(procs(S)):length(S)] = repeat([myid()], length( indexpids(S):length(procs(S)):length(S)))) +3×4 SharedArray{Int64,2}: + 2 2 2 2 + 3 3 3 3 + 4 4 4 4 +``` + +Since all processes have access to the underlying data, you do have to be careful not to set up +conflicts. For example: + +```julia +@sync begin + for p in procs(S) + @async begin + remotecall_wait(fill!, p, S, p) + end + end +end +``` + +would result in undefined behavior. Because each process fills the *entire* array with its own +`pid`, whichever process is the last to execute (for any particular element of `S`) will have +its `pid` retained. + +As a more extended and complex example, consider running the following "kernel" in parallel: + +```julia +q[i,j,t+1] = q[i,j,t] + u[i,j,t] +``` + +In this case, if we try to split up the work using a one-dimensional index, we are likely to run +into trouble: if `q[i,j,t]` is near the end of the block assigned to one worker and `q[i,j,t+1]` +is near the beginning of the block assigned to another, it's very likely that `q[i,j,t]` will +not be ready at the time it's needed for computing `q[i,j,t+1]`. In such cases, one is better +off chunking the array manually. Let's split along the second dimension. +Define a function that returns the `(irange, jrange)` indices assigned to this worker: + +```julia-repl +julia> @everywhere function myrange(q::SharedArray) + idx = indexpids(q) + if idx == 0 # This worker is not assigned a piece + return 1:0, 1:0 + end + nchunks = length(procs(q)) + splits = [round(Int, s) for s in range(0, stop=size(q,2), length=nchunks+1)] + 1:size(q,1), splits[idx]+1:splits[idx+1] + end +``` + +Next, define the kernel: + +```julia-repl +julia> @everywhere function advection_chunk!(q, u, irange, jrange, trange) + @show (irange, jrange, trange) # display so we can see what's happening + for t in trange, j in jrange, i in irange + q[i,j,t+1] = q[i,j,t] + u[i,j,t] + end + q + end +``` + +We also define a convenience wrapper for a `SharedArray` implementation + +```julia-repl +julia> @everywhere advection_shared_chunk!(q, u) = + advection_chunk!(q, u, myrange(q)..., 1:size(q,3)-1) +``` + +Now let's compare three different versions, one that runs in a single process: + +```julia-repl +julia> advection_serial!(q, u) = advection_chunk!(q, u, 1:size(q,1), 1:size(q,2), 1:size(q,3)-1); +``` + +one that uses [`@distributed`](@ref): + +```julia-repl +julia> function advection_parallel!(q, u) + for t = 1:size(q,3)-1 + @sync @distributed for j = 1:size(q,2) + for i = 1:size(q,1) + q[i,j,t+1]= q[i,j,t] + u[i,j,t] + end + end + end + q + end; +``` + +and one that delegates in chunks: + +```julia-repl +julia> function advection_shared!(q, u) + @sync begin + for p in procs(q) + @async remotecall_wait(advection_shared_chunk!, p, q, u) + end + end + q + end; +``` + +If we create `SharedArray`s and time these functions, we get the following results (with `julia -p 4`): + +```julia-repl +julia> q = SharedArray{Float64,3}((500,500,500)); + +julia> u = SharedArray{Float64,3}((500,500,500)); +``` + +Run the functions once to JIT-compile and [`@time`](@ref) them on the second run: + +```julia-repl +julia> @time advection_serial!(q, u); +(irange,jrange,trange) = (1:500,1:500,1:499) + 830.220 milliseconds (216 allocations: 13820 bytes) + +julia> @time advection_parallel!(q, u); + 2.495 seconds (3999 k allocations: 289 MB, 2.09% gc time) + +julia> @time advection_shared!(q,u); + From worker 2: (irange,jrange,trange) = (1:500,1:125,1:499) + From worker 4: (irange,jrange,trange) = (1:500,251:375,1:499) + From worker 3: (irange,jrange,trange) = (1:500,126:250,1:499) + From worker 5: (irange,jrange,trange) = (1:500,376:500,1:499) + 238.119 milliseconds (2264 allocations: 169 KB) +``` + +The biggest advantage of `advection_shared!` is that it minimizes traffic among the workers, allowing +each to compute for an extended time on the assigned piece. + +### Shared Arrays and Distributed Garbage Collection + +Like remote references, shared arrays are also dependent on garbage collection on the creating +node to release references from all participating workers. Code which creates many short lived +shared array objects would benefit from explicitly finalizing these objects as soon as possible. +This results in both memory and file handles mapping the shared segment being released sooner. + +## ClusterManagers + +The launching, management and networking of Julia processes into a logical cluster is done via +cluster managers. A `ClusterManager` is responsible for + + * launching worker processes in a cluster environment + * managing events during the lifetime of each worker + * optionally, providing data transport + +A Julia cluster has the following characteristics: + + * The initial Julia process, also called the `master`, is special and has an `id` of 1. + * Only the `master` process can add or remove worker processes. + * All processes can directly communicate with each other. + +Connections between workers (using the in-built TCP/IP transport) is established in the following +manner: + + * [`addprocs`](@ref) is called on the master process with a `ClusterManager` object. + * [`addprocs`](@ref) calls the appropriate [`launch`](@ref) method which spawns required number + of worker processes on appropriate machines. + * Each worker starts listening on a free port and writes out its host and port information to [`stdout`](@ref). + * The cluster manager captures the [`stdout`](@ref) of each worker and makes it available to the + master process. + * The master process parses this information and sets up TCP/IP connections to each worker. + * Every worker is also notified of other workers in the cluster. + * Each worker connects to all workers whose `id` is less than the worker's own `id`. + * In this way a mesh network is established, wherein every worker is directly connected with every + other worker. + +While the default transport layer uses plain [`TCPSocket`](@ref), it is possible for a Julia cluster to +provide its own transport. + +Julia provides two in-built cluster managers: + + * `LocalManager`, used when [`addprocs()`](@ref) or [`addprocs(np::Integer)`](@ref) are called + * `SSHManager`, used when [`addprocs(hostnames::Array)`](@ref) is called with a list of hostnames + +`LocalManager` is used to launch additional workers on the same host, thereby leveraging multi-core +and multi-processor hardware. + +Thus, a minimal cluster manager would need to: + + * be a subtype of the abstract `ClusterManager` + * implement [`launch`](@ref), a method responsible for launching new workers + * implement [`manage`](@ref), which is called at various events during a worker's lifetime (for + example, sending an interrupt signal) + +[`addprocs(manager::FooManager)`](@ref addprocs) requires `FooManager` to implement: + +```julia +function launch(manager::FooManager, params::Dict, launched::Array, c::Condition) + [...] +end + +function manage(manager::FooManager, id::Integer, config::WorkerConfig, op::Symbol) + [...] +end +``` + +As an example let us see how the `LocalManager`, the manager responsible for starting workers +on the same host, is implemented: + +```julia +struct LocalManager <: ClusterManager + np::Integer +end + +function launch(manager::LocalManager, params::Dict, launched::Array, c::Condition) + [...] +end + +function manage(manager::LocalManager, id::Integer, config::WorkerConfig, op::Symbol) + [...] +end +``` + +The [`launch`](@ref) method takes the following arguments: + + * `manager::ClusterManager`: the cluster manager that [`addprocs`](@ref) is called with + * `params::Dict`: all the keyword arguments passed to [`addprocs`](@ref) + * `launched::Array`: the array to append one or more `WorkerConfig` objects to + * `c::Condition`: the condition variable to be notified as and when workers are launched + +The [`launch`](@ref) method is called asynchronously in a separate task. The termination of +this task signals that all requested workers have been launched. Hence the [`launch`](@ref) +function MUST exit as soon as all the requested workers have been launched. + +Newly launched workers are connected to each other and the master process in an all-to-all manner. +Specifying the command line argument `--worker[=]` results in the launched processes +initializing themselves as workers and connections being set up via TCP/IP sockets. + +All workers in a cluster share the same [cookie](@ref man-cluster-cookie) as the master. When the cookie is +unspecified, i.e, with the `--worker` option, the worker tries to read it from its standard input. + `LocalManager` and `SSHManager` both pass the cookie to newly launched workers via their + standard inputs. + +By default a worker will listen on a free port at the address returned by a call to [`getipaddr()`](@ref). +A specific address to listen on may be specified by optional argument `--bind-to bind_addr[:port]`. +This is useful for multi-homed hosts. + +As an example of a non-TCP/IP transport, an implementation may choose to use MPI, in which case +`--worker` must NOT be specified. Instead, newly launched workers should call `init_worker(cookie)` +before using any of the parallel constructs. + +For every worker launched, the [`launch`](@ref) method must add a `WorkerConfig` object (with +appropriate fields initialized) to `launched` + +```julia +mutable struct WorkerConfig + # Common fields relevant to all cluster managers + io::Union{IO, Nothing} + host::Union{AbstractString, Nothing} + port::Union{Integer, Nothing} + + # Used when launching additional workers at a host + count::Union{Int, Symbol, Nothing} + exename::Union{AbstractString, Cmd, Nothing} + exeflags::Union{Cmd, Nothing} + + # External cluster managers can use this to store information at a per-worker level + # Can be a dict if multiple fields need to be stored. + userdata::Any + + # SSHManager / SSH tunnel connections to workers + tunnel::Union{Bool, Nothing} + bind_addr::Union{AbstractString, Nothing} + sshflags::Union{Cmd, Nothing} + max_parallel::Union{Integer, Nothing} + + # Used by Local/SSH managers + connect_at::Any + + [...] +end +``` + +Most of the fields in `WorkerConfig` are used by the inbuilt managers. Custom cluster managers +would typically specify only `io` or `host` / `port`: + + * If `io` is specified, it is used to read host/port information. A Julia worker prints out its + bind address and port at startup. This allows Julia workers to listen on any free port available + instead of requiring worker ports to be configured manually. + * If `io` is not specified, `host` and `port` are used to connect. + * `count`, `exename` and `exeflags` are relevant for launching additional workers from a worker. + For example, a cluster manager may launch a single worker per node, and use that to launch additional + workers. + + * `count` with an integer value `n` will launch a total of `n` workers. + * `count` with a value of `:auto` will launch as many workers as the number of CPU threads (logical cores) on that machine. + * `exename` is the name of the `julia` executable including the full path. + * `exeflags` should be set to the required command line arguments for new workers. + * `tunnel`, `bind_addr`, `sshflags` and `max_parallel` are used when a ssh tunnel is required to + connect to the workers from the master process. + * `userdata` is provided for custom cluster managers to store their own worker-specific information. + +`manage(manager::FooManager, id::Integer, config::WorkerConfig, op::Symbol)` is called at different +times during the worker's lifetime with appropriate `op` values: + + * with `:register`/`:deregister` when a worker is added / removed from the Julia worker pool. + * with `:interrupt` when `interrupt(workers)` is called. The `ClusterManager` should signal the + appropriate worker with an interrupt signal. + * with `:finalize` for cleanup purposes. + +### Cluster Managers with Custom Transports + +Replacing the default TCP/IP all-to-all socket connections with a custom transport layer is a +little more involved. Each Julia process has as many communication tasks as the workers it is +connected to. For example, consider a Julia cluster of 32 processes in an all-to-all mesh network: + + * Each Julia process thus has 31 communication tasks. + * Each task handles all incoming messages from a single remote worker in a message-processing loop. + * The message-processing loop waits on an `IO` object (for example, a [`TCPSocket`](@ref) in the default + implementation), reads an entire message, processes it and waits for the next one. + * Sending messages to a process is done directly from any Julia task--not just communication tasks--again, + via the appropriate `IO` object. + +Replacing the default transport requires the new implementation to set up connections to remote +workers and to provide appropriate `IO` objects that the message-processing loops can wait on. +The manager-specific callbacks to be implemented are: + +```julia +connect(manager::FooManager, pid::Integer, config::WorkerConfig) +kill(manager::FooManager, pid::Int, config::WorkerConfig) +``` + +The default implementation (which uses TCP/IP sockets) is implemented as `connect(manager::ClusterManager, pid::Integer, config::WorkerConfig)`. + +`connect` should return a pair of `IO` objects, one for reading data sent from worker `pid`, and +the other to write data that needs to be sent to worker `pid`. Custom cluster managers can use +an in-memory `BufferStream` as the plumbing to proxy data between the custom, possibly non-`IO` +transport and Julia's in-built parallel infrastructure. + +A `BufferStream` is an in-memory [`IOBuffer`](@ref) which behaves like an `IO`--it is a stream which can +be handled asynchronously. + +The folder `clustermanager/0mq` in the [Examples repository](https://github.com/JuliaAttic/Examples) +contains an example of using ZeroMQ to connect Julia workers +in a star topology with a 0MQ broker in the middle. Note: The Julia processes are still all *logically* +connected to each other--any worker can message any other worker directly without any awareness +of 0MQ being used as the transport layer. + +When using custom transports: + + * Julia workers must NOT be started with `--worker`. Starting with `--worker` will result in the + newly launched workers defaulting to the TCP/IP socket transport implementation. + * For every incoming logical connection with a worker, `Base.process_messages(rd::IO, wr::IO)()` + must be called. This launches a new task that handles reading and writing of messages from/to + the worker represented by the `IO` objects. + * `init_worker(cookie, manager::FooManager)` *must* be called as part of worker process initialization. + * Field `connect_at::Any` in `WorkerConfig` can be set by the cluster manager when [`launch`](@ref) + is called. The value of this field is passed in all [`connect`](@ref) callbacks. Typically, + it carries information on *how to connect* to a worker. For example, the TCP/IP socket transport + uses this field to specify the `(host, port)` tuple at which to connect to a worker. + +`kill(manager, pid, config)` is called to remove a worker from the cluster. On the master process, +the corresponding `IO` objects must be closed by the implementation to ensure proper cleanup. +The default implementation simply executes an `exit()` call on the specified remote worker. + +The Examples folder `clustermanager/simple` is an example that shows a simple implementation using UNIX domain +sockets for cluster setup. + +### Network Requirements for LocalManager and SSHManager + +Julia clusters are designed to be executed on already secured environments on infrastructure such +as local laptops, departmental clusters, or even the cloud. This section covers network security +requirements for the inbuilt `LocalManager` and `SSHManager`: + + * The master process does not listen on any port. It only connects out to the workers. + * Each worker binds to only one of the local interfaces and listens on an ephemeral port number + assigned by the OS. + * `LocalManager`, used by `addprocs(N)`, by default binds only to the loopback interface. This means + that workers started later on remote hosts (or by anyone with malicious intentions) are unable + to connect to the cluster. An `addprocs(4)` followed by an `addprocs(["remote_host"])` will fail. + Some users may need to create a cluster comprising their local system and a few remote systems. + This can be done by explicitly requesting `LocalManager` to bind to an external network interface + via the `restrict` keyword argument: `addprocs(4; restrict=false)`. + * `SSHManager`, used by `addprocs(list_of_remote_hosts)`, launches workers on remote hosts via SSH. + By default SSH is only used to launch Julia workers. Subsequent master-worker and worker-worker + connections use plain, unencrypted TCP/IP sockets. The remote hosts must have passwordless login + enabled. Additional SSH flags or credentials may be specified via keyword argument `sshflags`. + * `addprocs(list_of_remote_hosts; tunnel=true, sshflags=)` is useful when + we wish to use SSH connections for master-worker too. A typical scenario for this is a local laptop + running the Julia REPL (i.e., the master) with the rest of the cluster on the cloud, say on Amazon + EC2. In this case only port 22 needs to be opened at the remote cluster coupled with SSH client + authenticated via public key infrastructure (PKI). Authentication credentials can be supplied + via `sshflags`, for example ```sshflags=`-i ` ```. + + In an all-to-all topology (the default), all workers connect to each other via plain TCP sockets. + The security policy on the cluster nodes must thus ensure free connectivity between workers for + the ephemeral port range (varies by OS). + + Securing and encrypting all worker-worker traffic (via SSH) or encrypting individual messages + can be done via a custom `ClusterManager`. + + * If you specify `multiplex=true` as an option to `addprocs`, SSH multiplexing is used to create + a tunnel between the master and workers. If you have configured SSH multiplexing on your own and + the connection has already been established, SSH multiplexing is used regardless of `multiplex` + option. If multiplexing is enabled, forwarding is set by using the existing connection + (`-O forward` option in ssh). This is beneficial if your servers require password authentication; + you can avoid authentication in Julia by logging in to the server ahead of `addprocs`. The control + socket will be located at `~/.ssh/julia-%r@%h:%p` during the session unless the existing multiplexing + connection is used. Note that bandwidth may be limited if you create multiple processes on a node + and enable multiplexing, because in that case processes share a single multiplexing TCP connection. + +### [Cluster Cookie](@id man-cluster-cookie) + +All processes in a cluster share the same cookie which, by default, is a randomly generated string +on the master process: + + * [`cluster_cookie()`](@ref) returns the cookie, while `cluster_cookie(cookie)()` sets + it and returns the new cookie. + * All connections are authenticated on both sides to ensure that only workers started by the master + are allowed to connect to each other. + * The cookie may be passed to the workers at startup via argument `--worker=`. If argument + `--worker` is specified without the cookie, the worker tries to read the cookie from its + standard input ([`stdin`](@ref)). The `stdin` is closed immediately after the cookie is retrieved. + * `ClusterManager`s can retrieve the cookie on the master by calling [`cluster_cookie()`](@ref). + Cluster managers not using the default TCP/IP transport (and hence not specifying `--worker`) + must call `init_worker(cookie, manager)` with the same cookie as on the master. + +Note that environments requiring higher levels of security can implement this via a custom `ClusterManager`. +For example, cookies can be pre-shared and hence not specified as a startup argument. + +## Specifying Network Topology (Experimental) + +The keyword argument `topology` passed to `addprocs` is used to specify how the workers must be +connected to each other: + + * `:all_to_all`, the default: all workers are connected to each other. + * `:master_worker`: only the driver process, i.e. `pid` 1, has connections to the workers. + * `:custom`: the `launch` method of the cluster manager specifies the connection topology via the + fields `ident` and `connect_idents` in `WorkerConfig`. A worker with a cluster-manager-provided + identity `ident` will connect to all workers specified in `connect_idents`. + +Keyword argument `lazy=true|false` only affects `topology` option `:all_to_all`. If `true`, the cluster +starts off with the master connected to all workers. Specific worker-worker connections are established +at the first remote invocation between two workers. This helps in reducing initial resources allocated for +intra-cluster communication. Connections are setup depending on the runtime requirements of a parallel +program. Default value for `lazy` is `true`. + +Currently, sending a message between unconnected workers results in an error. This behaviour, +as with the functionality and interface, should be considered experimental in nature and may change +in future releases. + +## Noteworthy external packages + +Outside of Julia parallelism there are plenty of external packages that should be mentioned. +For example [MPI.jl](https://github.com/JuliaParallel/MPI.jl) is a Julia wrapper for the `MPI` protocol, or +[DistributedArrays.jl](https://github.com/JuliaParallel/Distributedarrays.jl), as presented in [Shared Arrays](@ref). +A mention must be made of Julia's GPU programming ecosystem, which includes: + +1. Low-level (C kernel) based operations [OpenCL.jl](https://github.com/JuliaGPU/OpenCL.jl) and [CUDAdrv.jl](https://github.com/JuliaGPU/CUDAdrv.jl) which are respectively an OpenCL interface and a CUDA wrapper. + +2. Low-level (Julia Kernel) interfaces like [CUDAnative.jl](https://github.com/JuliaGPU/CUDAnative.jl) which is a Julia native CUDA implementation. + +3. High-level vendor-specific abstractions like [CuArrays.jl](https://github.com/JuliaGPU/CuArrays.jl) and [CLArrays.jl](https://github.com/JuliaGPU/CLArrays.jl) + +4. High-level libraries like [ArrayFire.jl](https://github.com/JuliaComputing/ArrayFire.jl) and [GPUArrays.jl](https://github.com/JuliaGPU/GPUArrays.jl) + + +In the following example we will use both `DistributedArrays.jl` and `CuArrays.jl` to distribute an array across multiple +processes by first casting it through `distribute()` and `CuArray()`. + +Remember when importing `DistributedArrays.jl` to import it across all processes using [`@everywhere`](@ref) + + +```julia-repl +$ ./julia -p 4 + +julia> addprocs() + +julia> @everywhere using DistributedArrays + +julia> using CuArrays + +julia> B = ones(10_000) ./ 2; + +julia> A = ones(10_000) .* π; + +julia> C = 2 .* A ./ B; + +julia> all(C .≈ 4*π) +true + +julia> typeof(C) +Array{Float64,1} + +julia> dB = distribute(B); + +julia> dA = distribute(A); + +julia> dC = 2 .* dA ./ dB; + +julia> all(dC .≈ 4*π) +true + +julia> typeof(dC) +DistributedArrays.DArray{Float64,1,Array{Float64,1}} + +julia> cuB = CuArray(B); + +julia> cuA = CuArray(A); + +julia> cuC = 2 .* cuA ./ cuB; + +julia> all(cuC .≈ 4*π); +true + +julia> typeof(cuC) +CuArray{Float64,1} +``` +Keep in mind that some Julia features are not currently supported by CUDAnative.jl[^2] , especially some functions like `sin` will need to be replaced with `CUDAnative.sin`(cc: @maleadt). + +In the following example we will use both `DistributedArrays.jl` and `CuArrays.jl` to distribute an array across multiple +processes and call a generic function on it. + +```julia +function power_method(M, v) + for i in 1:100 + v = M*v + v /= norm(v) + end + + return v, norm(M*v) / norm(v) # or (M*v) ./ v +end +``` + +`power_method` repeatedly creates a new vector and normalizes it. We have not specified any type signature in +function declaration, let's see if it works with the aforementioned datatypes: + +```julia-repl +julia> M = [2. 1; 1 1]; + +julia> v = rand(2) +2-element Array{Float64,1}: +0.40395 +0.445877 + +julia> power_method(M,v) +([0.850651, 0.525731], 2.618033988749895) + +julia> cuM = CuArray(M); + +julia> cuv = CuArray(v); + +julia> curesult = power_method(cuM, cuv); + +julia> typeof(curesult) +CuArray{Float64,1} + +julia> dM = distribute(M); + +julia> dv = distribute(v); + +julia> dC = power_method(dM, dv); + +julia> typeof(dC) +Tuple{DistributedArrays.DArray{Float64,1,Array{Float64,1}},Float64} +``` + +To end this short exposure to external packages, we can consider `MPI.jl`, a Julia wrapper +of the MPI protocol. As it would take too long to consider every inner function, it would be better +to simply appreciate the approach used to implement the protocol. + +Consider this toy script which simply calls each subprocess, instantiate its rank and when the master +process is reached, performs the ranks' sum + +```julia +import MPI + +MPI.Init() + +comm = MPI.COMM_WORLD +MPI.Barrier(comm) + +root = 0 +r = MPI.Comm_rank(comm) + +sr = MPI.Reduce(r, MPI.SUM, root, comm) + +if(MPI.Comm_rank(comm) == root) + @printf("sum of ranks: %s\n", sr) +end + +MPI.Finalize() +``` + +``` +mpirun -np 4 ./julia example.jl +``` + +[^1]: + In this context, MPI refers to the MPI-1 standard. Beginning with MPI-2, the MPI standards committee + introduced a new set of communication mechanisms, collectively referred to as Remote Memory Access + (RMA). The motivation for adding rma to the MPI standard was to facilitate one-sided communication + patterns. For additional information on the latest MPI standard, see . + +[^2]: + [Julia GPU man pages](http://juliagpu.github.io/CUDAnative.jl/stable/man/usage.html#Julia-support-1) diff --git a/src/manual/multi-threading.md b/src/manual/multi-threading.md new file mode 100644 index 0000000..952e7ac --- /dev/null +++ b/src/manual/multi-threading.md @@ -0,0 +1,351 @@ +# [Multi-Threading](@id man-multithreading) + +Visit this [blog post](https://julialang.org/blog/2019/07/multithreading/) for a presentation +of Julia multi-threading features. + +## Starting Julia with multiple threads + +By default, Julia starts up with a single thread of execution. This can be verified by using the +command [`Threads.nthreads()`](@ref): + +```julia-repl +julia> Threads.nthreads() +1 +``` + +The number of execution threads is controlled either by using the +`-t`/`--threads` command line argument or by using the +[`JULIA_NUM_THREADS`](@ref JULIA_NUM_THREADS) environment variable. When both are +specified, then `-t`/`--threads` takes precedence. + +!!! compat "Julia 1.5" + The `-t`/`--threads` command line argument requires at least Julia 1.5. + In older versions you must use the environment variable instead. + +Lets start Julia with 4 threads: + +```bash +$ julia --threads 4 +``` + +Let's verify there are 4 threads at our disposal. + +```julia-repl +julia> Threads.nthreads() +4 +``` + +But we are currently on the master thread. To check, we use the function [`Threads.threadid`](@ref) + +```julia-repl +julia> Threads.threadid() +1 +``` + +!!! note + If you prefer to use the environment variable you can set it as follows in + Bash (Linux/macOS): + ```bash + export JULIA_NUM_THREADS=4 + ``` + C shell on Linux/macOS, CMD on Windows: + ```bash + set JULIA_NUM_THREADS=4 + ``` + Powershell on Windows: + ```powershell + $env:JULIA_NUM_THREADS=4 + ``` + Note that this must be done *before* starting Julia. + +!!! note + The number of threads specified with `-t`/`--threads` is propagated to worker processes + that are spawned using the `-p`/`--procs` or `--machine-file` command line options. + For example, `julia -p2 -t2` spawns 1 main process with 2 worker processes, and all + three processes have 2 threads enabled. For more fine grained control over worker + threads use [`addprocs`](@ref) and pass `-t`/`--threads` as `exeflags`. + +## Data-race freedom + +You are entirely responsible for ensuring that your program is data-race free, +and nothing promised here can be assumed if you do not observe that +requirement. The observed results may be highly unintuitive. + +The best way to ensure this is to acquire a lock around any access to data that +can be observed from multiple threads. For example, in most cases you should +use the following code pattern: + +```julia-repl +julia> lock(lk) do + use(a) + end + +julia> begin + lock(lk) + try + use(a) + finally + unlock(lk) + end + end +``` +where `lk` is a lock (e.g. `ReentrantLock()`) and `a` data. + +Additionally, Julia is not memory safe in the presence of a data race. Be very +careful about reading _any_ data if another thread might write to it! +Instead, always use the lock pattern above when changing data (such as assigning +to a global or closure variable) accessed by other threads. + +```julia +Thread 1: +global b = false +global a = rand() +global b = true + +Thread 2: +while !b; end +bad_read1(a) # it is NOT safe to access `a` here! + +Thread 3: +while !@isdefined(a); end +bad_read2(a) # it is NOT safe to access `a` here +``` + +## The `@threads` Macro + +Let's work a simple example using our native threads. Let us create an array of zeros: + +```jldoctest +julia> a = zeros(10) +10-element Vector{Float64}: + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 + 0.0 +``` + +Let us operate on this array simultaneously using 4 threads. We'll have each thread write its +thread ID into each location. + +Julia supports parallel loops using the [`Threads.@threads`](@ref) macro. This macro is affixed +in front of a `for` loop to indicate to Julia that the loop is a multi-threaded region: + +```julia-repl +julia> Threads.@threads for i = 1:10 + a[i] = Threads.threadid() + end +``` + +The iteration space is split among the threads, after which each thread writes its thread ID +to its assigned locations: + +```julia-repl +julia> a +10-element Array{Float64,1}: + 1.0 + 1.0 + 1.0 + 2.0 + 2.0 + 2.0 + 3.0 + 3.0 + 4.0 + 4.0 +``` + +Note that [`Threads.@threads`](@ref) does not have an optional reduction parameter like [`@distributed`](@ref). + +## Atomic Operations + +Julia supports accessing and modifying values *atomically*, that is, in a thread-safe way to avoid +[race conditions](https://en.wikipedia.org/wiki/Race_condition). A value (which must be of a primitive +type) can be wrapped as [`Threads.Atomic`](@ref) to indicate it must be accessed in this way. +Here we can see an example: + +```julia-repl +julia> i = Threads.Atomic{Int}(0); + +julia> ids = zeros(4); + +julia> old_is = zeros(4); + +julia> Threads.@threads for id in 1:4 + old_is[id] = Threads.atomic_add!(i, id) + ids[id] = id + end + +julia> old_is +4-element Array{Float64,1}: + 0.0 + 1.0 + 7.0 + 3.0 + +julia> ids +4-element Array{Float64,1}: + 1.0 + 2.0 + 3.0 + 4.0 +``` + +Had we tried to do the addition without the atomic tag, we might have gotten the +wrong answer due to a race condition. An example of what would happen if we didn't +avoid the race: + +```julia-repl +julia> using Base.Threads + +julia> nthreads() +4 + +julia> acc = Ref(0) +Base.RefValue{Int64}(0) + +julia> @threads for i in 1:1000 + acc[] += 1 + end + +julia> acc[] +926 + +julia> acc = Atomic{Int64}(0) +Atomic{Int64}(0) + +julia> @threads for i in 1:1000 + atomic_add!(acc, 1) + end + +julia> acc[] +1000 +``` + +!!! note + Not *all* primitive types can be wrapped in an `Atomic` tag. Supported types + are `Int8`, `Int16`, `Int32`, `Int64`, `Int128`, `UInt8`, `UInt16`, `UInt32`, + `UInt64`, `UInt128`, `Float16`, `Float32`, and `Float64`. Additionally, + `Int128` and `UInt128` are not supported on AAarch32 and ppc64le. + +## Side effects and mutable function arguments + +When using multi-threading we have to be careful when using functions that are not +[pure](https://en.wikipedia.org/wiki/Pure_function) as we might get a wrong answer. +For instance functions that have a +[name ending with `!`](@ref bang-convention) +by convention modify their arguments and thus are not pure. + +## @threadcall + +External libraries, such as those called via [`ccall`](@ref), pose a problem for +Julia's task-based I/O mechanism. +If a C library performs a blocking operation, that prevents the Julia scheduler +from executing any other tasks until the call returns. +(Exceptions are calls into custom C code that call back into Julia, which may then +yield, or C code that calls `jl_yield()`, the C equivalent of [`yield`](@ref).) + +The [`@threadcall`](@ref) macro provides a way to avoid stalling execution in such +a scenario. +It schedules a C function for execution in a separate thread. A threadpool with a +default size of 4 is used for this. The size of the threadpool is controlled via environment variable +`UV_THREADPOOL_SIZE`. While waiting for a free thread, and during function execution once a thread +is available, the requesting task (on the main Julia event loop) yields to other tasks. Note that +`@threadcall` does not return until the execution is complete. From a user point of view, it is +therefore a blocking call like other Julia APIs. + +It is very important that the called function does not call back into Julia, as it will segfault. + +`@threadcall` may be removed/changed in future versions of Julia. + +## Caveats + +At this time, most operations in the Julia runtime and standard libraries +can be used in a thread-safe manner, if the user code is data-race free. +However, in some areas work on stabilizing thread support is ongoing. +Multi-threaded programming has many inherent difficulties, and if a program +using threads exhibits unusual or undesirable behavior (e.g. crashes or +mysterious results), thread interactions should typically be suspected first. + +There are a few specific limitations and warnings to be aware of when using +threads in Julia: + + * Base collection types require manual locking if used simultaneously by + multiple threads where at least one thread modifies the collection + (common examples include `push!` on arrays, or inserting + items into a `Dict`). + * After a task starts running on a certain thread (e.g. via `@spawn`), it + will always be restarted on the same thread after blocking. In the future + this limitation will be removed, and tasks will migrate between threads. + * `@threads` currently uses a static schedule, using all threads and assigning + equal iteration counts to each. In the future the default schedule is likely + to change to be dynamic. + * The schedule used by `@spawn` is nondeterministic and should not be relied on. + * Compute-bound, non-memory-allocating tasks can prevent garbage collection from + running in other threads that are allocating memory. In these cases it may + be necessary to insert a manual call to `GC.safepoint()` to allow GC to run. + This limitation will be removed in the future. + * Avoid running top-level operations, e.g. `include`, or `eval` of type, + method, and module definitions in parallel. + * Be aware that finalizers registered by a library may break if threads are enabled. + This may require some transitional work across the ecosystem before threading + can be widely adopted with confidence. See the next section for further details. + +## Safe use of Finalizers + +Because finalizers can interrupt any code, they must be very careful in how +they interact with any global state. Unfortunately, the main reason that +finalizers are used is to update global state (a pure function is generally +rather pointless as a finalizer). This leads us to a bit of a conundrum. +There are a few approaches to dealing with this problem: + +1. When single-threaded, code could call the internal `jl_gc_enable_finalizers` + C function to prevent finalizers from being scheduled + inside a critical region. Internally, this is used inside some functions (such + as our C locks) to prevent recursion when doing certain operations (incremental + package loading, codegen, etc.). The combination of a lock and this flag + can be used to make finalizers safe. + +2. A second strategy, employed by Base in a couple places, is to explicitly + delay a finalizer until it may be able to acquire its lock non-recursively. + The following example demonstrates how this strategy could be applied to + `Distributed.finalize_ref`: + + ```julia + function finalize_ref(r::AbstractRemoteRef) + if r.where > 0 # Check if the finalizer is already run + if islocked(client_refs) || !trylock(client_refs) + # delay finalizer for later if we aren't free to acquire the lock + finalizer(finalize_ref, r) + return nothing + end + try # `lock` should always be followed by `try` + if r.where > 0 # Must check again here + # Do actual cleanup here + r.where = 0 + end + finally + unlock(client_refs) + end + end + nothing + end + ``` + +3. A related third strategy is to use a yield-free queue. We don't currently + have a lock-free queue implemented in Base, but + `Base.InvasiveLinkedListSynchronized{T}` is suitable. This can frequently be a + good strategy to use for code with event loops. For example, this strategy is + employed by `Gtk.jl` to manage lifetime ref-counting. In this approach, we + don't do any explicit work inside the `finalizer`, and instead add it to a queue + to run at a safer time. In fact, Julia's task scheduler already uses this, so + defining the finalizer as `x -> @spawn do_cleanup(x)` is one example of this + approach. Note however that this doesn't control which thread `do_cleanup` + runs on, so `do_cleanup` would still need to acquire a lock. That + doesn't need to be true if you implement your own queue, as you can explicitly + only drain that queue from your thread. diff --git a/tools/documenter.sty b/tools/documenter.sty new file mode 100644 index 0000000..352d87f --- /dev/null +++ b/tools/documenter.sty @@ -0,0 +1,98 @@ +% font settings +\usepackage{fontspec, newunicodechar, polyglossia} + +% \setsansfont{DejaVu Sans}[Scale=MatchLowercase, Ligatures=TeX] +\setmainfont{DejaVu Sans}[Scale=MatchLowercase, Ligatures=TeX] + +% download IropkeBatangM.ttf from http://font.iropke.com/batang/ +\setsansfont{IropkeBatangM}[Scale=MatchLowercase, Ligatures=TeX] +\linespread{1.4} + +% \setmonofont{DejaVu Sans Mono}[Scale=MatchLowercase] +% download D2Coding Ver 1.3.2 from https://github.com/naver/d2codingfont +\setmonofont{D2Coding}[Scale=MatchLowercase] + +\renewcommand{\familydefault}{\sfdefault} +% DejaVu Sans Mono does not have the xor symbol. So we hack around that by replacing all +% instances of it with calls to \unicodeveebar, which prints this single character as with +% DejaVu Sans instead. +\newfontfamily\unicodeveebarfont{DejaVu Sans}[Scale=MatchLowercase] +\newcommand\unicodeveebar{{\unicodeveebarfont ⊻}} +% + +% colours +\usepackage{xcolor} + +\definecolor{light-blue}{HTML}{6b85dd} +\definecolor{dark-blue}{HTML}{4266d5} +\definecolor{light-red}{HTML}{d66661} +\definecolor{dark-red}{HTML}{c93d39} +\definecolor{light-green}{HTML}{6bab5b} +\definecolor{dark-green}{HTML}{3b972e} +\definecolor{light-purple}{HTML}{aa7dc0} +\definecolor{dark-purple}{HTML}{945bb0} +% + +% maths +\usepackage{amsmath, amssymb} +% + +% listings +\usepackage{listings, minted} + +\lstset{ + basicstyle = \small\ttfamily, + breaklines = true, + columns = fullflexible, + frame = leftline, + keepspaces = true, + showstringspaces = false, + xleftmargin = 3pt, +} + +\setminted{ + breaklines = true, + fontsize = \small, + frame = leftline, +} +% + +% tables +\usepackage{tabulary} +% + +% hyperref +\usepackage{hyperref} +\hypersetup{ + pdfpagelabels, + bookmarks, + hyperindex, + unicode = true, + linkcolor = dark-blue, + urlcolor = dark-purple, + colorlinks = true, +} +% + +% table of contents +\maxtocdepth{subsection} +\renewcommand\arraystretch{1.6} +% + +% paragraphs +\setlength{\parindent}{0pt} +\nonzeroparskip +% + +% adjust margins +\setulmarginsandblock{1.5in}{1in}{*} +\setlrmarginsandblock{1.5in}{1in}{*} +% \setheaderspaces{1in}{*}{*} +\setheaderspaces{0.7in}{*}{*} +\checkandfixthelayout +% + +% images etc. +\usepackage{graphicx} +\usepackage[export]{adjustbox} +% diff --git a/tools/latex.jl b/tools/latex.jl new file mode 100644 index 0000000..3ac6b6b --- /dev/null +++ b/tools/latex.jl @@ -0,0 +1,70 @@ +# to change the STYLE file from Documenter.jl/src/Writers/LaTeXWriter.jl +const KR_STYLE = normpath(@__DIR__, "documenter.sty") + +using Documenter.Writers.LaTeXWriter +using .LaTeXWriter: DOCUMENT_STRUCTURE, Documents, LaTeX, Context, writeheader, writefooter, files, latex, compile_tex, _println + +function LaTeXWriter.render(doc::Documents.Document, settings::LaTeX=LaTeX()) + @info "LaTeXWriter: creating the LaTeX file." + Base.mktempdir() do path + cp(joinpath(doc.user.root, doc.user.build), joinpath(path, "build")) + cd(joinpath(path, "build")) do + name = "julia" # doc.user.sitename + let tag = get(ENV, "TRAVIS_TAG", "") + if occursin(Base.VERSION_REGEX, tag) + v = VersionNumber(tag) + name *= "-$(v.major).$(v.minor).$(v.patch)" + end + end + name = replace(name, " " => "") + texfile = name * ".tex" + pdffile = name * ".pdf" + open(texfile, "w") do io + context = Context(io) + writeheader(context, doc) + for (title, filename, depth) in files(doc.user.pages) + context.filename = filename + empty!(context.footnotes) + if 1 <= depth <= length(DOCUMENT_STRUCTURE) + header_type = DOCUMENT_STRUCTURE[depth] + header_text = "\n\\$(header_type){$(title)}\n" + if isempty(filename) + _println(context, header_text) + else + path = normpath(filename) + page = doc.blueprint.pages[path] + if get(page.globals.meta, :IgnorePage, :none) !== :latex + context.depth = depth + (isempty(title) ? 0 : 1) + context.depth > depth && _println(context, header_text) + latex(context, page, doc) + end + end + end + end + writefooter(context, doc) + end + cp(KR_STYLE, "documenter.sty") + + # compile .tex + status = compile_tex(doc, settings, texfile) + + # Debug: if DOCUMENTER_LATEX_DEBUG environment variable is set, copy the LaTeX + # source files over to a directory under doc.user.root. + if haskey(ENV, "DOCUMENTER_LATEX_DEBUG") + dst = isempty(ENV["DOCUMENTER_LATEX_DEBUG"]) ? mktempdir(doc.user.root) : + joinpath(doc.user.root, ENV["DOCUMENTER_LATEX_DEBUG"]) + sources = cp(pwd(), dst, force=true) + @info "LaTeX sources copied for debugging to $(sources)" + end + + # If the build was successful, copy the PDF or the LaTeX source to the .build directory + if status && (settings.platform != "none") + cp(pdffile, joinpath(doc.user.root, doc.user.build, pdffile); force = true) + elseif status && (settings.platform == "none") + cp(pwd(), joinpath(doc.user.root, doc.user.build); force = true) + else + error("Compiling the .tex file failed. See logs for more information.") + end + end + end +end From 9fafc077c010edffa0e400153b889f0bbe5cb63b Mon Sep 17 00:00:00 2001 From: Dohyeon Lee Date: Thu, 3 Sep 2020 00:01:56 +0900 Subject: [PATCH 132/153] =?UTF-8?q?=EB=B3=80=EC=88=98=20=EC=B1=95=ED=84=B0?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/index.md | 11 +++--- src/manual/variables.md | 77 +++++++++++++++++++---------------------- 2 files changed, 41 insertions(+), 47 deletions(-) diff --git a/src/index.md b/src/index.md index 4c3214a..30516f3 100644 --- a/src/index.md +++ b/src/index.md @@ -43,11 +43,10 @@ Markdown.parse(""" ### [소개글](@id man-introduction) -과학 분야 컴퓨팅은 전통적으로 최고의 성능을 요구하지만, 당사자인 전문 연구자들은 속도가 느리더라도 동적인 언어로서 그들의 업무를 처리한다. -동적 언어를 즐겨쓰는 여러가지 이유로 보건데, 이러한 추세가 쉽게 사그러들지는 않아 보인다. -다행히 근래의 언어 디자인과 컴파일러 기법의 발달은, 미뤄두었던 성능 문제를 해결함으로서 -프로토타이핑 작업에 요구되는 개별 환경의 생산성과, 성능이 중요한 애플리케이션의 구축에서 그 효용을 충분히 발휘한다. -줄리아 프로그래밍 언어는 다음과 같은 역할을 수행한다: 과학과 수학 분야 컴퓨팅에 적합한, 기존의 정적 타입 언어에 견줄만한 성능을 갖춘 유연한 동적 언어. +과학 분야 컴퓨팅은 빠른 성능을 요구함에도, 정작 대부분의 연구자들은 속도가 느린 동적인 언어로 일을 처리한다. +동적 언어를 즐겨쓰는 여러 이유로 보아 이러한 추세는 쉽게 사그러들지는 않아 보인다. +다행히 언어 디자인과 컴파일러 기법의 발달로 성능 문제가 해결되면서 동적 언어의 성능 하락 문제를 극복하고 프로토타이핑과 계산 집중형 애플리케이션의 구축을 하나의 환경에서 발휘할 수 있게 되었다. +Julia는 이런 장점을 최대화한 언어이다. Julia는 (1) 과학과 수학 분야의 컴퓨팅에 적합한 동적 언어이면서 (2) 정적 타입 언어에 겨줄만한 성능을 지닌다. 줄리아 컴파일러는 파이썬, R과 같은 언어의 해석 방식과 다르다. 줄리아가 뽑아내는 성능이 아마도 처음에는 의아할 것이다. 그럼에도 작성한 코드가 느리다면 [성능 팁](@ref man-performance-tips)을 읽어보길 권한다. @@ -69,7 +68,7 @@ Markdown.parse(""" * 인자 타입에 따라 효율적이고 특화된 코드를 자동으로 생성 * C와 같은 정적으로 컴파일되는 언어에 근접하는 훌륭한 성능 -동적 언어에 대해 "타입이 없다"는 식으로 말하곤 하는데 사실은 그렇지 않다: 프리미티브(숫자와 같은 기본 타입의)이거나 별도 정의를 통틀어 모든 객체는 타입을 가진다. +동적 언어에 대해 "타입이 없다"는 식으로 말하곤 하는데 사실은 그렇지 않다: 기본 타입이거나 별도 정의를 통해 모든 객체는 타입을 가진다. 그러나 대부분의 동적 언어는 타입 선언의 부족으로 컴파일러가 해당 값의 타입을 인지하지 못한다거나 타입에 대해 무엇인지 명시적으로 밝힐 수 없는 상태가 되곤 한다. 한편 정적 언어는 타입 정보를 -- 대개 -- 컴파일러용으로서 달기에, 타입은 오직 컴파일 시점에만 존재하여 실행시에는 이를 다루거나 표현할 수 없다. 줄리아에서 타입은 그 자체로 런타임 객체이며 컴파일러가 요하는 정보를 알려주는 데에도 쓰인다. diff --git a/src/manual/variables.md b/src/manual/variables.md index 1864268..a7f576e 100644 --- a/src/manual/variables.md +++ b/src/manual/variables.md @@ -1,32 +1,29 @@ # [변수](@id Variables) -변수는 값에 연결된 (또는 바인딩 된) 이름입니다. 나중에 사용할 수 있도록 값 (예 : 일부 계산 후에 얻은 값)을 저장하려는 경우 유용합니다. - -예 : +변수는 값의 이름이다. +나중에 값을 재사용하려고 한다면 변수에 저장하여 활용할 수 있다: ```julia-repl -# 변수 x에 10을 할당할때 -# Assign the value 10 to the variable x +# 변수 x에 10을 할당한다. julia> x = 10 10 -# x의 값으로 계산할떄 +# x의 값으로 계산할 수 있다. julia> x + 1 11 -# x의값을 재설계할때 +# x의 값을 재할당할 수 있다. julia> x = 1 + 1 2 -# 텍스트 문자열과 같은 다른 유형의 값을 지정할 수 있습니다. +# 기존에 저장된 값과 다른 타입을 저장할 수 있다(예시: 문자열). julia> x = "Hello World!" "Hello World!" ``` - Julia는 변수 명명에 매우 유연한 시스템을 제공합니다. 변수 이름은 대소 문자를 구 -분합니다. 그리고 의미 론적 의미가 없습니다 (즉, 언어는 변수를 다르게 취급하지 않 -습니다. +Julia는 유연한 변수 명명법을 가진다. +일단 변수 이름은 대소문자를 구분한다: ```jldoctest julia> x = 1.0 @@ -45,7 +42,7 @@ julia> UniversalDeclarationOfHumanRightsStart = "人人生而自由,在尊严 "人人生而自由,在尊严和权利上一律平等。" ``` -Unicode names (in UTF-8 encoding) are allowed: +Julia는 유니코드 기반의 변수를 허용한다: ```jldoctest julia> δ = 0.00001 @@ -55,10 +52,13 @@ julia> 안녕하세요 = "Hello" "Hello" ``` -REPL 및 다른 여러 줄리아 편집 환경에서 많은 유니코드 수학 기호를 입력 할 수 있습니다. 백 슬래쉬 - LaTeX 기호명 - 탭을 입력하면 기호로 변환됩니다. 예를 들어 변수명 δ는 `\delta`-tab, `α^²`는 `\alpha`-tab-`\hat`-tab-`\_2`-tab 으로 입력할 수 있습니다. 어떤 기호를 입력하는 방법은 REPL에서 ?(help 호출)를 입력 후 원하는 유니코드 기호를 붙여넣기하여 알 수 있습니다. +REPL 및 다른 여러 줄리아 편집 환경에서 많은 유니코드 수학 기호를 입력할 수 있다. +`\` - *LaTeX 기호명* - *tab*을 입력하면 기호로 변환된다. +예를 들어 변수명 δ는 `\delta`-tab, `α̂₂`는 `\alpha`-*tab*-`\hat`-*tab*-`\_2`-*tab* 으로 입력할 수 있다. +특정 기호의 LaTex 기호명이 궁금하다면 REPL에서 ?(help 호출)를 입력하고 원하는 유니코드 기호를 넣어서 확인할 수 있다. -julia는 심지어 내장 상수와 함수조차도 필요하다면 재정의합니다.(잠재적인 혼란을 피하기 위해 추천하지는 않습니다.) +julia는 심지어 내장 상수와 함수를 필요한 경우 변수로 재정의할 수 있다(추천하지 않는 방법이다): ``` julia> pi = 3 3 @@ -70,7 +70,7 @@ julia> sqrt = 4 4 ``` -그러나 이미 사용 중인 내장 상수와 함수를 다시 정의하려고 하면 julia는 다음과 같은 에러를 냅니다. +그러나 이미 사용했던 내장 상수나 함수를 다시 정의하려고 하면 다음과 같은 오류를 낸다. ```jldoctest julia> pi @@ -86,19 +86,21 @@ julia> sqrt = 4 ERROR: cannot assign a value to variable Base.sqrt from module Main ``` -##허용된 변수 이름 +##허용하는 변수 이름 + +변수 이름은 문자(A-Z 또는 a-z), 밑줄(`_`) 또는 00A0보다 큰 유니코드 코드의 부분 집합으로 시작해야 한다. +특히 [유니 코드 문자 범주] (http://www.fileformat.info/info/unicode/category/index.htm) Lu/Ll/Lt/Lm/Lo/Nl(문자), Sc/So(통화 및 기타 기호) 및 기타 문자와 유사한 문자(Sm의 부분집합)가 허용된다. +그 다음 문자는 !와 숫자 (0-9와 Nd/No에 포함된 문자) 및 기타 유니코드 코드 포인트: (Mn/Mc/Me/Sk)의 발음 구별 기호 및 기타 수정 표시, 구두점(Pc), 소수(primes) 및 몇 가지 다른 문자)를 포함할 수 있다. -변수 이름은 문자(A-Z 또는 a-z), 밑줄 또는 00A0보다 큰 유니코드 코드의 하위 집합으로 시작해야 합니다. 특히 [유니 코드 문자 범주] (http://www.fileformat.info/info/unicode/category/index.htm)Lu/Ll/Lt/Lm/Lo/Nl(문자), Sc/So(통화 및 기타 기호) 및 기타 문자와 유사한 문자(예 : Sm 수학 기호의 서브 세트)가 허용됩니다. 그다음 문자는 !와 숫자 (0-9 및 Nd/No 범주의 다른 문자) 및 기타 유니코드 코드 포인트(Mn/Mc/Me/Sk 범주의 발음 구별 기호 및 기타 수정 표시, Pc 범주의 일부 구두점 커넥터, 소수(primes) 및 몇 가지 다른 문자)가 포함되어 있습니다. +`+`와 같은 연산자도 유니코드에 포함되지만 예외적으로 파싱된다. +일부 조건에서는 연산자를 변수로 사용할 수 있다. +예를 들어`(+)`는 더하기 함수를 가리키고, `(+) = f`로 재할당을 할 수 있다. +`⊕`와 같은 대부분의 유니코드 중위 연산자(Sm)는 Julia의 중위 연산자로 파싱되며 사용자 정의 메소드(예 :크로네커 곱을 정의하기 위해`const ⊗ = kron`를 정의)를 사용할 수도 있다. +연산자는 수정 기호, 프라임 기호, 윗첨자/아래첨자를 접두로 붙일 수 있다. +예를 들어 `+̂ₐ″`는`+`와 같은 우선 순위를 가진 중위 연산자로 파싱된다. -`+`와 같은 연산자도 유효한 식별자이지만 특별히 구문 분석됩니다. 일부 상황에서는 연산자 -변수와 마찬가지로 사용할 수 있습니다. 예를 들어`(+)`는 더하기 함수를,`(+) = f`는그것을 재 할당합니다. `⊕ '와 같은 대부분의 유니 코드 중온 연산자 (범주 Sm에서)는 - 파싱됩니다 -중온 연산자 (infix operators)로 사용되며 사용자 정의 메소드 (예 :`const ⊗ = kron`를 사용할 수 있습니다. -'⊗`을 크로 니커 제품으로 정의). 연산자에는 수정 표시가 붙을 수 있습니다. -소수 (primes), 서브 / 윗 첨자 (sub / superscript). `+ ₐ '`는`+`와 같은 우선 순위 -를 가진 중위 연산자로 파싱됩니다. -명시 적으로 허용되지 않는 변수 이름은 내장 명령문의 이름입니다. +허용되지 않는 변수 이름은 내장 [Keywords](@ref)뿐이다. ```julia-repl @@ -109,24 +111,17 @@ julia> try = "No" ERROR: syntax: unexpected "=" ``` +일부 유니코드 문자는 동등하게 간주된다. +유니코드가 달라도 문자가 같으면 동일하게 취급된다(Julia는 NFC 표준을 사용함). +예를 들어 유니 코드 문자`ɛ` (U + 025B : 라틴어 소문자 열린e)와 `μ`(U + 00B5 : 마이크로 부호)는 이와 형태가 같은 그리스 문자와 동일하게 취급된다. -일부 유니 코드 문자는 식별자에서 동등한 것으로 간주됩니다. -문자 조합 (예 : 악센트)을 입력하는 다양한 방법 -(줄리아 식별자는 NFC 표준화되어 있음). -유니 코드 문자`ɛ` (U + 025B : 라틴 소문자 e) -및 'μ'(U + 00B5 : 마이크로 부호)는 대응하는 -전자는 일부 입력 방법을 통해 쉽게 액세스 할 수 있기 때문에 그리스 문자를 사용합>니다. ## 문체 규칙 -Julia는 유효한 이름에 대해 제한을 두지 않지만 다음을 채택하는 것이 유용 해졌습니 -다 -협약 : +Julia는 변수 명명법이 자유롭지만 다음 규칙을 준수하는 것을 추천한다: - * 변수는 소문자를 사용합니다. - * (`'_'`)를 사용할수 있지만,사용 안하는 것이 좋습니다.(다른사람이 사용하기 불 - 편합니다) - * `Type`과`Module`의 이름은 대문자로 시작하고 단어 분리는 upper - camel 경우에 대신에 underscores. - * `함수`와`매크로`의 이름에는 밑줄을 넣지 않습니다 - * 인수에 쓰는 함수의 이름은!로 끝납니다. 이들은 때때로 "mutating"또는 "in-place"함수라고 불리는데, 그 이유는 값을 반환하는 것이 아니라 함수가 호출 된 후에 인>수가 변경되기 때문입니다. + * 변수는 소문자를 사용한다. + * `'_'`와 같은 문자는 다른 사람을 배려해 되도록 사용하지 않는다. + * 타입과 모듈 이름은 대문자로 시작하고 단어 분리는 밑줄(`_`)대신 쌍봉낙타 표기법(UpperCamelCase: 모든 단어의 첫글자를 대문자로 표기)을 지향한다. + * `함수`와`매크로`의 이름에는 밑줄을 넣지 않는다. + * in-place 함수의 이름은 `!`로 끝난다. From 45ec5ed5128dcb7f4d85a26563345876f798b972 Mon Sep 17 00:00:00 2001 From: Dohyeon Lee Date: Fri, 4 Sep 2020 23:21:24 +0900 Subject: [PATCH 133/153] =?UTF-8?q?=ED=95=A8=EC=88=98=20=EB=8B=A4=EC=A4=91?= =?UTF-8?q?=20=EC=9D=B8=EC=9E=90=20=EB=B2=88=EC=97=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/manual/arrays.md | 8 ++++---- src/manual/control-flow.md | 14 +++++++------- src/manual/functions.md | 35 +++++++++++++++-------------------- src/manual/getting-started.md | 31 +++++++++++++++++++++---------- 4 files changed, 47 insertions(+), 41 deletions(-) diff --git a/src/manual/arrays.md b/src/manual/arrays.md index cc2a159..0f51fbc 100644 --- a/src/manual/arrays.md +++ b/src/manual/arrays.md @@ -16,9 +16,9 @@ Julia 컴파일러는 타입 추론을 통해 스칼라 배열 인덱싱에 최 줄리아는 함수에 인자를 줄 때 "공유를 통한 전달([pass-by-sharing](https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing))을 한다. 몇몇 프로그래밍 언어는 배열을 값으로 전달하여([pass-by-value](https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_value)), 원치않는 수정을 막지만 무분별한 값의 복사로 인해 속도 지연을 겪을 수 있다. -줄리아는 관습적으로 `!`울 함수 이름의 마지막에 붙여 값이 수정되거나 삭제될 수 있음을 미연에 알려준다([`sort`](@ref)와 [`sort!`](@ref)를 비교해보자). -함수내에서 객체를 수정하지 않으려면 명시적으로 복사를 해야한다. -이렇게 객체를 수정하지 않는 함수는 `!`이 붙여진 동일 이름의 함수와 같은 역할을 하면서 복사된 객체를 반환한다. +Julia는 함수 내에서 값이 수정되거나 삭제될 가능성을 있을 때, 관습적으로 `!`을 함수 이름의 마지막에 붙여서 알려준다([`sort`](@ref)와 [`sort!`](@ref)를 비교해보자). +Collee가 객체의 수정을 피하려면 명시적으로 객체를 복사를 해야한다. +객체를 수정하지 않는 함수는 `!`이 붙여진 동일 이름의 함수와 같은 역할을 하면서 복사된 객체를 반환한다. ## 기본 함수 @@ -38,7 +38,7 @@ Julia 컴파일러는 타입 추론을 통해 스칼라 배열 인덱싱에 최 ## 생성과 초기화 배열을 생성하고 초기화 하는 많은 함수가 있다. -다음에 나열된 함수들에서, `dims...` 인수는 차원의 크기들을 나타내는 튜플 하나를 받거나, 혹은 각 차원의 크기를 여러 인수로 받을 수 있다. +다음에 나열된 함수들에서 `dims...` 인수는 차원의 크기들을 나타내는 튜플 하나를 받거나, 혹은 각 차원의 크기를 여러 인수로 받을 수 있다. 이 함수들의 대부분은 첫번째 인수로 배열의 원소 타입 `T`를 받을 수 있다. `T`가 생략되었다면 [`Float64`](@ref)가 기본값이다. diff --git a/src/manual/control-flow.md b/src/manual/control-flow.md index 1cc82f5..748279d 100644 --- a/src/manual/control-flow.md +++ b/src/manual/control-flow.md @@ -1,12 +1,12 @@ -# Control Flow +# 제어 흐름 -Julia는 다양한 제어 흐름 구조를 제공합니다. +Julia는 다양한 제어 흐름 구조를 제공한다. - * 복합 표현: `begin` 및 `(;)`. - * 조건부 평가: `if`-`elseif`-`else` 및 `?:` (삼항 연산자). - * 단락 평가: `&&`, `||` 및 연속 비교문. - * 반복 평가: 루프: `while` 및 `for`. - * 예외 처리: `try`-`catch`, `error` 및 `throw`. + * 복합 표현: `begin`및 `(;)`. + * 조건부 평가: `if`-`elseif`-`else`및 `?:` (삼항 연산자). + * 단락 계산: `&&`, `||`및 연속 비교문. + * 반복 게산: `while`및 `for`. + * 예외 처리: `try`-`catch`, `error`및 `throw`. * 태스크(일명 코루틴): `yieldto`. 처음 5개의 제어 흐름 메커니즘은 고급 프로그래밍 언어의 표준입니다. 하지만 `태스크`는 그렇지 않습니다. 태스크는 비지역적 제어 흐름을 제공하여, 일시적으로 중단된 계산을 바꾸는 것을 가능하게 만듭니다. 태스크는 강력한 구조입니다: Julia는 예외 처리 및 협력적 멀티태스킹 모두를 태스크를 사용하여 구현합니다. 일상적인 프로그래밍에서는 태스크를 사용할 필요가 없지만, 몇몇 문제는 태스크를 사용함으로써 더 쉽게 해결될 수 있습니다. diff --git a/src/manual/functions.md b/src/manual/functions.md index f99fbd9..e4f2a2f 100644 --- a/src/manual/functions.md +++ b/src/manual/functions.md @@ -1,6 +1,6 @@ # [함수](@id man-functions) -함수는 인자를 받아 값을 리턴하는 객체이다. Julia에서 정의하는 함수는 실행 상황에 영향을 받는다는 점에서 수학적 정의에 따른 함수와는 다르다. 아래는 Julia에서 함수는 정의하는 가장 기본적인 방법이다: +함수는 인자를 받아 값을 반환하는 객체이다. Julia에서 정의하는 함수는 실행 상황에 영향을 받는다는 점에서 수학적 정의에 따른 함수와는 조금 다르다. 아래는 Julia에서 함수는 정의하는 가장 기본적인 방법이다: ```jldoctest julia> function f(x,y) @@ -220,10 +220,9 @@ julia> x[2] 크기가 1인 튜플을 만들고 싶어도 `(1,)`처럼 꼭 반점을 넣어야 한다. `(1)`은 값을 소괄호로 감싼 것으로 취급된다. `()`은 비어 있는 튜플을 생성한다. -## Named Tuples +## 지명 튜플(Named tuple) -The components of tuples can optionally be named, in which case a *named tuple* is -constructed: +튜플의 인자에 이름을 부여할 수 있으며 이를 *지명 튜플*이라고 한다: ```jldoctest julia> x = (a=1, b=1+1) @@ -233,15 +232,14 @@ julia> x.a 1 ``` -Named tuples are very similar to tuples, except that fields can additionally be accessed by name -using dot syntax (`x.a`). +지명 튜플은 이름이 있다는 것을 제외하면 일반적인 튜플과 유사하며, dot 문법을 통해 값에 접근할 수 있다 (`x.a`). -## Multiple Return Values +## 다중 반환값 -In Julia, one returns a tuple of values to simulate returning multiple values. However, tuples -can be created and destructured without needing parentheses, thereby providing an illusion that -multiple values are being returned, rather than a single tuple value. For example, the following -function returns a pair of values: +여러 값을 반환하기 위해 함수는 튜플을 반환한다. +하지만 튜플은 괄호 없이 생성되기도 하고 분리되기도 하므로 명시적으로 튜플을 사용한다는 것을 나타낼 필요가 없다. +이는 우리가 값을 여러개 반환한다는 환상을 심어준다. +예제로 두개의 값을 반환하는 상황을 보자: ```jldoctest foofunc julia> function foo(a,b) @@ -250,16 +248,14 @@ julia> function foo(a,b) foo (generic function with 1 method) ``` -If you call it in an interactive session without assigning the return value anywhere, you will -see the tuple returned: +대화형 실행환경에서 함수를 실행하면 튜플이 반환되는 것을 확인할 수 있다: ```jldoctest foofunc julia> foo(2,3) (5, 6) ``` -A typical usage of such a pair of return values, however, extracts each value into a variable. -Julia supports simple tuple "destructuring" that facilitates this: +보통의 경우 튜플의 값을 변수로 각각 분리하고 사용하기 때문에, Julia는 튜플을 분리할 수 있는 간단한 방법을 제공하여 편의성을 높였다: ```jldoctest foofunc julia> x, y = foo(2,3) @@ -272,7 +268,8 @@ julia> y 6 ``` -You can also return multiple values via an explicit usage of the `return` keyword: +`return`으로도 다중 변수 반환을 할 수 있다. +아래 예제는 이전 예제와 똑같이 작동한다: ```julia function foo(a,b) @@ -280,9 +277,7 @@ function foo(a,b) end ``` -This has the exact same effect as the previous definition of `foo`. - -## Argument destructuring +## 인자 분리 The destructuring feature can also be used within a function argument. If a function argument name is written as a tuple (e.g. `(x, y)`) instead of just @@ -301,7 +296,7 @@ Notice the extra set of parentheses in the definition of `range`. Without those, `range` would be a two-argument function, and this example would not work. -## Varargs Functions +## 가변인자 함수 It is often convenient to be able to write functions taking an arbitrary number of arguments. Such functions are traditionally known as "varargs" functions, which is short for "variable number diff --git a/src/manual/getting-started.md b/src/manual/getting-started.md index 042a03f..242478a 100644 --- a/src/manual/getting-started.md +++ b/src/manual/getting-started.md @@ -1,9 +1,11 @@ # [시작하기](@id man-getting-started) -줄리아의 설치는 어렵지 않다. 미리 컴파일된 실행파일을 이용하거나, 아니면 소스로부터 직접 컴파일하는 두가지 방법이 존재한다. [https://julialang.org/downloads/](https://julialang.org/downloads/)에서 - 알려주는 방법에 따라 Julia를 다운로드하고 설치하면 된다. +줄리아의 설치는 어렵지 않다. +미리 만들어진 실행파일을 사용하거나, 소스로부터 직접 컴파일하는 두 방법이 있다. +[https://julialang.org/downloads/](https://julialang.org/downloads/)에서 알려주는 방법에 따라 Julia를 다운로드하고 설치하면 된다. -Julia를 처음 접할 때는 대화형 실행 환경을 통해서 시작하는 것이 가장 쉽게 Julia를 익힐 수 있는 방법이다. 대화형 실행 환경은 단순히 Julia 실행파일을 더블 클릭하거나, 명령창에서 `julia` 명령어를 입력하여 실행할 수 있다. +Julia 대화형 실행 환경(REPL)은 Julia를 가장 쉽게 익힐 수 있는 수단이다. +대화형 실행 환경은 단순히 Julia 실행파일을 더블 클릭하거나, 명령창에 `julia`를 입력해 실행할 수 있다. ```@eval io = IOBuffer() @@ -13,12 +15,16 @@ import Markdown Markdown.parse("```\n\$ julia\n\n$(banner)\njulia> 1 + 2\n3\n\njulia> ans\n3\n```") ``` -대화형 실행 환경을 종료하기 위해서는 `CTRL-D`(컨트롤/`^` 키와 `d` 키를 함께 누른다) 를 입력하거나 -`exit()`를 대화형 실행 환경 입력창에 타이핑한다. 대화형 실행 환경을 실행하면, 위와 같이 `julia` 배너가 보여지고, 커서창이 사용자의 입력을 기다리며 깜빡이고 있다. 사용자가 `1 + 2`, 와 같은 표현식을 입력한 뒤, 엔터 버튼을 누르는 순간, Julia는 표현식을 평가하고 그 결과를 보여준다. 만약 사용자가 입력한 표현식이 세미콜론(;)으로 끝난다면, 대화형 실행 환경은 결과를 바로 보여주지 않는다. 대신에 `ans` 라는 변수가 결과를 보여주든 보여주지 않든 가장 마지막으로 계산된 표현식의 결과를 저장하고 있다 `ans` 변수는 대화형 실행 환경에서만 존재하며, 다른 방식으로 동작하는 Julia 코드 상에서는 나타나지 않는다. +대화형 실행 환경을 종료하기 위해서는 `CTRL-D`(컨트롤 키와 `d` 키를 함께 누른다) 를 누르거나 `exit()`를 입력한다. +대화형 실행 환경을 실행하면, 위와 같이 `julia` 배너가 보여지고, 커서창이 사용자의 입력을 기다리며 깜빡이고 있다. +사용자가 `1 + 2`와 같은 표현식을 입력한 뒤 엔터 버튼을 누르면 Julia는 표현식을 계산하고 결과를 보여준다. +만약 사용자가 입력한 표현식이 세미콜론(;)으로 끝난다면, 대화형 실행 환경은 결과를 화면에 보여주지 않는다. +대신 `ans` 라는 변수가 가장 마지막으로 계산된 표현식의 결과를 저장하고 있으므로 이를 활용할 수 있다. +`ans` 변수는 대화형 실행 환경에서만 존재하며, 다른 방식으로 동작하는 Julia 코드 상에서는 나타나지 않는다. -`file.jl`라는 소스 파일에 저장되어 있는 표현식을 계산하기 위해서는, `include("file.jl")`와 같이 입력한다. +`file.jl`라는 소스 파일에 저장되어 있는 코드를 실행하기 위해서는`include("file.jl")`을 입력하면 된다. -대화형 실행 환경을 이용하지 않고 파일에 저장되어 있는 소스 코드를 실행하기 위해서는, 소스 코드 파일 이름을`julia` 명령어의 첫번째 매개 변수로 넣어서 실행한다. +대화형 실행 환경을 이용하지 않고 파일에 저장되어 있는 코드를 실행하기 위해서는, 소스 파일 이름을 `julia` 명령어의 첫번째 매개 변수로 넣어서 실행한다. 명령어: @@ -26,7 +32,12 @@ Markdown.parse("```\n\$ julia\n\n$(banner)\njulia> 1 + 2\n3\n\njulia> ans\n3\n`` $ julia script.jl arg1 arg2... ``` -예제와 같이 `julia` 실행 명령 뒤에 오는 매개변수들은 전역 상수 `ARGS`라고 불리우는 `script.jl`라는 프로그램의 명령줄 인자로 작동한다. 이 프로그램의 이름은 전역 상수 `PROGRAM_FILE` 에도 설정된다. 또한 `ARGS`는 이 뿐만이 아니라`-e` 옵션을 통해서 julia 스크립트를 실행할 때도 설정할 수 있음을 알 필요가 있다. 그러나 이 경우에는 `PROGRAM_FILE` 은 아무것도 설정되지 않은 채로 실행될 것이다.(아래의 `julia` 도움말을 보도록 하자.) 예를 들어, 단순히 스크립트에 주어진 명령줄 인자를 출력할 때는 다음과 같이 입력하면 된다. +예제와 같이 `julia` 실행 명령 뒤에 오는 매개변수들은 전역 상수 `ARGS`라고 불리우는 `script.jl`라는 프로그램의 명령줄 인자로 작동한다. +이 프로그램의 이름은 전역 상수 `PROGRAM_FILE` 에도 설정된다. +또한 `ARGS`는 이 뿐만이 아니라`-e` 옵션을 통해서 julia 스크립트를 실행할 때도 설정할 수 있음을 알 필요가 있다. +그러나 이 경우에는 `PROGRAM_FILE` 은 아무것도 설정되지 않은 채로 실행될 것이다. +(아래의 `julia` 도움말을 보도록 하자.) +예를 들어, 단순히 스크립트에 주어진 명령줄 인자를 출력할 때는 다음과 같이 입력하면 된다. ``` $ julia -e 'println(PROGRAM_FILE); for x in ARGS; println(x); end' foo bar @@ -55,7 +66,7 @@ See also [Scripting](@ref man-scripting) for more information on writing Julia s Julia는 `-p` 옵션이나 `--machine-file` 옵션을 이용하여 병렬 환경에서 실행시킬 수 있다. `-p n` 옵션은 n개의 worker 프로세스를 생성하지만, `--machine-file file` 옵션은 file의 각 행에 지정된 노드마다 worker를 생성한다. `file` 에 지정된 노드(machine)들은 `ssh` 로그인을 통해 패스워드가 필요없이 실행할 수 있어야 하며, Julia는 현재 호스트와 같은 경로에 설치가 되어 있어야 한다. `file` 에 작성되는 노드는 `[count*][user@]host[:port] [bind_addr[:port]]` 와 같은 형식으로 작성한다. `user` 는 현재 user id를 나타내고, `port` 는 기본 ssh port, `count` 는 각 노드당 생성하는 worker의 개수 (기본값 : 1) `bin-to bind_addr[:port]` 은 선택적인 옵션으로 다른 worker들이 현재의 worker로 연결하기 위해 필요한 특정 IP 주소와 포트를 지정한다. -만약 Julia가 실행할 때마다 실행되는 코드가 있다면, 그 코드를 `~/.juliarc.ji` 에 넣으면 된다. +만약 Julia가 실행할 때마다 실행되는 코드가 있다면, 그 코드를 `~/.julia/config/startup.jl` 에 넣으면 된다. ``` $ echo 'println("Greetings! 你好! 안녕하세요?")' > ~/.julia/config/startup.jl @@ -65,7 +76,7 @@ Greetings! 你好! 안녕하세요? ... ``` -`perl` 과 `ruby` 와 같이, Julia 코드를 실행하고 옵션을 지정하는 방법은 다음과 같이 여러가지가 있다. +`perl` 과 `ruby` 와 같이, Julia 코드를 실행하고 옵션을 지정하는 방법은 다음과 같이 여러가지가 있다. ``` julia [switches] -- [programfile] [args...] From c883ecfec842aa0418b2f92ec74e699d5d8b3340 Mon Sep 17 00:00:00 2001 From: Dohyeon Lee Date: Fri, 2 Oct 2020 22:25:59 +0900 Subject: [PATCH 134/153] =?UTF-8?q?Control=20flow,=20function=20=EC=B1=95?= =?UTF-8?q?=ED=84=B0=20=EB=B3=80=EA=B2=BD=20Control=20flow:=20evalutation?= =?UTF-8?q?=20=ED=95=B4=EC=84=9D=20=EB=B3=80=EA=B2=BD(=ED=8F=89=EA=B0=80?= =?UTF-8?q?=20->=20=EA=B3=84=EC=82=B0),=20=EB=B2=88=EC=97=AD=20=EB=90=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EC=9D=80=20=EB=B6=80=EB=B6=84=20=EB=B2=88?= =?UTF-8?q?=EC=97=AD=20functions:=20=EB=B2=88=EC=97=AD=EB=90=98=EC=A7=80?= =?UTF-8?q?=20=EC=95=8A=EC=9D=80=20=EB=B6=80=EB=B6=84=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/manual/control-flow.md | 93 ++++++++++++++++++++------------------ src/manual/functions.md | 56 ++++++++--------------- 2 files changed, 67 insertions(+), 82 deletions(-) diff --git a/src/manual/control-flow.md b/src/manual/control-flow.md index 748279d..43a0ca7 100644 --- a/src/manual/control-flow.md +++ b/src/manual/control-flow.md @@ -1,19 +1,24 @@ # 제어 흐름 -Julia는 다양한 제어 흐름 구조를 제공한다. +Julia는 다양한 제어 흐름 문법을 제공합니다. * 복합 표현: `begin`및 `(;)`. - * 조건부 평가: `if`-`elseif`-`else`및 `?:` (삼항 연산자). + * 조건부 계산: `if`-`elseif`-`else`및 `?:` (삼항 연산자). * 단락 계산: `&&`, `||`및 연속 비교문. - * 반복 게산: `while`및 `for`. + * 반복 계산: `while`및 `for`. * 예외 처리: `try`-`catch`, `error`및 `throw`. * 태스크(일명 코루틴): `yieldto`. -처음 5개의 제어 흐름 메커니즘은 고급 프로그래밍 언어의 표준입니다. 하지만 `태스크`는 그렇지 않습니다. 태스크는 비지역적 제어 흐름을 제공하여, 일시적으로 중단된 계산을 바꾸는 것을 가능하게 만듭니다. 태스크는 강력한 구조입니다: Julia는 예외 처리 및 협력적 멀티태스킹 모두를 태스크를 사용하여 구현합니다. 일상적인 프로그래밍에서는 태스크를 사용할 필요가 없지만, 몇몇 문제는 태스크를 사용함으로써 더 쉽게 해결될 수 있습니다. +태스크를 제외한 나머지 문법들은 프로그래밍 언어의 표준 문법이라 할 수 있습니다. +태스크는 이들과 다르며, 여러 계산을 일시적으로 중단하고 다시 실행하는 능력을 가집니다. +태스크는 강력한 구조이며, Julia는 예외 처리 및 협력적 멀티태스킹을 태스크로 구현합니다. +많은 경우 태스크를 사용할 필요가 없지만, 몇몇 문제는 태스크를 사용함으로써 더 쉽게 해결될 수 있습니다. ## [복합 표현](@id man-compound-expressions) -때로는 여러 하위식을 순서대로 평가하는 단 하나의 식이 더 편리하며, 이 경우 마지막 하위식의 값을 그 값으로 반환하게 됩니다. 이를 수행하는 두 개의 Julia 구조가 있습니다: 바로 `begin` 구문과 `(;)` 체인 구문입니다. 두 복합 표현 구조의 값은 마지막 하위식의 값입니다. 다음은 `begin` 구문의 예제입니다. +때로는 여러 하위식을 순서대로 계산하는 단 하나의 식이 더 편리하며, 이 경우 마지막 하위식의 값을 그 값으로 반환하게 됩니다. +이를 수행하는 두 개의 Julia 구조가 있습니다: 바로 `begin` 구문과 `(;)` 체인 구문입니다. +두 복합 표현의 반환값은 가장 마지막에 계산된 값입니다. 다음은 `begin` 구문의 예제입니다. ```jldoctest julia> z = begin @@ -24,7 +29,7 @@ julia> z = begin 3 ``` -위와 같이 식의 길이가 매우 짧고 단순하다면, 유용한 `(;)` 체인 구문을 사용해 한 줄로 쉽게 표현할 수 있습니다. +위와 같이 식의 길이가 매우 짧고 단순하다면, `(;)` 체인 구문을 사용해 한 줄로 쉽게 표현할 수 있습니다. ```jldoctest julia> z = (x = 1; y = 2; x + y) @@ -43,9 +48,9 @@ julia> (x = 1; 3 ``` -## [조건부 평가](@id man-conditional-evaluation) +## [조건부 계산](@id man-conditional-evaluation) -조건부 평가는 논리식의 값에 따라 일부 코드의 실행 여부를 결정합니다. 다음은 `if`-`elseif`-`else` 조건 구문의 구조입니다. +조건부 계산는 논리식의 값에 따라 일부 코드의 실행 여부를 결정합니다. 다음은 `if`-`elseif`-`else` 조건 구문의 구조입니다. ```julia if x < y @@ -57,7 +62,7 @@ else end ``` -조건식 `x < y`가 `true`이면 해당 블록이 실행됩니다. 참이 아니라면, 조건식 `x > y`를 평가하고 `true`이면 해당 블록이 실행됩니다. 만약 두 표현 둘 다 참이 아니라면, `else` 블록이 실행됩니다. 다음은 실행 예제입니다. +조건식 `x < y`가 `true`이면 해당 블록이 실행됩니다. 참이 아니라면, 조건식 `x > y`를 계산하고 `true`이면 해당 블록이 실행됩니다. 만약 두 표현 둘 다 참이 아니라면, `else` 블록이 실행됩니다. 다음은 실행 예제입니다. ```jldoctest julia> function test(x, y) @@ -81,9 +86,10 @@ julia> test(1, 1) x is equal to y ``` -`elseif`와 `else` 블록은 선택 사항이며, 원하는 만큼 많은 `elseif` 블록을 사용할 수 있습니다. `if`-`elseif`-`else` 구문 안의 조건식은 어느 한 식이 처음으로 `true`로 평가될 때까지 평가되고, 그 후에 관련 블록이 실행되며, 이후로는 어떤 식이나 블록도 실행되지 않습니다. +`elseif`와 `else` 블록은 선택 사항이며, 원하는 만큼 많은 `elseif` 블록을 사용할 수 있습니다. `if`-`elseif`-`else` 구문 안의 조건식은 어느 한 식이 처음으로 `true`로 계산될 때까지 계산되고, 그 후에 관련 블록이 실행되며, 이후로는 어떤 식이나 블록도 실행되지 않습니다. -`if` 블록은 지역 범위를 만들지 않기 때문에 한 마디로 "구멍이 났다"고 할 수 있습니다. 이는 `if` 절 안에서 정의된 새로운 변수가 `if` 블록 다음에도 사용될 수 있음을 의미합니다. 따라서, 위에서 정의한 `test` 함수를 다음과 같이 정의할 수도 있습니다. +`if` 블록은 지역 스코프를 만들지 않기 때문에 `if` 절 안에서 정의된 새로운 변수를 `if` 블록 밖에서도 사용할 수 있습니다. +따라서, 위에서 정의한 `test` 함수를 다음과 같이 정의할 수도 있습니다. ```jldoctest; filter = r"Stacktrace:(\n \[[0-9]+\].*)*" julia> function test(x,y) @@ -138,7 +144,7 @@ julia> if x > 0 "positive!" ``` -아주 짧은(한 줄로 된) 조건문은 다음 절에 설명되었듯이 Julia의 단락 회로 평가를 통해 자주 표현된다는 것을 유념하시기 바랍니다. +아주 짧은(한 줄로 된) 조건문은 다음 절에 설명되었듯이 Julia의 단락 회로 계산을 통해 자주 표현된다는 것을 유념하시기 바랍니다. C, MATLAB, Perl, Python, Ruby와는 다르게 조건식의 값이 `true`나 `false`가 아니면 오류가 발생하며, 이는 Java와 같이 자료형을 엄격하게 다루는 언어와 비슷하다고 할 수 있습니다. @@ -157,7 +163,7 @@ ERROR: TypeError: non-boolean (Int64) used in boolean context a ? b : c ``` -`?` 앞의 `a`는 조건식이고, 삼항 연산자는 `a`가 `true`이면 `:` 앞의 `b`를, `false`이면 `:` 뒤의 `c`를 실행합니다. 여기서 `?`와 `:` 주위에는 공백이 있어야 함을 명심하십시오. `a?b:c`와 같은 식은 유효하지 않은 식입니다.(다만 `?`와 `:` 각각의 뒤에 개행 문자는 사용 가능) +`?` 앞의 `a`는 조건식이고, 삼항 연산자는 `a`가 `true`이면 `b`를, `false`이면 `c`를 실행합니다. 여기서 `?`와 `:` 주위에는 공백이 있어야 함을 명심하십시오. `a?b:c`와 같은 식은 유효하지 않은 식입니다.(다만 `?`와 `:` 각각의 뒤에 개행 문자는 사용 가능) 이 동작을 이해하는 가장 쉬운 방법은 예제를 보는 것입니다. 이전 예제에서 `println` 호출은 세 브랜치 모두에서 공유되었습니다. 실제로 고른 것은 오직 출력할 리터럴 문자열이었습니다. 이제 삼항 연산자를 사용하여 보다 간결하게 예제를 작성할 수 있습니다. 명확히 하기 위해, 먼저 둘 중 하나를 고르는 버전을 사용해 봅시다. @@ -173,7 +179,7 @@ julia> println(x < y ? "less than" : "not less than") not less than ``` -`x < y` 식이 참이면, 전체 삼항 연산자 식은 `"미만"` 문자열을 평가하고, 거짓이면 `"이상"` 문자열을 평가할 것입니다. 기존의 셋 중 하나를 고르는 예제를 구현하려면 삼항 연산자를 여러 번 사용하여 중첩할 필요가 있습니다. +`x < y` 식이 참이면, 전체 삼항 연산자 식은 `"less than"` 문자열을 계산하고, 거짓이면 `"not less than"` 문자열을 출력할 것입니다. 기존의 셋 중 하나를 고르는 예제를 구현하려면 삼항 연산자를 여러 번 사용하여 중첩할 필요가 있습니다. ```jldoctest julia> test(x, y) = println(x < y ? "x is less than y" : @@ -192,7 +198,7 @@ x is equal to y 연결을 쉽게 하기 위해 연산자는 오른쪽에서 왼쪽으로 연결됩니다. -`if`-`elseif`-`else`와 같이 조건식이 각각 `true`나 `false`로 평가될 때만 `:` 앞뒤로 있는 식이 평가된다는 점 역시 중요합니다. +`if`-`elseif`-`else`와 같이 조건식이 각각 `true`나 `false`로 계산될 때만 `:` 앞뒤로 있는 식이 계산된다는 점 역시 중요합니다. ```jldoctest julia> v(x) = (println(x); x) @@ -207,12 +213,12 @@ no "no" ``` -## [단락 평가](@id Short-Circuit-Evaluation) +## [단락 계산](@id Short-Circuit-Evaluation) -단락 평가는 조건부 평가와 상당히 유사합니다. 이 동작은 `&&` 및 `||` 연산자가 있는 대부분의 명령형 프로그래밍 언어에서 찾을 수 있습니다. 이런 연산자로 연결된 일련의 표현식에서, 최종 논리값을 결정하는 데 필요한 최소 식만 평가됩니다. 명쾌하게 말하자면, 이는 다음을 의미합니다. +단락 계산는 조건부 계산와 상당히 유사합니다. 이 동작은 `&&` 및 `||` 연산자가 있는 대부분의 명령형 프로그래밍 언어에서 찾을 수 있습니다. 이런 연산자로 연결된 일련의 표현식에서, 최종 논리값을 결정하는 데 필요한 최소 식만 계산됩니다. 명쾌하게 말하자면, 이는 다음을 의미합니다. - * 표현식 `a && b`에서, 하위 표현식 `b`는 오직 `a`가 `true`로 평가될 때만 평가를 받는다. - * 표현식 `a || b`에서, 하위 표현식 `b`는 오직 `a`가 `false`로 평가될 때만 평가를 받는다. + * 표현식 `a && b`에서, 하위 표현식 `b`는 오직 `a`가 `true`로 계산될 때만 계산을 받는다. + * 표현식 `a || b`에서, 하위 표현식 `b`는 오직 `a`가 `false`로 계산될 때만 계산을 받는다. 왜냐 하면, `a`가 `false`이면, `b`의 값에 관계없이 `a && b`는 무조건 `false`가 되고, `a`가 `true`이면, `b`의 값에 관계없이 `a && b`는 무조건 `true`가 되기 때문입니다. `&&`와 `||` 모두 오른쪽에 연관되지만, `&&`가 `||`보다 우선 순위가 더 높습니다. 실험해 보면 동작을 이해하기 쉽습니다. @@ -264,7 +270,7 @@ false 이 동작은 Julia에서 매우 짧은 `if` 문의 대용으로 자주 사용됩니다. `if <조건> <문장> end` 대신에, `<조건>` 그리고 나서 `<문장>`이라고 읽을 수 있는 `<조건> && <문장>`을 쓸 수 있습니다. 비슷하게, `if ! <조건> <문장> end` 대신에, `<조건>` 아니면 `<문장>`이라고 읽을 수 있는 `<조건> || <문장>`을 쓸 수 있습니다. -예제로 재귀적 팩토리얼 함수를 다음과 같이 선언할 수 있습니다. +예제로 팩토리얼 함수를 다음과 같이 재귀적으로 선언할 수 있습니다. ```jldoctest; filter = r"Stacktrace:(\n \[[0-9]+\].*)*" julia> function fact(n::Int) @@ -288,7 +294,7 @@ Stacktrace: [3] top-level scope ``` -Mathematical Operations and Elementary Functions: `&` 및 `|`에서 소개한 비트 논리 연산자로 단락 평가가 없는 논리 연산을 할 수 있습니다. 그것들은 이항연산자 구문을 지원하지만, 항상 인수를 평가하는 일반적인 함수라고 할 수 있습니다. +단락 계산이 없는 논리 연산은 [산술 연산과 기본 함수](@ref mathematical-operations)에서 소개된 비트 논리 연산자 `&`, `|` 로 할 수 있습니다. 이들은 이항연산자 구문을 지원하지만, 항상 인수를 계산하는 일반적인 함수라고 할 수 있습니다. ```jldoctest tandf julia> f(1) & t(2) @@ -309,7 +315,7 @@ julia> 1 && true ERROR: TypeError: non-boolean (Int64) used in boolean context ``` -반면에 조건부 체인 끝에는 어떤 표현식이든 사용할 수 있습니다. 이는 선행 조건에 따라 평가되고 반환될 것이기 때문입니다. +반면에 조건부 체인 끝에는 어떤 표현식이든 사용할 수 있습니다. 이는 선행 조건에 따라 계산되고 반환될 것이기 때문입니다. ```jldoctest julia> true && (x = (1, 2, 3)) @@ -319,9 +325,9 @@ julia> false && (x = (1, 2, 3)) false ``` -## [반복 평가: 루프](@id man-loops) +## [반복 계산: 루프](@id man-loops) -반복 평가식에는 두 구문이 있습니다. 바로 `while` 루프와 `for` 루프입니다. 다음은 `while` 루프의 예제입니다. +반복 계산은 `while`과 `for` 구문으로 수행합니다. 다음은 `while` 루프의 예제입니다. ```jldoctest julia> i = 1; @@ -337,9 +343,9 @@ julia> while i <= 5 5 ``` -`while` 루프는 조건식(여기서는 `i <= 5`)을 평가하여, `true`가 아닐 때까지 내내 `while` 루프를 반복하여 실행합니다. `while` 루프에 도착했을 때, 조건식이 `false`이면 루프를 실행하지 않습니다. +`while`은 조건식(여기서는 `i <= 5`)을 계산하여, `false`일 때까지 `while` 루프를 실행합니다. -`for` 루프는 평범한 반복 평가문을 작성하기 쉽게 만들어 줍니다. 위의 `while` 루프와 같이 위아래로 세는 것이 일반적이므로 `for` 루프를 통해 보다 간결하게 표현할 수 있습니다. +`for`은 평범한 특정 횟수를 반복하게 합니다. 위 예제는 `for` 루프로 보다 간결하게 표현할 수 있습니다. ```jldoctest julia> for i = 1:5 @@ -368,9 +374,9 @@ julia> j ERROR: UndefVarError: j not defined ``` -변수 범위에 관한 자세한 설명과 그것이 Julia에서 어떻게 작동하는지는 Scope of Variables 문서를 통해 확인하십시오. - -일반적으로, `for` 루프 구조는 어떤 컨테이너든 반복할 수 있습니다. 이 경우, 코드의 더 명확한 가독성을 위해 `=` 대신 일반적으로 `in`이나 `∈`가 대용(그러나 완전히 동등한) 키워드로 사용됩니다. +변수 범위에 관한 자세한 설명은 [Scope of Variables](@ref variables-and-scoping) 문서를 통해 확인하십시오. +일반적으로, `for` 루프는 컨테이너 형태의 객체에서도 반복할 수 있습니다. +이 경우, 코드의 더 명확한 가독성을 위해 `=` 대신 `in`이나 `∈`가 대용(그러나 완전히 동등한)으로 사용됩니다. ```jldoctest julia> for i in [1,4,0] @@ -388,9 +394,10 @@ bar baz ``` -다양한 유형의 반복 가능한 컨테이너가 매뉴얼 뒷부분(예: Multi-dimensional Arrays 문서 참조)에서 소개되고 논의될 것입니다. +다양한 유형의 반복 가능한 컨테이너가 매뉴얼 뒷부분(예: [Multi-dimensional Arrays](@ref arrays) 문서 참조)에서 소개되고 논의될 것입니다. -테스트 조건이 위조되기 전에 `while` 반복을 종료하거나, 반복용 변수가 끝에 도달하기 전에 `for` 루프를 멈추는 것이 편리할 때가 있습니다. 이는 `break` 키워드로 수행할 수 있습니다. +실행 중간에 `while`이나 `for` 을 멈추는 것이 편리할 때가 있습니다. +이는 `break` 키워드로 수행할 수 있습니다. ```jldoctest julia> i = 1; @@ -421,9 +428,10 @@ julia> for j = 1:1000 5 ``` -`break` 키워드 없이는 `while` 루프는 절대 스스로 종료되지 않을 것이며, `for` 루프는 1000까지 세고 말 것입니다. 이 루프 모두 `break`를 사용하여 빠져나갈 수 있습니다. +위 예제에서는 `break` 키워드 없이는 `while` 루프는 절대 스스로 종료되지 않을 것이며, `for` 루프는 1000까지 세고 말 것입니다. +이 루프 모두 `break`를 사용하여 빠져나갈 수 있습니다. -다른 상황에서는 반복을 중지하고 즉시 다음 단계로 넘어가는 것이 더 유용할 수 있습니다. `continue` 키워드는 다음을 수행합니다. +다른 상황에서는 반복을 중지하고 즉시 다음 단계로 넘어가고 싶을 때 `continue`로 대처할 수 있습니다. ```jldoctest julia> for i = 1:10 @@ -437,7 +445,7 @@ julia> for i = 1:10 9 ``` -이는 조건을 무효화하고 조건을 무효화하고 `println` 호출을 `if` 블록 안에 두어 더 똑같은 동작을 명확하게 나타낼 수 있기 때문에 다소 고안된 예제입니다. 실제 코드에서는 `continue` 뒤에 평가할 코드가 더 많을 것이며, 종종 `continue`가 여러 번 사용될 수도 있습니다. +이는 조건을 무효화하고 `println` 호출을 `if` 블록 안에 두어 더 똑같은 동작을 명확하게 나타낼 수 있기 때문에 다소 고안된 예제입니다. 실제 코드에서는 `continue` 뒤에 계산할 코드가 더 많을 것이며, 종종 `continue`가 여러 번 사용될 수도 있습니다. 다중 중첩 `for` 루프는 하나의 외부 루프로 결합되어, 반복용 변수의 데카르트 곱을 형성합니다. @@ -451,11 +459,9 @@ julia> for i = 1:2, j = 3:4 (2, 4) ``` -With this syntax, iterables may still refer to outer loop variables; e.g. `for i = 1:n, j = 1:i` -is valid. -However a `break` statement inside such a loop exits the entire nest of loops, not just the inner one. -Both variables (`i` and `j`) are set to their current iteration values each time the inner loop runs. -Therefore, assignments to `i` will not be visible to subsequent iterations: +위 문법에서는 범위 객체가 외부 루프 변수의 값을 사용할 수 있습니다(예: `for i = 1:n, j = 1:i`). +그러나 위와 같은 선언에서 `break`는 모든 루프를 탈출하게 됩니다. +`i`와 `j` 변수 둘다 매번 루프가 실행 될 때 값이 지정되므로 실행 중에 `i`값을 바꿔도 그 다음 루프에서 이를 확인 할 수 없습니다: ```jldoctest julia> for i = 1:2, j = 3:4 @@ -468,14 +474,13 @@ julia> for i = 1:2, j = 3:4 (2, 4) ``` -If this example were rewritten to use a `for` keyword for each variable, then the output would -be different: the second and fourth values would contain `0`. +만약 위 예제가 이중 `for` 루프로 구현된다면 `i`값이 중간에 초기화되지 않아 `0`을 출력하는 것을 볼 수 있습니다. ## 예외 처리 예기치 않은 조건이 발생하면 함수가 호출자에게 적절한 값을 반환하지 못할 수 있습니다. 이런 경우에는 예외적인 조건에서 진단 오류 메시지를 출력하는 동안 프로그램을 종료하는 것이 좋을 수도 있지만, 프로그래머가 예외적인 상황을 처리하는 코드를 제공한 경우 해당 코드가 적절한 조치를 취하도록 하는 것이 최선의 방법입니다. -### 기본 제공 '예외' +### 기본 예외 타입 예기치 않은 조건이 일어나면 `Exception`이 발생합니다. 아래에 나열된 기본 제공 `Exception`은 모두 정상적인 제어 흐름을 방해합니다. @@ -540,7 +545,7 @@ Stacktrace: [1] f(::Int64) at ./none:1 ``` -괄호가 없는 `DomainError`는 예외가 아니라 예외 유형임을 기억하십시오. `Exception` 객체를 얻으려면 호출해야 합니다. +괄호가 없는 `DomainError`는 예외가 아니라 예외 타입임을 기억하십시오. `Exception` 객체를 얻으려면 호출해야 합니다. ```jldoctest julia> typeof(DomainError(nothing)) <: Exception @@ -571,7 +576,7 @@ julia> Base.showerror(io::IO, e::MyUndefVarError) = print(io, e.var, " not defin 오류 메시지를 작성할 때 첫 번째 단어를 소문자로 만드는 것이 좋습니다. 예를 들어, `size(A) == size(B) || throw(DimensionMismatch("size of A not equal to size of B"))` - 가 아래보다 선호됩니다. + 가 아래보다 더 좋은 예외 처리입니다 `size(A) == size(B) || throw(DimensionMismatch("Size of A not equal to size of B"))`. diff --git a/src/manual/functions.md b/src/manual/functions.md index e4f2a2f..af71699 100644 --- a/src/manual/functions.md +++ b/src/manual/functions.md @@ -234,7 +234,7 @@ julia> x.a 지명 튜플은 이름이 있다는 것을 제외하면 일반적인 튜플과 유사하며, dot 문법을 통해 값에 접근할 수 있다 (`x.a`). -## 다중 반환값 +## 다중 반환 여러 값을 반환하기 위해 함수는 튜플을 반환한다. 하지만 튜플은 괄호 없이 생성되기도 하고 분리되기도 하므로 명시적으로 튜플을 사용한다는 것을 나타낼 필요가 없다. @@ -298,18 +298,15 @@ not work. ## 가변인자 함수 -It is often convenient to be able to write functions taking an arbitrary number of arguments. -Such functions are traditionally known as "varargs" functions, which is short for "variable number -of arguments". You can define a varargs function by following the last argument with an ellipsis: +경우에 따라 함수에 원하는 만큼 인자를 주는 것이 유용할 때도 있다. +이러한 가변인자 함수를 만들려면 함수 인자 선언의 마지막에 `(인자 이름)...`을 넣으면 된다: ```jldoctest barfunc julia> bar(a,b,x...) = (a,b,x) bar (generic function with 1 method) ``` -The variables `a` and `b` are bound to the first two argument values as usual, and the variable -`x` is bound to an iterable collection of the zero or more values passed to `bar` after its first -two arguments: +위 예제에서 처음 두번째 인자까지는 `a`와 `b`에 할당되고, 변수 `x`에는 나머지 인자들이 튜플로 묶여서 전달된다: ```jldoctest barfunc julia> bar(1,2) @@ -325,14 +322,11 @@ julia> bar(1,2,3,4,5,6) (1, 2, (3, 4, 5, 6)) ``` -In all these cases, `x` is bound to a tuple of the trailing values passed to `bar`. +가변인자의 개수를 제한하는 방법은 [Parametrically-constrained Varargs methods](@ref)에서 확인할 수 있다. -It is possible to constrain the number of values passed as a variable argument; this will be discussed -later in [Parametrically-constrained Varargs methods](@ref). - -On the flip side, it is often handy to "splat" the values contained in an iterable collection -into a function call as individual arguments. To do this, one also uses `...` but in the function -call instead: +`...`을 다르게도 활용할 수 있다. +interable 객체에 저장된 값 하나하나를 전부 함수 인자로 주고 싶을 때, 해당 변수에 `...`을 붙여주면 순서대로 인자를 넣어준다. +아래의 경우 튜플이 알아서 쪼개져 각 인자에 순서대로 들어간다: ```jldoctest barfunc julia> x = (3, 4) @@ -340,12 +334,7 @@ julia> x = (3, 4) julia> bar(1,2,x...) (1, 2, (3, 4)) -``` - -In this case a tuple of values is spliced into a varargs call precisely where the variable number -of arguments go. This need not be the case, however: -```jldoctest barfunc julia> x = (2, 3, 4) (2, 3, 4) @@ -359,7 +348,7 @@ julia> bar(x...) (1, 2, (3, 4)) ``` -Furthermore, the iterable object splatted into a function call need not be a tuple: +물론 interable 객체이기만 하면 위 방법을 사용할 수 있다: ```jldoctest barfunc julia> x = [3,4] @@ -381,8 +370,7 @@ julia> bar(x...) (1, 2, (3, 4)) ``` -Also, the function that arguments are splatted into need not be a varargs function (although it -often is): +이 방법은 가변인자 함수가 아니어도 사용할 수 있다: ```jldoctest julia> baz(a,b) = a + b; @@ -407,16 +395,12 @@ Closest candidates are: baz(::Any, ::Any) at none:1 ``` -As you can see, if the wrong number of elements are in the splatted container, then the function -call will fail, just as it would if too many arguments were given explicitly. +보다시피 인자의 개수가 잘못되면 함수 호출은 실패하고 위와 같은 에러를 보게 될 것이다. -## Optional Arguments +## 기본값이 제공된 인자(optional arguments) -In many cases, function arguments have sensible default values and therefore might not need to -be passed explicitly in every call. For example, the function [`Date(y, [m, d])`](@ref) -from `Dates` module constructs a `Date` type for a given year `y`, month `m` and day `d`. -However, `m` and `d` arguments are optional and their default value is `1`. -This behavior can be expressed concisely as: +기본값이 지정된 함수는 해당 인자를 주지 않아도 잘 작동한다. +예를 들어`Dates`의 `Date`타입에 지정된 [`Date(y, [m, d])`](@ref) 함수는 `y`만 지정하면 `m`과 `d`는 1로 자동 지정된다: ```julia function Date(y::Int64, m::Int64=1, d::Int64=1) @@ -426,11 +410,8 @@ function Date(y::Int64, m::Int64=1, d::Int64=1) end ``` -Observe, that this definition calls another method of `Date` function that takes one argument -of `UTInstant{Day}` type. - -With this definition, the function can be called with either one, two or three arguments, and -`1` is automatically passed when any of the arguments is not specified: +이 예제에 부연설명을 하면, `Date`함수는 `UTInstant{Day}`라는 인자를 받는 다른 매서드 함수 `Date`를 호출한다. +위 함수의 정의에 따라 이 함수에는 인자를 하나, 둘, 혹은 세개를 줄 수 있으며, 인자가 직접 주어지지 않을 경우 `1`이 자동으로 부여됨을 알 수 있다: ```jldoctest julia> using Dates @@ -445,9 +426,8 @@ julia> Date(2000) 2000-01-01 ``` -Optional arguments are actually just a convenient syntax for writing multiple method definitions -with different numbers of arguments (see [Note on Optional and keyword Arguments](@ref)). -This can be checked for our `Date` function example by calling `methods` function. +기본값 제공은 다중인자 함수의 사용 편의성을 위한 것이다([Note on Optional and keyword Arguments](@ref)를 보자). +위 예제에서 메서드 함수를 호출한 것을 보면 알 수 있다. ## Keyword Arguments From 75a48c1b79d427d917ac88bb9571224ec506d959 Mon Sep 17 00:00:00 2001 From: Dohyeon Lee Date: Sat, 3 Oct 2020 00:59:05 +0900 Subject: [PATCH 135/153] =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=EB=A7=81?= =?UTF-8?q?=ED=81=AC=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- make.jl | 6 ++-- src/manual/complex-and-rational-numbers.md | 2 +- src/manual/constructors.md | 2 +- src/manual/control-flow.md | 6 ++-- src/manual/conversion-and-promotion.md | 4 +-- src/manual/functions.md | 36 +++++++++++++++---- .../integers-and-floating-point-numbers.md | 6 ++-- src/manual/mathematical-operations.md | 2 +- src/manual/metaprogramming.md | 2 +- src/manual/methods.md | 2 +- src/manual/noteworthy-differences.md | 2 +- src/manual/parallel-computing.md | 2 +- src/manual/types.md | 14 ++++---- 13 files changed, 55 insertions(+), 31 deletions(-) diff --git a/make.jl b/make.jl index 51c1135..a0d9b3b 100644 --- a/make.jl +++ b/make.jl @@ -53,10 +53,10 @@ const t_html_canonical = "https://juliakorea.github.io/ko/latest/" # Korean text in PAGES const t_Home = "홈" const t_Manual = "매뉴얼" -const t_Julia_Documentation = "Julia Documentation" +const t_Julia_Documentation = "줄리아 문서" const t_Base = "Base" -const t_Standard_Library = "Standard Library" -const t_Developer_Documentation = "Developer Documentation" +const t_Standard_Library = "표준 라이브러리" +const t_Developer_Documentation = "개발자 문서" Manual = [ "manual/getting-started.md", diff --git a/src/manual/complex-and-rational-numbers.md b/src/manual/complex-and-rational-numbers.md index 372ce4a..26714ab 100644 --- a/src/manual/complex-and-rational-numbers.md +++ b/src/manual/complex-and-rational-numbers.md @@ -156,7 +156,7 @@ julia> a = 1; b = 2; complex(a, b) 1 + 2im ``` -[특별한 부동 소수점 값들](@ref)에서 소개한 [`Inf`](@ref)과 [`NaN`](@ref)을 복소수에서도 사용할 수 있다: +[특별한 부동 소수점 값들](@ref Special-floating-point-values)에서 소개한 [`Inf`](@ref)과 [`NaN`](@ref)을 복소수에서도 사용할 수 있다: ```jldoctest julia> 1 + Inf*im diff --git a/src/manual/constructors.md b/src/manual/constructors.md index 33f6d8f..ef7f05e 100644 --- a/src/manual/constructors.md +++ b/src/manual/constructors.md @@ -484,7 +484,7 @@ Following the outer constructor definitions, we defined a number of methods for operator, which provides a syntax for writing rationals (e.g. `1 ⊘ 2`). Julia's `Rational` type uses the [`//`](@ref) operator for this purpose. Before these definitions, `⊘` is a completely undefined operator with only syntax and no meaning. Afterwards, it behaves just -as described in [Rational Numbers](@ref) -- its entire behavior is defined in these few lines. +as described in [유리수](@ref) -- its entire behavior is defined in these few lines. The first and most basic definition just makes `a ⊘ b` construct a `OurRational` by applying the `OurRational` constructor to `a` and `b` when they are integers. When one of the operands of `⊘` is already a rational number, we construct a new rational for the resulting ratio slightly differently; diff --git a/src/manual/control-flow.md b/src/manual/control-flow.md index 43a0ca7..08d1c8a 100644 --- a/src/manual/control-flow.md +++ b/src/manual/control-flow.md @@ -294,7 +294,7 @@ Stacktrace: [3] top-level scope ``` -단락 계산이 없는 논리 연산은 [산술 연산과 기본 함수](@ref mathematical-operations)에서 소개된 비트 논리 연산자 `&`, `|` 로 할 수 있습니다. 이들은 이항연산자 구문을 지원하지만, 항상 인수를 계산하는 일반적인 함수라고 할 수 있습니다. +단락 계산이 없는 논리 연산은 [산술 연산과 기본 함수](@ref)에서 소개된 비트 논리 연산자 `&`, `|` 로 할 수 있습니다. 이들은 이항연산자 구문을 지원하지만, 항상 인수를 계산하는 일반적인 함수라고 할 수 있습니다. ```jldoctest tandf julia> f(1) & t(2) @@ -374,7 +374,7 @@ julia> j ERROR: UndefVarError: j not defined ``` -변수 범위에 관한 자세한 설명은 [Scope of Variables](@ref variables-and-scoping) 문서를 통해 확인하십시오. +변수 범위에 관한 자세한 설명은 [Scope of Variables](@ref) 문서를 통해 확인하십시오. 일반적으로, `for` 루프는 컨테이너 형태의 객체에서도 반복할 수 있습니다. 이 경우, 코드의 더 명확한 가독성을 위해 `=` 대신 `in`이나 `∈`가 대용(그러나 완전히 동등한)으로 사용됩니다. @@ -394,7 +394,7 @@ bar baz ``` -다양한 유형의 반복 가능한 컨테이너가 매뉴얼 뒷부분(예: [Multi-dimensional Arrays](@ref arrays) 문서 참조)에서 소개되고 논의될 것입니다. +다양한 유형의 반복 가능한 컨테이너가 매뉴얼 뒷부분(예: [다차원 배열](@ref man-multi-dim-arrays) 문서 참조)에서 소개되고 논의될 것입니다. 실행 중간에 `while`이나 `for` 을 멈추는 것이 편리할 때가 있습니다. 이는 `break` 키워드로 수행할 수 있습니다. diff --git a/src/manual/conversion-and-promotion.md b/src/manual/conversion-and-promotion.md index 8a9c72b..324d028 100644 --- a/src/manual/conversion-and-promotion.md +++ b/src/manual/conversion-and-promotion.md @@ -1,8 +1,8 @@ # [Conversion and Promotion](@id conversion-and-promotion) Julia has a system for promoting arguments of mathematical operators to a common type, which has -been mentioned in various other sections, including [Integers and Floating-Point Numbers](@ref), -[Mathematical Operations and Elementary Functions](@ref), [Types](@ref man-types), and [Methods](@ref). +been mentioned in various other sections, including [정수와 부동 소수점 수](@ref Integers-and-Floating-Point-Numbers), +[산술 연산과 기본 함수](@ref), [Types](@ref man-types), and [Methods](@ref). In this section, we explain how this promotion system works, as well as how to extend it to new types and apply it to functions besides built-in mathematical operators. Traditionally, programming languages fall into two camps with respect to promotion of arithmetic arguments: diff --git a/src/manual/functions.md b/src/manual/functions.md index af71699..79e10e9 100644 --- a/src/manual/functions.md +++ b/src/manual/functions.md @@ -46,7 +46,7 @@ julia> ∑(2, 3) `Array`와 같은 mutable 객체가 함수 안에서 변하면, 함수 밖에서도 그 변화를 볼 수 있다. 이런 방식은 Scheme, Python, Ruby, Perl 그리고 대부분의 Lisp와 같은 동적언어가 채택한 방식이다. -## 반환값 +## return 키워드 함수가 반환하는 값은 암묵적으로 가장 마지막으로 계산된 값이다. 이전의 예제 함수 `f`에서는 `x+y`의 값이 반환될 것이다. 다른 프로그래밍 언어처럼 `return`과 리턴값이 명시적으로 선언될 경우, 함수는 즉시 종료되고 `return`앞에 있는 식을 계산하고 반환할 것이다: @@ -98,6 +98,8 @@ julia> hypot(3, 4) ``` 위 함수는 경우에 따라 세가지 방법으로 값을 반환한다. 마지막에 `return`은 생략해도 된다. +## 반환 타입 + 반환값의 타입은 `::`로 명시할 수 있으며, 이경우 반환값이 자동 형변환된다. ```jldoctest @@ -109,13 +111,35 @@ julia> typeof(g(1, 2)) Int8 ``` -위 함수는 `x`와 `y`의 타입에 상관없이 반환값은 `Int8`로 정해져있다. 타입에 대해 자세히 알고 싶다면 -[타입 선언](@ref)을 참고하자. +위 함수는 `x`와 `y`의 타입에 상관없이 반환값은 `Int8`로 정해져있다. 타입에 대해 자세히 알고 싶다면 [Type Declarations](@ref)을 참고하자. + +## 반환값이 없는 함수 + +함수가 값을 반환할 필요가 없을 경우, Julia 언어 내에서는 관습적으로 [nothing](@ref)을 반환한다: + +```jldoctest +function printx(x) + println("x = $x") + return nothing +end +``` + +This is a *convention* in the sense that `nothing` is not a Julia keyword +but a only singleton object of type `Nothing`. +Also, you may notice that the `printx` function example above is contrived, +because `println` already returns `nothing`, so that the `return` line is redundant. + +There are two possible shortened forms for the `return nothing` expression. +On the one hand, the `return` keyword implicitly returns `nothing`, so it can be used alone. +On the other hand, since functions implicitly return their last expression evaluated, +`nothing` can be used alone when it's the last expression. +The preference for the expression `return nothing` as opposed to `return` or `nothing` +alone is a matter of coding style. ## 연산자는 함수다 Julia에서 연산자는 특별한 문법을 가진 함수일 뿐입니다(`&&`와 `||`는 예외다. -이들은 [Short-Circuit Evaluation](@ref)에서 나왔다시피 연산자가 피연산자보다 먼저 계산되기 때문이다). +이들은 [단락 계산](@ref Short-Circuit-Evaluation)에서 나왔다시피 연산자가 피연산자보다 먼저 계산되기 때문이다). 따라서 연산자는 일반 함수처럼 소괄호를 이용해 인자를 전달할 수 있다: ```jldoctest @@ -322,7 +346,7 @@ julia> bar(1,2,3,4,5,6) (1, 2, (3, 4, 5, 6)) ``` -가변인자의 개수를 제한하는 방법은 [Parametrically-constrained Varargs methods](@ref)에서 확인할 수 있다. +가변인자의 개수를 제한하는 방법은 [매개변수적으로 제한된 Varargs 메서드](@ref)에서 확인할 수 있다. `...`을 다르게도 활용할 수 있다. interable 객체에 저장된 값 하나하나를 전부 함수 인자로 주고 싶을 때, 해당 변수에 `...`을 붙여주면 순서대로 인자를 넣어준다. @@ -583,7 +607,7 @@ end Here, [`open`](@ref) first opens the file for writing and then passes the resulting output stream to the anonymous function you defined in the `do ... end` block. After your function exits, [`open`](@ref) will make sure that the stream is properly closed, regardless of whether your function exited -normally or threw an exception. (The `try/finally` construct will be described in [Control Flow](@ref).) +normally or threw an exception. (The `try/finally` construct will be described in [제어 흐름](@ref).) With the `do` block syntax, it helps to check the documentation or implementation to know how the arguments of the user function are initialized. diff --git a/src/manual/integers-and-floating-point-numbers.md b/src/manual/integers-and-floating-point-numbers.md index f4a681a..1018639 100644 --- a/src/manual/integers-and-floating-point-numbers.md +++ b/src/manual/integers-and-floating-point-numbers.md @@ -40,7 +40,7 @@ | [`Float32`](@ref) | [single](https://en.wikipedia.org/wiki/Single_precision_floating-point_format) | 32 | | [`Float64`](@ref) | [double](https://en.wikipedia.org/wiki/Double_precision_floating-point_format) | 64 | -추가적으로 [Complex and Rational Numbers](@ref)는 위에서 언급한 타입에 기초하여 만들어졌다. 모든 기본 수치 타입들은 유연하고, 쉽게 확장이 가능한 [type promotion system](@ref conversion-and-promotion) 덕분에 자유롭게 상호운용이 가능하다. +추가적으로 [복소수와 유리수](@ref)는 위에서 언급한 타입에 기초하여 만들어졌다. 모든 기본 수치 타입들은 유연하고, 쉽게 확장이 가능한 [type promotion system](@ref conversion-and-promotion) 덕분에 자유롭게 상호운용이 가능하다. ## 정수 @@ -335,7 +335,7 @@ julia> bitstring(-0.0) | `-Inf16` | `-Inf32` | `-Inf` | negative infinity | 모든 유한한 부동 소수점 실수보다 작은 값 | | `NaN16` | `NaN32` | `NaN` | not a number | 어떤 부동 소수점 실수와도 같지 않은 값 | -이와 같은 유한하지 않은 부동 소수점 값들이 서로와 다른 실수에 대해서 순서를 매길 때에는 [Numeric Comparisons](@ref)를 참고하길 바란다. [IEEE 754 standard](https://en.wikipedia.org/wiki/IEEE_754-2008)에 따르면, 위에서의 부동 소수점 실수들은 어떤 산술 연산에 의한 결과임을 알 수 있다: +이와 같은 유한하지 않은 부동 소수점 값들이 서로와 다른 실수에 대해서 순서를 매길 때에는 [비교 연산](@ref)을 참고하길 바란다. [IEEE 754 standard](https://en.wikipedia.org/wiki/IEEE_754-2008)에 따르면, 위에서의 부동 소수점 실수들은 어떤 산술 연산에 의한 결과임을 알 수 있다: ```jldoctest julia> 1/Inf @@ -616,7 +616,7 @@ example, `1.5F22` is equal to `1.5 * F22`. | [`zero(x)`](@ref) | `x`타입이나 변수 `x`의 타입의 리터럴 0 | | [`one(x)`](@ref) | `x`타입이나 변수 `x`의 타입의 리터럴 1 | -위 함수들은 [Numeric Comparisons](@ref)에서 불필요한 [type conversion](@ref conversion-and-promotion)에 의한 성능저하를 줄일 때 유용하다. +위 함수들은 [비교 연산](@ref)에서 불필요한 [type conversion](@ref conversion-and-promotion)에 의한 성능저하를 줄일 때 유용하다. Examples: diff --git a/src/manual/mathematical-operations.md b/src/manual/mathematical-operations.md index d3b0957..0165699 100644 --- a/src/manual/mathematical-operations.md +++ b/src/manual/mathematical-operations.md @@ -326,7 +326,7 @@ Julia는 수치 계산을 위한 함수와 연산자를 전폭적으로 지원 ## 연산자 우선순위와 결합성 -아래 표는 높은 우선 순위부터 낮은 우선순위별로 연산자를 나열하고, [연산자 결합성](@https://en.wikipedia.org/wiki/Operator_associativity)을 확인할 수 있다: +아래 표는 높은 우선 순위부터 낮은 우선순위별로 연산자를 나열하고, [연산자 결합성](https://en.wikipedia.org/wiki/Operator_associativity)을 확인할 수 있다: | 분류 | 연산자 | 결합성 | |:-------------- |:------------------------------------------------------------------------------------------------- |:-------------------------- | diff --git a/src/manual/metaprogramming.md b/src/manual/metaprogramming.md index f2a63fe..a3e3ddc 100644 --- a/src/manual/metaprogramming.md +++ b/src/manual/metaprogramming.md @@ -684,7 +684,7 @@ the error message. The actual definition of `@assert` in Julia Base is more complicated. It allows the user to optionally specify their own error message, instead of just printing the failed expression. -Just like in functions with a variable number of arguments ([Varargs Functions](@ref)), this is specified with an ellipses +Just like in functions with a variable number of arguments ([가변인자 함수](@ref)), this is specified with an ellipses following the last argument: ```jldoctest assert2 diff --git a/src/manual/methods.md b/src/manual/methods.md index 35e20ce..b8905be 100644 --- a/src/manual/methods.md +++ b/src/manual/methods.md @@ -668,7 +668,7 @@ matmul(a, b) = matmul(promote(a, b)...) ## [매개변수적으로 제한된 Varargs 메서드](@id Parametrically-constrained-Varargs-methods) -함수매개변수는 "varargs"함수 ([Varargs Functions](@ref))에 제공 될 수있는 인수의 수를 제한하는 데 사용될 수도 있습니다. +함수매개변수는 [다중인자 함수](@ref)에 제공 되는 인자의 수를 제한하는 데 사용될 수도 있습니다. `Vararg {T, N}` 표기법은 그러한 제약을 나타내기 위해 사용됩니다. 예: ```jldoctest diff --git a/src/manual/noteworthy-differences.md b/src/manual/noteworthy-differences.md index 5bd810c..300cb07 100644 --- a/src/manual/noteworthy-differences.md +++ b/src/manual/noteworthy-differences.md @@ -41,7 +41,7 @@ may trip up Julia users accustomed to MATLAB: also seen in functions such as [`range`](@ref), or with iterators such as `enumerate`, and `zip`. The special objects can mostly be used as if they were normal arrays. * Functions in Julia return values from their last expression or the `return` keyword instead of - listing the names of variables to return in the function definition (see [The return Keyword](@ref) + listing the names of variables to return in the function definition (see [return 키워드](@ref) for details). * A Julia script may contain any number of functions, and all definitions will be externally visible when the file is loaded. Function definitions can be loaded from files outside the current working diff --git a/src/manual/parallel-computing.md b/src/manual/parallel-computing.md index a796b7d..3c1c343 100644 --- a/src/manual/parallel-computing.md +++ b/src/manual/parallel-computing.md @@ -44,7 +44,7 @@ work to processes only when they finish their current tasks. ## Channels -The section on [`Task`](@ref)s in [Control Flow](@ref) discussed the execution of multiple functions in +The section on [`Task`](@ref)s in [제어 흐름](@ref) discussed the execution of multiple functions in a co-operative manner. [`Channel`](@ref)s can be quite useful to pass data between running tasks, particularly those involving I/O operations. diff --git a/src/manual/types.md b/src/manual/types.md index 5e2b209..7fbaf3d 100644 --- a/src/manual/types.md +++ b/src/manual/types.md @@ -13,7 +13,7 @@ Julia's type system is dynamic, but gains some of the advantages of static type it possible to indicate that certain values are of specific types. This can be of great assistance in generating efficient code, but even more significantly, it allows method dispatch on the types of function arguments to be deeply integrated with the language. Method dispatch is explored in -detail in [Methods](@ref), but is rooted in the type system presented here. +detail in [메서드](@ref Methods), but is rooted in the type system presented here. The default behavior in Julia when types are omitted is to allow values to be of any type. Thus, one can write many useful Julia functions without ever explicitly using types. When additional @@ -210,7 +210,7 @@ end The first thing to note is that the above argument declarations are equivalent to `x::Any` and `y::Any`. When this function is invoked, say as `myplus(2,5)`, the dispatcher chooses the most -specific method named `myplus` that matches the given arguments. (See [Methods](@ref) for more +specific method named `myplus` that matches the given arguments. (See [메서드](@ref Methods) for more information on multiple dispatch.) Assuming no method more specific than the above is found, Julia next internally defines and compiles @@ -303,7 +303,7 @@ such as integers and floating-point values, are not objects, while instances of types are true objects with associated methods. In Julia, all values are objects, but functions are not bundled with the objects they operate on. This is necessary since Julia chooses which method of a function to use by multiple dispatch, meaning that the types of *all* of a function's -arguments are considered when selecting a method, rather than just the first one (see [Methods](@ref) +arguments are considered when selecting a method, rather than just the first one (see [메서드](@ref Methods) for more information on methods and dispatch). Thus, it would be inappropriate for functions to "belong" to only their first argument. Organizing methods into function objects rather than having named bags of methods "inside" each object ends up being a highly beneficial aspect of the language @@ -398,7 +398,7 @@ The [`===`](@ref) function confirms that the "two" constructed instances of `NoF and the same. Singleton types are described in further detail [below](@ref man-singleton-types). There is much more to say about how instances of composite types are created, but that discussion -depends on both [Parametric Types](@ref) and on [Methods](@ref), and is sufficiently important +depends on both [Parametric Types](@ref) and on [메서드](@ref Methods), and is sufficiently important to be addressed in its own section: [Constructors](@ref man-constructors). ## Mutable Composite Types @@ -634,7 +634,7 @@ end (Equivalently, one could define `function norm(p::Point{T} where T<:Real)` or `function norm(p::Point{T}) where T<:Real`; see [UnionAll Types](@ref).) -More examples will be discussed later in [Methods](@ref). +More examples will be discussed later in [메서드](@ref Methods). How does one construct a `Point` object? It is possible to define custom constructors for composite types, which will be discussed in detail in [Constructors](@ref man-constructors), but in the absence of any special @@ -789,7 +789,7 @@ Now both `Point{Float64}` and `DiagPoint{Float64}` are implementations of the `P abstraction, and similarly for every other possible choice of type `T`. This allows programming to a common interface shared by all `Pointy` objects, implemented for both `Point` and `DiagPoint`. This cannot be fully demonstrated, however, until we have introduced methods and dispatch in the -next section, [Methods](@ref). +next section, [메서드](@ref Methods). There are situations where it may not make sense for type parameters to range freely over all possible types. In such situations, one can constrain the range of `T` like so: @@ -908,7 +908,7 @@ false ``` Notice that `Vararg{T}` corresponds to zero or more elements of type `T`. Vararg tuple types are -used to represent the arguments accepted by varargs methods (see [Varargs Functions](@ref)). +used to represent the arguments accepted by varargs methods (see [가변인자 함수](@ref)). The type `Vararg{T,N}` corresponds to exactly `N` elements of type `T`. `NTuple{N,T}` is a convenient alias for `Tuple{Vararg{T,N}}`, i.e. a tuple type containing exactly `N` elements of type `T`. From 27ed697a212b4eabd4f087ba52e5de33aee159dd Mon Sep 17 00:00:00 2001 From: Dohyeon Lee Date: Sat, 3 Oct 2020 10:29:28 +0900 Subject: [PATCH 136/153] =?UTF-8?q?html=EB=AC=B8=EC=84=9C:=20=EC=84=B9?= =?UTF-8?q?=EC=85=98=20=EC=A0=91=EA=B8=B0=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- make.jl | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d170149..6547d99 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ ### 줄리아 문서 번역하기 - - [번역하기](https://github.com/juliakorea/translate-doc/wiki/%EB%B2%88%EC%97%AD%ED%95%98%EA%B8%B0) + - Julia 문서는 마크다운으로 번역됩니다. 모든 번역해야 할 문서는 /src 디렉토리에 있으며 자세한 사항은 [번역하기](https://github.com/juliakorea/translate-doc/wiki/%EB%B2%88%EC%97%AD%ED%95%98%EA%B8%B0)를 참고해주시기 바랍니다. ### 최근 번역 빌드한 것 보기 (HTML) diff --git a/make.jl b/make.jl index a0d9b3b..95e3f3b 100644 --- a/make.jl +++ b/make.jl @@ -197,12 +197,13 @@ else canonical = t_html_canonical, analytics = t_analytics, assets = ["assets/julia-manual.css", ], + collapselevel = 1, ) end makedocs( build = joinpath(pwd(), "local" in ARGS ? "_build_local" : "_build/html/ko/latest"), - modules = [Base, Core, [Base.root_module(Base, stdlib.stdlib) for stdlib in STDLIB_DOCS]...], + modules = [Main, Base, Core, [Base.root_module(Base, stdlib.stdlib) for stdlib in STDLIB_DOCS]...], clean = false, # true doctest = ("doctest=fix" in ARGS) ? (:fix) : ("doctest=true" in ARGS) ? true : false, linkcheck = "linkcheck=true" in ARGS, From fc606aa08e0fcf53788daae5aaee559b48dd3802 Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Tue, 27 Oct 2020 07:20:16 +0900 Subject: [PATCH 137/153] =?UTF-8?q?NEWS=20=EC=95=88=EB=B3=B4=EC=9D=B4?= =?UTF-8?q?=EA=B2=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/index.md | 1 - 1 file changed, 1 deletion(-) diff --git a/src/index.md b/src/index.md index 30516f3..698557b 100644 --- a/src/index.md +++ b/src/index.md @@ -19,7 +19,6 @@ import Markdown Markdown.parse(String(take!(io))) ``` -지난 릴리즈에서 부터 바뀐 점은 [릴리즈 노트](NEWS.md)에 있습니다. ` ` From 52b7f82dab0bac926fa5ce5fe3151844ff89260e Mon Sep 17 00:00:00 2001 From: Aki <71239005+AkiaCode@users.noreply.github.com> Date: Sat, 23 Jan 2021 12:38:11 +0900 Subject: [PATCH 138/153] Update index.md --- src/index.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/index.md b/src/index.md index 698557b..320b4e6 100644 --- a/src/index.md +++ b/src/index.md @@ -19,9 +19,6 @@ import Markdown Markdown.parse(String(take!(io))) ``` - -` ` - !!! note "번역 안내" 한글 문서 번역은 깃헙 [https://github.com/juliakorea/translate-doc](https://github.com/juliakorea/translate-doc) 에서 누구나 참여하실 수 있습니다. 많은 참여 부탁드립니다. @@ -40,7 +37,7 @@ Markdown.parse(""" """) ``` -### [소개글](@id man-introduction) +### [소개 글](@id man-introduction) 과학 분야 컴퓨팅은 빠른 성능을 요구함에도, 정작 대부분의 연구자들은 속도가 느린 동적인 언어로 일을 처리한다. 동적 언어를 즐겨쓰는 여러 이유로 보아 이러한 추세는 쉽게 사그러들지는 않아 보인다. From a27e859956db96495cd7b42b7cb96baa00a3769f Mon Sep 17 00:00:00 2001 From: Yeongjae Jang <54150647+Liberatedwinner@users.noreply.github.com> Date: Mon, 15 Feb 2021 12:16:23 +0900 Subject: [PATCH 139/153] Update index.md --- src/index.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/index.md b/src/index.md index 320b4e6..78a47ca 100644 --- a/src/index.md +++ b/src/index.md @@ -42,7 +42,7 @@ Markdown.parse(""" 과학 분야 컴퓨팅은 빠른 성능을 요구함에도, 정작 대부분의 연구자들은 속도가 느린 동적인 언어로 일을 처리한다. 동적 언어를 즐겨쓰는 여러 이유로 보아 이러한 추세는 쉽게 사그러들지는 않아 보인다. 다행히 언어 디자인과 컴파일러 기법의 발달로 성능 문제가 해결되면서 동적 언어의 성능 하락 문제를 극복하고 프로토타이핑과 계산 집중형 애플리케이션의 구축을 하나의 환경에서 발휘할 수 있게 되었다. -Julia는 이런 장점을 최대화한 언어이다. Julia는 (1) 과학과 수학 분야의 컴퓨팅에 적합한 동적 언어이면서 (2) 정적 타입 언어에 겨줄만한 성능을 지닌다. +줄리아 (Julia)는 이런 장점을 최대화한 언어이다. 줄리아는 (1) 과학과 수학 분야의 컴퓨팅에 적합한 동적 언어이면서 (2) 정적 타입 언어에 견줄만한 성능을 지닌다. 줄리아 컴파일러는 파이썬, R과 같은 언어의 해석 방식과 다르다. 줄리아가 뽑아내는 성능이 아마도 처음에는 의아할 것이다. 그럼에도 작성한 코드가 느리다면 [성능 팁](@ref man-performance-tips)을 읽어보길 권한다. @@ -77,7 +77,7 @@ Julia는 이런 장점을 최대화한 언어이다. Julia는 (1) 과학과 수 런타임 타입 추론(타입 지정을 점진적으로 늘려가며)을 이유로, 또 이 프로젝트를 시작할 때 무엇보다도 성능을 강조하였기에 줄리아의 계산 효율은 다른 동적 언어들에 비해 우월하며 심지어 정적으로 컴파일하는 경쟁 언어들마저 능가한다. -거대 규모의 수치 해석 문제에 있어 속도는 매번 그리고 앞으로도, 아마 항상 결정적 요소일 것이다: 처리되는 데이터의 양이 지난 수십년간 무어의 법칙을 따르고 있지 않은가. +거대 규모의 수치 해석 문제에 있어 속도는 매번 그리고 앞으로도, 아마 항상 결정적 요소일 것이다: 처리되는 데이터의 양이 지난 수십 년간 무어의 법칙을 따르고 있지 않은가. 사용하기 편하면서도 강력하고 효율적인 언어를 줄리아는 목표하고 있다. 다른 시스템과 견주어 줄리아를 씀으로 좋은 점은 다음과 같다: @@ -91,4 +91,4 @@ Julia는 이런 장점을 최대화한 언어이다. Julia는 (1) 과학과 수 * 효율적인 [유니코드](https://ko.wikipedia.org/wiki/%EC%9C%A0%EB%8B%88%EC%BD%94%EB%93%9C) 와 [UTF-8](https://ko.wikipedia.org/wiki/UTF-8) 지원 * C 함수 직접 호출(별도의 래퍼나 특정한 API가 필요하지 않음) * 다른 프로세스를 관리하는 쉘과 비슷한 강력한 기능 - * 리스프와 비슷한 매크로, 메타프로그래밍을 위한 장치들 + * 리스프 (Lisp)와 비슷한 매크로, 메타프로그래밍을 위한 장치들 From 05a795fe43210bca7d22e2575a14967c976fb577 Mon Sep 17 00:00:00 2001 From: Yeongjae Jang <54150647+Liberatedwinner@users.noreply.github.com> Date: Mon, 15 Feb 2021 03:32:07 +0000 Subject: [PATCH 140/153] Create complex-and-rational-numbers.md --- src/manual/complex-and-rational-numbers.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/manual/complex-and-rational-numbers.md b/src/manual/complex-and-rational-numbers.md index 26714ab..942273a 100644 --- a/src/manual/complex-and-rational-numbers.md +++ b/src/manual/complex-and-rational-numbers.md @@ -5,8 +5,8 @@ Julia에서는 복소수와 유리수를 표현할 수 있고 [산술 연산과 ## 복소수 -전역 상수 [`im`](@ref)는 -1의 루트값으로, 복소수의 허수부 *i*옆에 붙어있다. -(수학자는 `i`로 쓰고 공학자는 `j` 쓰지만, 이 이름은 인덱싱할 때 자주 사용하므로 전역 상수의 이름으로 채택되지 않았다.) +전역 상수 [`im`](@ref)는 -1의 제곱근으로, 복소수 *i*에 해당한다. +(수학자는 이를 `i`로 쓰고 공학자는 `j`로 쓰지만, 이 문자들은 인덱싱할 때 자주 사용하므로 전역 상수의 이름으로 채택되지 않았다.) Julia는 [계수와 변수 사이에 곱셈 기호를 생략하는 것](@ref man-numeric-literal-coefficients)을 허용하기 때문에 수학적 표기법을 그대로 사용할 수 있다: ```jldoctest @@ -176,7 +176,7 @@ julia> 2//3 2//3 ``` -분모와 분자가 공통 분모를 가지고 있다면, 이들은 자동으로 상쇄된다: +분모와 분자가 공통 인수를 가지고 있다면, 이들은 자동으로 약분된다: ```jldoctest julia> 6//9 @@ -192,7 +192,7 @@ julia> -4//-12 1//3 ``` -분자가 분모가 서로인 상태는 유일하며, 두 유리수가 같은지 보려면 각 분자와 분모가 같은지 보면 된다. +분자가 분모가 서로소인 상태는 유일하며, 두 유리수가 같은지 보려면 각 분자와 분모가 같은지 보면 된다. 유리수의 분자와 분모는 [`numerator`](@ref)와 [`denominator`](@ref)함수로 확인할 수 있다: ```jldoctest @@ -238,7 +238,7 @@ julia> float(3//4) 0.75 ``` -유리수를 실수와 비교할 때는 유리수가 실수로 형 변환을 하고 비교하도록 설계되었다(단, `a == 0`이고 `b == 0`인 경우 제외): +유리수를 실수와 비교할 때는 유리수를 실수로 형 변환을 하고 비교하도록 설계되었다(단, `a == 0`이고 `b == 0`인 경우 제외): ```jldoctest julia> a = 1; b = 2; From 3fa01de983581e52c0d6722500b2986dcbea34fc Mon Sep 17 00:00:00 2001 From: Yeongjae Jang <54150647+Liberatedwinner@users.noreply.github.com> Date: Mon, 15 Feb 2021 13:08:48 +0900 Subject: [PATCH 141/153] Update variables.md --- src/manual/variables.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/manual/variables.md b/src/manual/variables.md index a7f576e..ddc546e 100644 --- a/src/manual/variables.md +++ b/src/manual/variables.md @@ -38,8 +38,8 @@ julia> Z = "My string" julia> customary_phrase = "Hello world!" "Hello world!" -julia> UniversalDeclarationOfHumanRightsStart = "人人生而自由,在尊严和权利上一>律平等。" -"人人生而自由,在尊严和权利上一律平等。" +julia> UniversalDeclarationOfHumanRightsStart = "모든 인간은 태어날 때부터 자유로우며 그 존엄과 권리에 있어 동등하다." +"모든 인간은 태어날 때부터 자유로우며 그 존엄과 권리에 있어 동등하다." ``` Julia는 유니코드 기반의 변수를 허용한다: @@ -113,7 +113,7 @@ ERROR: syntax: unexpected "=" 일부 유니코드 문자는 동등하게 간주된다. 유니코드가 달라도 문자가 같으면 동일하게 취급된다(Julia는 NFC 표준을 사용함). -예를 들어 유니 코드 문자`ɛ` (U + 025B : 라틴어 소문자 열린e)와 `μ`(U + 00B5 : 마이크로 부호)는 이와 형태가 같은 그리스 문자와 동일하게 취급된다. +예를 들어 유니코드 문자 `ɛ` (U + 025B : 라틴어 소문자 열린 e)와 `μ`(U + 00B5 : 마이크로 부호)는 이와 형태가 같은 그리스 문자와 동일하게 취급된다. ## 문체 규칙 @@ -123,5 +123,5 @@ Julia는 변수 명명법이 자유롭지만 다음 규칙을 준수하는 것 * 변수는 소문자를 사용한다. * `'_'`와 같은 문자는 다른 사람을 배려해 되도록 사용하지 않는다. * 타입과 모듈 이름은 대문자로 시작하고 단어 분리는 밑줄(`_`)대신 쌍봉낙타 표기법(UpperCamelCase: 모든 단어의 첫글자를 대문자로 표기)을 지향한다. - * `함수`와`매크로`의 이름에는 밑줄을 넣지 않는다. + * `함수`와 `매크로`의 이름에는 밑줄을 넣지 않는다. * in-place 함수의 이름은 `!`로 끝난다. From ba2e571bc37ed7f55c3ce2d486fd55550c9d1e82 Mon Sep 17 00:00:00 2001 From: Yeongjae Jang <54150647+Liberatedwinner@users.noreply.github.com> Date: Mon, 15 Feb 2021 13:32:07 +0900 Subject: [PATCH 142/153] Update base.md --- src/base/base.md | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/src/base/base.md b/src/base/base.md index 3006636..c4bcd02 100644 --- a/src/base/base.md +++ b/src/base/base.md @@ -1,19 +1,18 @@ -# Essentials +# 기본 골자 -## Introduction +## 소개 Julia Base contains a range of functions and macros appropriate for performing scientific and numerical computing, but is also as broad as those of many general purpose programming -languages. Additional functionality is available from a growing collection of available packages. -Functions are grouped by topic below. +languages. Additional functionality is available from a growing collection of available packages. +Functions are grouped by topic below. 함수들은 아래의 주제별로 묶여있다. -Some general notes: +몇몇의 기본 사항은 다음과 같다: - * To use module functions, use `import Module` to import the module, and `Module.fn(x)` to use the - functions. - * Alternatively, `using Module` will import all exported `Module` functions into the current namespace. - * By convention, function names ending with an exclamation point (`!`) modify their arguments. - Some functions have both modifying (e.g., `sort!`) and non-modifying (`sort`) versions. + * 모듈의 함수를 사용하기 위해서는 `import Module`로 모듈을 가지고 와서(import), `Module.fn(x)`의 형식으로 사용하면 된다. + * 다른 방법으로, `using Module`을 사용하면 현재의 namespace에서 `Module`의 모든 (all exported) 함수를 사용할 수 있다. + * 기본 규약(convention)으로, 느낌표(`!`)로 그 이름이 끝나는 함수는 전달받은 전달인자(arguments)의 값을 바꾼다. + 몇몇 함수는 바꾸는 경우(e.g., `sort!`)와 바꾸지 않는 경우(`sort`)의 두 가지 버전을 모두 갖는다. ## Getting Around @@ -35,23 +34,23 @@ Base.@show ans ``` -## Keywords +## 주요 단어들 -This is the list of reserved keywords in Julia: +아래의 단어 목록은 줄리아의 예약어(reserved keyword) 목록이다: `baremodule`, `begin`, `break`, `catch`, `const`, `continue`, `do`, `else`, `elseif`, `end`, `export`, `false`, `finally`, `for`, `function`, `global`, `if`, `import`, `let`, `local`, `macro`, `module`, `quote`, `return`, `struct`, `true`, `try`, `using`, `while`. -Those keywords are not allowed to be used as variable names. +이 단어들은 변수 이름으로 사용하는 것이 불가하다. -The following two-word sequences are reserved: +아래의 연속된 두 단어짜리 구 전체는 예약어이다 (따라서 변수 이름으로 사용할 수 없다.): `abstract type`, `mutable struct`, `primitive type`. -However, you can create variables with names: -`abstract`, `mutable`, `primitive` and `type`. +하지만, 아래의 이름으로 변수를 만드는 것은 가능하다: +`abstract`, `mutable`, `primitive`, and `type`. -Finally,`where` is parsed as an infix operator for writing parametric method -and type definitions. Also `in` and `isa` are parsed as infix operators. -Creation of a variable named `where`, `in` or `isa` is allowed though. +마지막으로, Finally, `where`는 parametric method나 type 정의를 적을 때 중위 연산자(infix operator)로 구문분석된다(is parsed). +`in`과 `isa` 또한 중위 연산자로 구문분석된다. +그러나 `where`, `in` 혹은 `isa`로 변수 이름을 짓는 것은 허용된다. ```@docs module From d1c2c230922a17d01cf7218390844dc2a92304a3 Mon Sep 17 00:00:00 2001 From: Yeongjae Jang <54150647+Liberatedwinner@users.noreply.github.com> Date: Mon, 15 Feb 2021 13:34:45 +0900 Subject: [PATCH 143/153] Update complex-and-rational-numbers.md --- src/manual/complex-and-rational-numbers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/manual/complex-and-rational-numbers.md b/src/manual/complex-and-rational-numbers.md index 942273a..ffdb4c9 100644 --- a/src/manual/complex-and-rational-numbers.md +++ b/src/manual/complex-and-rational-numbers.md @@ -192,7 +192,7 @@ julia> -4//-12 1//3 ``` -분자가 분모가 서로소인 상태는 유일하며, 두 유리수가 같은지 보려면 각 분자와 분모가 같은지 보면 된다. +분자와 분모가 서로소인 상태는 유일하며, 두 유리수가 같은지 보려면 각 분자와 분모가 같은지 보면 된다. 유리수의 분자와 분모는 [`numerator`](@ref)와 [`denominator`](@ref)함수로 확인할 수 있다: ```jldoctest From 22c3d7138ec7a3256056349fb27bf9939a4eb23b Mon Sep 17 00:00:00 2001 From: Yeongjae Jang <54150647+Liberatedwinner@users.noreply.github.com> Date: Mon, 15 Feb 2021 13:41:44 +0900 Subject: [PATCH 144/153] Update functions.md --- src/manual/functions.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/manual/functions.md b/src/manual/functions.md index 79e10e9..c77df6c 100644 --- a/src/manual/functions.md +++ b/src/manual/functions.md @@ -1,6 +1,6 @@ # [함수](@id man-functions) -함수는 인자를 받아 값을 반환하는 객체이다. Julia에서 정의하는 함수는 실행 상황에 영향을 받는다는 점에서 수학적 정의에 따른 함수와는 조금 다르다. 아래는 Julia에서 함수는 정의하는 가장 기본적인 방법이다: +함수는 인자를 받아 값을 반환하는 객체이다. Julia에서 정의하는 함수는 실행 상황에 영향을 받는다는 점에서 수학적 정의에 따른 함수와는 조금 다르다. 아래는 Julia에서 함수를 정의하는 가장 기본적인 방법이다: ```jldoctest julia> function f(x,y) @@ -13,7 +13,7 @@ f (generic function with 1 method) julia> f(x,y) = x + y f (generic function with 1 method) ``` -위처럼 "할당 형식(assignment form)"으로 선언할 경우 복합 표현이더라도 한줄로 표현해야 한다([복합 표현을 자세하고 알고 싶다면?](@ref man-compound-expressions)). 이렇게 함수를 표현하는 경우는 Julia에 흔한 일이고, 때론 코드 가독성을 높여준다. +위처럼 "할당 형식(assignment form)"으로 선언할 경우 복합 표현이더라도 한 줄로 표현해야 한다([복합 표현을 자세하고 알고 싶다면?](@ref man-compound-expressions)). 이렇게 함수를 표현하는 경우는 Julia에 흔한 일이고, 때론 코드 가독성을 높여준다. 다른 언어처럼 소괄호를 통해 함수 인자를 전달한다: @@ -41,14 +41,14 @@ julia> ∑(2, 3) ## 인자 전달 방식 함수에 인자를 줄 때 Julia는 "공유를 통한 전달([pass-by-sharing](https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing))"을 한다. -이 말은 즉슨, 객체를 복사하지 않고 공유한다는 뜻이다. +이 말인즉슨, 객체를 복사하지 않고 공유한다는 뜻이다. 전달된 인자는 함수 안에 있는 변수에 할당되고, 함수 안의 변수는 단지 그 객체를 가리킬 뿐이다. `Array`와 같은 mutable 객체가 함수 안에서 변하면, 함수 밖에서도 그 변화를 볼 수 있다. 이런 방식은 Scheme, Python, Ruby, Perl 그리고 대부분의 Lisp와 같은 동적언어가 채택한 방식이다. ## return 키워드 함수가 반환하는 값은 암묵적으로 가장 마지막으로 계산된 값이다. 이전의 예제 함수 `f`에서는 `x+y`의 값이 반환될 것이다. -다른 프로그래밍 언어처럼 `return`과 리턴값이 명시적으로 선언될 경우, 함수는 즉시 종료되고 `return`앞에 있는 식을 계산하고 반환할 것이다: +다른 프로그래밍 언어처럼 `return`과 반환값이 명시적으로 선언될 경우, 함수는 즉시 종료되고 `return` 앞에 있는 식을 계산하고 반환할 것이다: ```julia function g(x,y) @@ -75,7 +75,7 @@ julia> g(2,3) 6 ``` 함수 `g`에서 `x+y`는 절대 실행되지 않기 때문에, 이 부분을 빼고 `x*y`만 남겨놔도 똑같이 작동한다. -`return`을 직접 선언하는 방식은 조건문과 같이 코드의 흐름을 바꾸는 구문과 사용했을 대 빛을 발한다. 아래에 직각 삼각형에서 밑변 `x`와 높이 `y`가 주어졌을 때 빗변의 길이는 구하는 예제로 확인할 수 있다. 아래 함수는 overflow를 없애기 위해 조건문을 사용했다: +`return`을 직접 선언하는 방식은 조건문과 같이 코드의 흐름을 바꾸는 구문과 사용했을 때 빛을 발한다. 아래에 직각 삼각형에서 밑변 `x`와 높이 `y`가 주어졌을 때 빗변의 길이는 구하는 예제로 확인할 수 있다. 아래 함수는 overflow를 없애기 위해 조건문을 사용했다: ```jldoctest julia> function hypot(x,y) @@ -96,11 +96,11 @@ hypot (generic function with 1 method) julia> hypot(3, 4) 5.0 ``` -위 함수는 경우에 따라 세가지 방법으로 값을 반환한다. 마지막에 `return`은 생략해도 된다. +위 함수는 경우에 따라 세 가지 방법으로 값을 반환한다. 마지막에 `return`은 생략해도 된다. ## 반환 타입 -반환값의 타입은 `::`로 명시할 수 있으며, 이경우 반환값이 자동 형변환된다. +반환값의 타입은 `::`로 명시할 수 있으며, 이 경우 반환값이 자동 형변환된다. ```jldoctest julia> function g(x, y)::Int8 @@ -138,7 +138,7 @@ alone is a matter of coding style. ## 연산자는 함수다 -Julia에서 연산자는 특별한 문법을 가진 함수일 뿐입니다(`&&`와 `||`는 예외다. +Julia에서 연산자는 특별한 문법을 가진 함수일 뿐이다(`&&`와 `||`는 예외다. 이들은 [단락 계산](@ref Short-Circuit-Evaluation)에서 나왔다시피 연산자가 피연산자보다 먼저 계산되기 때문이다). 따라서 연산자는 일반 함수처럼 소괄호를 이용해 인자를 전달할 수 있다: @@ -262,8 +262,8 @@ julia> x.a 여러 값을 반환하기 위해 함수는 튜플을 반환한다. 하지만 튜플은 괄호 없이 생성되기도 하고 분리되기도 하므로 명시적으로 튜플을 사용한다는 것을 나타낼 필요가 없다. -이는 우리가 값을 여러개 반환한다는 환상을 심어준다. -예제로 두개의 값을 반환하는 상황을 보자: +이는 우리가 값을 여러 개 반환한다는 환상을 심어준다. +예제로 두 개의 값을 반환하는 상황을 보자: ```jldoctest foofunc julia> function foo(a,b) From 934b38860c04db1d64c86a859fd040fac4018972 Mon Sep 17 00:00:00 2001 From: Yeongjae Jang <54150647+Liberatedwinner@users.noreply.github.com> Date: Mon, 15 Feb 2021 13:42:41 +0900 Subject: [PATCH 145/153] Update base.md --- src/base/base.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/base/base.md b/src/base/base.md index c4bcd02..2295eae 100644 --- a/src/base/base.md +++ b/src/base/base.md @@ -11,7 +11,7 @@ Functions are grouped by topic below. 함수들은 아래의 주제별로 묶여 * 모듈의 함수를 사용하기 위해서는 `import Module`로 모듈을 가지고 와서(import), `Module.fn(x)`의 형식으로 사용하면 된다. * 다른 방법으로, `using Module`을 사용하면 현재의 namespace에서 `Module`의 모든 (all exported) 함수를 사용할 수 있다. - * 기본 규약(convention)으로, 느낌표(`!`)로 그 이름이 끝나는 함수는 전달받은 전달인자(arguments)의 값을 바꾼다. + * 관습적으로(by convention), 느낌표(`!`)로 그 이름이 끝나는 함수는 전달받은 전달인자(arguments)의 값을 바꾼다. 몇몇 함수는 바꾸는 경우(e.g., `sort!`)와 바꾸지 않는 경우(`sort`)의 두 가지 버전을 모두 갖는다. ## Getting Around From f2cfdb45c1e6cc7fcc4782cfdd3cccf832f7c87b Mon Sep 17 00:00:00 2001 From: Yeongjae Jang <54150647+Liberatedwinner@users.noreply.github.com> Date: Mon, 15 Feb 2021 14:45:45 +0900 Subject: [PATCH 146/153] Update arrays.md --- src/manual/arrays.md | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/manual/arrays.md b/src/manual/arrays.md index 0f51fbc..b9f763b 100644 --- a/src/manual/arrays.md +++ b/src/manual/arrays.md @@ -10,7 +10,7 @@ Julia는 대부분의 수치 계산용 언어처럼 일급 객체로써 배열 일반으로 배열은 [`Any`](@ref) 타입의 객체들을 담을 수 있다. 수치 계산용으로 사용하려면 배열은 [`Float64`](@ref)이나 [`Int32`](@ref)와 같이 더 구체적인 타입의 객체를 담는 것이 좋다. -다른 많은 수치 계산용 언어에서는 성능을 위해 프로그램을 벡터화된 스타일로 작성하지만, Julia에서는 대게 그럴 필요가 없다. +다른 많은 수치 계산용 언어에서는 성능을 위해 프로그램을 벡터화된 스타일로 작성하지만, Julia에서는 대개 그럴 필요가 없다. Julia 컴파일러는 타입 추론을 통해 스칼라 배열 인덱싱에 최적화된 코드를 생성한다. 따라서 편리하고 읽기 쉬운 스타일로 프로그램을 작성해도 성능이 보존되며, 오히려 메모리를 더 적게 사용하는 경우도 있다. @@ -381,17 +381,13 @@ A[I_1, I_2, ..., I_n] = X 여기서 `I_k` 는 스칼라 정수, 정수의 배열, 혹은 [지원하는 다른 인덱스](@ref man-supported-index-types) 중 하나이다. 여기에는 모든 인덱스를 선택하는 [`Colon`](@ref) (`:`), 연속되거나 일정한 간격의 부분수열을 선택하는 `a:c` 혹은 `a:b:c`와 같은 형태의 범위, 그리고 `true` 값을 선택하는 부울 배열도 포함된다. -If all indices `I_k` are integers, then the value in location `I_1, I_2, ..., I_n` of `A` is -overwritten with the value of `X`, [`convert`](@ref)ing to the -[`eltype`](@ref) of `A` if necessary. +만약 인덱스 `I_k`들이 모두 정수라면, `A`의 `I_1, I_2, ..., I_n`에 위치한 값은 `X`의 값으로 덮어씌워진다. +필요하다면 [`eltype`](@ref)으로 형 변환[`convert`](@ref)이 일어날 수 있다. - -If any index `I_k` selects more than one location, then the right hand side `X` must be an -array with the same shape as the result of indexing `A[I_1, I_2, ..., I_n]` or a vector with -the same number of elements. The value in location `I_1[i_1], I_2[i_2], ..., I_n[i_n]` of -`A` is overwritten with the value `X[I_1, I_2, ..., I_n]`, converting if necessary. The -element-wise assignment operator `.=` may be used to [broadcast](@ref Broadcasting) `X` -across the selected locations: +만약 어떤 인덱스 `I_k`가 한 개보다 많은 위치를 선택할 경우, +우변의 `X`는 `A[I_1, I_2, ..., I_n]`의 인덱싱 결과와 같은 모양의 배열이거나, 성분 개수가 같은 벡터여야만 한다. +`A`의 `I_1[i_1], I_2[i_2], ..., I_n[i_n]`에 위치한 값은 값 `X[I_1, I_2, ..., I_n]`으로 덮어씌워지며, 필요한 경우 형 변환이 일어난다. +성분별 대입 연산자(The element-wise assignment operator) `.=`는 선택된 위치 전체에 대한 `X`의 브로드캐스팅[broadcast](@ref Broadcasting)에 쓰일 수 있다. ``` A[I_1, I_2, ..., I_n] .= X From 64ed62776a0fb0682125a0a2e9f978e3bb775384 Mon Sep 17 00:00:00 2001 From: Yeongjae Jang <54150647+Liberatedwinner@users.noreply.github.com> Date: Mon, 15 Feb 2021 14:50:39 +0900 Subject: [PATCH 147/153] Update arrays.md --- src/manual/arrays.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/manual/arrays.md b/src/manual/arrays.md index b9f763b..1ba0698 100644 --- a/src/manual/arrays.md +++ b/src/manual/arrays.md @@ -382,12 +382,12 @@ A[I_1, I_2, ..., I_n] = X 여기에는 모든 인덱스를 선택하는 [`Colon`](@ref) (`:`), 연속되거나 일정한 간격의 부분수열을 선택하는 `a:c` 혹은 `a:b:c`와 같은 형태의 범위, 그리고 `true` 값을 선택하는 부울 배열도 포함된다. 만약 인덱스 `I_k`들이 모두 정수라면, `A`의 `I_1, I_2, ..., I_n`에 위치한 값은 `X`의 값으로 덮어씌워진다. -필요하다면 [`eltype`](@ref)으로 형 변환[`convert`](@ref)이 일어날 수 있다. +필요하다면 `A`의 [`eltype`](@ref)으로 형 변환[`convert`](@ref)이 일어날 수 있다. 만약 어떤 인덱스 `I_k`가 한 개보다 많은 위치를 선택할 경우, 우변의 `X`는 `A[I_1, I_2, ..., I_n]`의 인덱싱 결과와 같은 모양의 배열이거나, 성분 개수가 같은 벡터여야만 한다. `A`의 `I_1[i_1], I_2[i_2], ..., I_n[i_n]`에 위치한 값은 값 `X[I_1, I_2, ..., I_n]`으로 덮어씌워지며, 필요한 경우 형 변환이 일어난다. -성분별 대입 연산자(The element-wise assignment operator) `.=`는 선택된 위치 전체에 대한 `X`의 브로드캐스팅[broadcast](@ref Broadcasting)에 쓰일 수 있다. +성분별 대입 연산자(The element-wise assignment operator) `.=`를 선택된 위치 전체에 대한 `X`의 브로드캐스팅[broadcast](@ref Broadcasting)에 쓸 수도 있다. ``` A[I_1, I_2, ..., I_n] .= X From 4f9f28667285c63ab4d21cdb1c80aa29ad8b42c8 Mon Sep 17 00:00:00 2001 From: Yeongjae Jang <54150647+Liberatedwinner@users.noreply.github.com> Date: Mon, 15 Feb 2021 15:05:16 +0900 Subject: [PATCH 148/153] Update control-flow.md --- src/manual/control-flow.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/manual/control-flow.md b/src/manual/control-flow.md index 08d1c8a..f2d3116 100644 --- a/src/manual/control-flow.md +++ b/src/manual/control-flow.md @@ -215,12 +215,12 @@ no ## [단락 계산](@id Short-Circuit-Evaluation) -단락 계산는 조건부 계산와 상당히 유사합니다. 이 동작은 `&&` 및 `||` 연산자가 있는 대부분의 명령형 프로그래밍 언어에서 찾을 수 있습니다. 이런 연산자로 연결된 일련의 표현식에서, 최종 논리값을 결정하는 데 필요한 최소 식만 계산됩니다. 명쾌하게 말하자면, 이는 다음을 의미합니다. +단락 계산은 조건부 계산과 상당히 유사합니다. 이 동작은 `&&` 및 `||` 연산자가 있는 대부분의 명령형 프로그래밍 언어에서 찾을 수 있습니다. 이런 연산자로 연결된 일련의 표현식에서, 최종 논리값을 결정하는 데 필요한 최소 식만 계산됩니다. 명쾌하게 말하자면, 이는 다음을 의미합니다. * 표현식 `a && b`에서, 하위 표현식 `b`는 오직 `a`가 `true`로 계산될 때만 계산을 받는다. * 표현식 `a || b`에서, 하위 표현식 `b`는 오직 `a`가 `false`로 계산될 때만 계산을 받는다. -왜냐 하면, `a`가 `false`이면, `b`의 값에 관계없이 `a && b`는 무조건 `false`가 되고, `a`가 `true`이면, `b`의 값에 관계없이 `a && b`는 무조건 `true`가 되기 때문입니다. `&&`와 `||` 모두 오른쪽에 연관되지만, `&&`가 `||`보다 우선 순위가 더 높습니다. 실험해 보면 동작을 이해하기 쉽습니다. +왜냐 하면, `a`가 `false`이면, `b`의 값에 관계없이 `a && b`는 무조건 `false`가 되고, `a`가 `true`이면, `b`의 값에 관계없이 `a && b`는 무조건 `true`가 되기 때문입니다. `&&`와 `||` 모두 오른쪽에 연관되지만, `&&`가 `||`보다 우선 순위가 더 높습니다. 실험해보면 동작을 이해하기 쉽습니다. ```jldoctest tandf julia> t(x) = (println(x); true) @@ -461,7 +461,7 @@ julia> for i = 1:2, j = 3:4 위 문법에서는 범위 객체가 외부 루프 변수의 값을 사용할 수 있습니다(예: `for i = 1:n, j = 1:i`). 그러나 위와 같은 선언에서 `break`는 모든 루프를 탈출하게 됩니다. -`i`와 `j` 변수 둘다 매번 루프가 실행 될 때 값이 지정되므로 실행 중에 `i`값을 바꿔도 그 다음 루프에서 이를 확인 할 수 없습니다: +`i`와 `j` 변수 둘 다 매번 루프가 실행 될 때 값이 지정되므로 실행 중에 `i` 값을 바꿔도 그 다음 루프에서 이를 확인 할 수 없습니다: ```jldoctest julia> for i = 1:2, j = 3:4 From 597f8674610b898550eb0b8003ccccb011d328e2 Mon Sep 17 00:00:00 2001 From: Yeongjae Jang <54150647+Liberatedwinner@users.noreply.github.com> Date: Mon, 15 Feb 2021 15:22:39 +0900 Subject: [PATCH 149/153] Update mathematical-operations.md --- src/manual/mathematical-operations.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/manual/mathematical-operations.md b/src/manual/mathematical-operations.md index 0165699..16ddec6 100644 --- a/src/manual/mathematical-operations.md +++ b/src/manual/mathematical-operations.md @@ -147,8 +147,9 @@ julia> .![true,false,true] 만약 `2 .* A.^2 .+ sin.(A)`(혹은 [`@.`](@ref @__dot__) macro)을 사용하여 `@. 2A^2 + sin(A)`를 계산한다면, Julia는 `A`의 모든 원소에 대해 `2a^2 + sin(a)`를 계산한다. `f.(g.(x))`같은 nested dot 호출도 이런 최적화가 일어나기 때문에 `x .+ 3 .* x.^2`와 `(+).(x, (*).(3, (^).(x, 2)))`같은 함수 꼴로 사용해도 성능상 차이가 발생하지 않는다. -Furthermore, "dotted" updating operators like `a .+= b` (or `@. a += b`) are parsed -as `a .= a .+ b`, where `.=` is a fused *in-place* assignment operation +나아가서, *제자리에 두는* 융합된 대입 연산 `.=`에 대해 +`a .+= b` (or `@. a += b`)와 같은 "dot" 업데이트 연산자들은 `a .= a .+ b`로 구문분석된다(are parsed). + ([dot 문법 문서](@ref man-vectorized)을 참고하라). dot 연산자는 사용자 정의 연산자에서도 활용할 수 있다. @@ -289,7 +290,7 @@ true ``` 비교연산 이어쓰기는 코드 구성을 깔끔하게 한다. -비교연산 이어쓰기는 `&&`사용하여 연산을 한것과 똑같이 작용하고, 원소별 연산에서는 [`&`](@ref)을 사용한 것과 동일하다. +비교연산 이어쓰기는 `&&`를 사용하여 연산을 한 것과 똑같이 작용하고, 원소별 연산에서는 [`&`](@ref)을 사용한 것과 동일하다. 쉽게 말하면 우리가 수학적으로 예상한 것과 똑같이 나온다는 것이다. 그 예로 `0 .< A .< 1`는 각 원소가 0과 1 사이에 있는지에 대한 참/거짓을 행렬로 반환한다. @@ -314,12 +315,12 @@ false 첫번째 결과에서 중간값이 한번만 계산됨을 확인할 수 있다. 이를 통해 `v(1) < v(2) && v(2) <= v(3)`로 계산했을 때보다 적은 계산량을 가지고, 비교연산 이어쓰기에서는 기존 프로그래밍 언어와 달리 계산 순서는 미리 예측할 수 없다는 걸 확인할 수 있다. 따라서 비교연산 이어쓰기에서는 계산 순서가 중요한 연산(예시: 입출력)을 하지말자. -이런 부작용을 감안하고 써야한다면 `&&`연산자를 활용하자. ([Short-Circuit Evaluation](@ref)을 참고하라). +이런 부작용을 감안하고 써야한다면 `&&` 연산자를 활용하자. ([Short-Circuit Evaluation](@ref)을 참고하라). ### 기본 함수 Julia는 수치 계산을 위한 함수와 연산자를 전폭적으로 지원한다. -이런 연산은 서로 다른 타입의 숫자(정수, 실수, 유리수 등)가 충돌없이 수학적인 결과와 맞아 떨어지게끔 되어있다. +이런 연산은 서로 다른 타입의 숫자(정수, 실수, 유리수 등)가 충돌 없이 수학적인 결과와 맞아 떨어지게끔 되어있다. 이런 함수 모두 [dot 문법](@ref man-vectorized)을 지원한다. 예를 들어 `sin.(A)`는 array의 모든 `A`의 원소의 sin값을 구한다. @@ -381,11 +382,10 @@ julia> Base.operator_associativity(:⊗), Base.operator_associativity(:sin), Bas Julia supports three forms of numerical conversion, which differ in their handling of inexact conversions. - * The notation `T(x)` or `convert(T,x)` converts `x` to a value of type `T`. + * 표기법 `T(x)` 또는 `convert(T,x)`는 `x`를 type `T`의 값으로 변환한다. - * If `T` is a floating-point type, the result is the nearest representable value, which could be - positive or negative infinity. - * If `T` is an integer type, an `InexactError` is raised if `x` is not representable by `T`. + * 만약 `T`가 부동 소숫점 type이면, 결과값은 표현할 수 있는 가장 가까운 값으로 나타내며, 이는 양 혹은 음의 무한대도 될 수 있다. + * 만약 `T`가 정수 type이면, `x`를 `T` type으로 나타낼 수 없을 때, `InexactError`가 발생한다. * `x % T` converts an integer `x` to a value of integer type `T` congruent to `x` modulo `2^n`, where `n` is the number of bits in `T`. In other words, the binary representation is truncated to fit. From 0bf6d40712e83563c258540715701addbc0414f6 Mon Sep 17 00:00:00 2001 From: Yeongjae Jang <54150647+Liberatedwinner@users.noreply.github.com> Date: Mon, 15 Feb 2021 15:31:22 +0900 Subject: [PATCH 150/153] Update mathematical-operations.md --- src/manual/mathematical-operations.md | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/manual/mathematical-operations.md b/src/manual/mathematical-operations.md index 16ddec6..85e6659 100644 --- a/src/manual/mathematical-operations.md +++ b/src/manual/mathematical-operations.md @@ -273,12 +273,12 @@ julia> isequal(-0.0, 0.0) false ``` -정수의 signed나 unsigned 혹은 실수 사이의 비교연산은 까다롭습니다. -Julia는 타입 충돌 없이 이런 것들이 잘 작동하게 보장합니다. +정수의 signed나 unsigned 혹은 실수 사이의 비교연산은 까다롭다. +Julia는 타입 충돌 없이 이런 것들이 잘 작동하게 보장한다. -서로 다른 타입에서 `isequal`을 사용하면 [`==`](@ref)을 호출하게 되어있습니다. -여러분이 나만의 타입에서 동일성을 정의하고 싶다면 [`==`](@ref) method를 정의하면 됩니다. -여기에 [`hash`](@ref) method도 정의하면 `isequal(x,y)`은 `hash(x) == hash(y)`을 반환합니다. +서로 다른 타입에서 `isequal`을 사용하면 [`==`](@ref)을 호출하게 되어있다. +당신이 자신만의 타입에서 동일성을 정의하고 싶다면 [`==`](@ref) method를 정의하면 된다. +여기에 [`hash`](@ref) method도 정의하면 `isequal(x,y)`은 `hash(x) == hash(y)`을 반환한다. ### 비교연산 이어쓰기 @@ -314,7 +314,7 @@ false 첫번째 결과에서 중간값이 한번만 계산됨을 확인할 수 있다. 이를 통해 `v(1) < v(2) && v(2) <= v(3)`로 계산했을 때보다 적은 계산량을 가지고, 비교연산 이어쓰기에서는 기존 프로그래밍 언어와 달리 계산 순서는 미리 예측할 수 없다는 걸 확인할 수 있다. -따라서 비교연산 이어쓰기에서는 계산 순서가 중요한 연산(예시: 입출력)을 하지말자. +따라서 비교연산 이어쓰기에서는 계산 순서가 중요한 연산(예시: 입출력)을 하지 말자. 이런 부작용을 감안하고 써야한다면 `&&` 연산자를 활용하자. ([Short-Circuit Evaluation](@ref)을 참고하라). ### 기본 함수 @@ -374,7 +374,7 @@ julia> Base.operator_associativity(:⊗), Base.operator_associativity(:sin), Bas (:left, :none, :right) ``` -`:sin`의 경우 우선순위가 `0`임을 확인할 수 있는데, `0`은 최하위 우선순위가 아니라 유효하지 않은 연사자를 나타낸다. +`:sin`의 경우 우선순위가 `0`임을 확인할 수 있는데, `0`은 최하위 우선순위가 아니라 유효하지 않은 연산자를 나타낸다. 이와 비슷한 이유로 이런 연산자는 연산자 결합성이 `:none`임을 볼 수 있다. ## Numerical Conversions @@ -386,9 +386,8 @@ conversions. * 만약 `T`가 부동 소숫점 type이면, 결과값은 표현할 수 있는 가장 가까운 값으로 나타내며, 이는 양 혹은 음의 무한대도 될 수 있다. * 만약 `T`가 정수 type이면, `x`를 `T` type으로 나타낼 수 없을 때, `InexactError`가 발생한다. - * `x % T` converts an integer `x` to a value of integer type `T` congruent to `x` modulo `2^n`, - where `n` is the number of bits in `T`. In other words, the binary representation is truncated - to fit. + * `x % T`는 정수 `x`를 법 `2^n`에 대해 합동(congruent to `x` modulo `2^n`)인, type `T`의 정수값으로 변환한다(converts an integer `x` to a value of integer type `T`). + 여기서 `n`은 `T` 안의 비트 수이다. In other words, the binary representation is truncated to fit. * The [Rounding functions](@ref) take a type `T` as an optional argument. For example, `round(Int,x)` is a shorthand for `Int(round(x))`. From 68c61b7a8e618c8d355846a6af950bcf60d3b523 Mon Sep 17 00:00:00 2001 From: Yeongjae Jang <54150647+Liberatedwinner@users.noreply.github.com> Date: Mon, 15 Feb 2021 15:33:16 +0900 Subject: [PATCH 151/153] Update mathematical-operations.md --- src/manual/mathematical-operations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/manual/mathematical-operations.md b/src/manual/mathematical-operations.md index 85e6659..cc69393 100644 --- a/src/manual/mathematical-operations.md +++ b/src/manual/mathematical-operations.md @@ -147,7 +147,7 @@ julia> .![true,false,true] 만약 `2 .* A.^2 .+ sin.(A)`(혹은 [`@.`](@ref @__dot__) macro)을 사용하여 `@. 2A^2 + sin(A)`를 계산한다면, Julia는 `A`의 모든 원소에 대해 `2a^2 + sin(a)`를 계산한다. `f.(g.(x))`같은 nested dot 호출도 이런 최적화가 일어나기 때문에 `x .+ 3 .* x.^2`와 `(+).(x, (*).(3, (^).(x, 2)))`같은 함수 꼴로 사용해도 성능상 차이가 발생하지 않는다. -나아가서, *제자리에 두는* 융합된 대입 연산 `.=`에 대해 +나아가서, *in-place* 융합된 대입 연산 `.=`에 대해 `a .+= b` (or `@. a += b`)와 같은 "dot" 업데이트 연산자들은 `a .= a .+ b`로 구문분석된다(are parsed). ([dot 문법 문서](@ref man-vectorized)을 참고하라). From 6c6f67ee9a0c6240c2e14f646997e3d9f466646c Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Mon, 26 Apr 2021 21:52:17 +0900 Subject: [PATCH 152/153] update codex, src manual/variables-and-scoping.md --- codex/manual/variables-and-scoping.md | 628 +++++++++++++++++--------- src/manual/variables-and-scoping.md | 628 +++++++++++++++++--------- 2 files changed, 830 insertions(+), 426 deletions(-) diff --git a/codex/manual/variables-and-scoping.md b/codex/manual/variables-and-scoping.md index d15f4a5..2b0b23d 100644 --- a/codex/manual/variables-and-scoping.md +++ b/codex/manual/variables-and-scoping.md @@ -1,33 +1,37 @@ # [Scope of Variables](@id scope-of-variables) The *scope* of a variable is the region of code within which a variable is visible. Variable scoping -helps avoid variable naming conflicts. The concept is intuitive: two functions can both have arguments -called `x` without the two `x`'s referring to the same thing. Similarly, there are many other cases -where different blocks of code can use the same name without referring to the same thing. The -rules for when the same variable name does or doesn't refer to the same thing are called scope -rules; this section spells them out in detail. +helps avoid variable naming conflicts. The concept is intuitive: two functions can both have +arguments called `x` without the two `x`'s referring to the same thing. Similarly, there are many +other cases where different blocks of code can use the same name without referring to the same +thing. The rules for when the same variable name does or doesn't refer to the same thing are called +scope rules; this section spells them out in detail. Certain constructs in the language introduce *scope blocks*, which are regions of code that are eligible to be the scope of some set of variables. The scope of a variable cannot be an arbitrary -set of source lines; instead, it will always line up with one of these blocks. There are two -main types of scopes in Julia, *global scope* and *local scope*. The latter can be nested. The -constructs introducing scope blocks are: +set of source lines; instead, it will always line up with one of these blocks. There are two main +types of scopes in Julia, *global scope* and *local scope*. The latter can be nested. There is also +a distinction in Julia between constructs which introduce a "hard scope" and those which only +introduce a "soft scope", which affects whether +[shadowing](https://en.wikipedia.org/wiki/Variable_shadowing) +a global variable by the same name is allowed or not. ### [Scope constructs](@id man-scope-table) -Construct | Scope type | Scope blocks it may be nested in ------------- | ------------- |--------------------------- -[`module`](@ref), [`baremodule`](@ref) | global | global -interactive prompt (REPL) | global | global -(mutable) [`struct`](@ref), [`macro`](@ref) | local | global -[`for`](@ref), [`while`](@ref), [`try-catch-finally`](@ref try), [`let`](@ref) |local | global or local -functions (either syntax, anonymous & do-blocks) | local | global or local -comprehensions, broadcast-fusing | local | global or local +The constructs introducing scope blocks are: + +| Construct | Scope type | Allowed within | +|:----------|:-----------|:---------------| +| [`module`](@ref), [`baremodule`](@ref) | global | global | +| [`struct`](@ref) | local (soft) | global | +| [`for`](@ref), [`while`](@ref), [`try`](@ref try) | local (soft) | global, local | +| [`macro`](@ref) | local (hard) | global | +| functions, [`do`](@ref) blocks, [`let`](@ref) blocks, comprehensions, generators | local (hard) | global, local | Notably missing from this table are [begin blocks](@ref man-compound-expressions) and [if blocks](@ref man-conditional-evaluation) which do *not* introduce new scopes. -Both types of scopes follow somewhat different rules which will be explained below. +The three types of scopes follow somewhat different rules which will be explained below. Julia uses [lexical scoping](https://en.wikipedia.org/wiki/Scope_%28computer_science%29#Lexical_scoping_vs._dynamic_scoping), meaning that a function's scope does not inherit from its caller's scope, but from the scope in @@ -52,15 +56,21 @@ julia> Bar.foo() 1 ``` -Thus *lexical scope* means that the scope of variables can be inferred from the source code alone. +Thus *lexical scope* means that what a variable in a particular piece of code refers to can be +deduced from the code in which it appears alone and does not depend on how the program executes. A +scope nested inside another scope can "see" variables in all the outer scopes in which it is +contained. Outer scopes, on the other hand, cannot see variables in inner scopes. ## Global Scope -Each module introduces a new global scope, separate from the global scope of all other modules; -there is no all-encompassing global scope. Modules can introduce variables of other modules into -their scope through the [using or import](@ref modules) statements or through qualified access using the -dot-notation, i.e. each module is a so-called *namespace*. Note that variable bindings can only -be changed within their global scope and not from an outside module. +Each module introduces a new global scope, separate from the global scope of all other modules—there +is no all-encompassing global scope. Modules can introduce variables of other modules into their +scope through the [using or import](@ref modules) statements or through qualified access using the +dot-notation, i.e. each module is a so-called *namespace* as well as a first-class data structure +associating names with values. Note that while variable bindings can be read externally, they can only +be changed within the module to which they belong. As an escape hatch, you can always evaluate code +inside that module to modify a variable; this guarantees, in particular, that module bindings cannot +be modified externally by code that never calls `eval`. ```jldoctest julia> module A @@ -93,249 +103,431 @@ Note that the interactive prompt (aka REPL) is in the global scope of the module ## Local Scope -A new local scope is introduced by most code blocks (see above -[table](@ref man-scope-table) for a complete list). -A local scope inherits all the variables from a parent local scope, -both for reading and writing. -Unlike global scopes, local scopes are not namespaces, -thus variables in an inner scope cannot be retrieved from the parent scope through some sort of -qualified access. - -The following rules and examples pertain to local scopes. -A newly introduced variable in a local scope cannot be referenced by a parent scope. -For example, here the ``z`` is not introduced into the top-level scope: +A new local scope is introduced by most code blocks (see above [table](@ref +man-scope-table) for a complete list). If such a block is syntactically nested +inside of another local scope, the scope it creates is nested inside of all the +local scopes that it appears within, which are all ultimately nested inside of +the global scope of the module in which the code is evaluated. Variables in +outer scopes are visible from any scope they contain — meaning that they can be +read and written in inner scopes — unless there is a local variable with the +same name that "shadows" the outer variable of the same name. This is true even +if the outer local is declared after (in the sense of textually below) an inner +block. When we say that a variable "exists" in a given scope, this means that a +variable by that name exists in any of the scopes that the current scope is +nested inside of, including the current one. + +Some programming languages require explicitly declaring new variables before +using them. Explicit declaration works in Julia too: in any local scope, writing +`local x` declares a new local variable in that scope, regardless of whether +there is already a variable named `x` in an outer scope or not. Declaring each +new variable like this is somewhat verbose and tedious, however, so Julia, like +many other languages, considers assignment to a variable name that doesn't +already exist to implicitly declare that variable. If the current scope is +global, the new variable is global; if the current scope is local, the new +variable is local to the innermost local scope and will be visible inside of +that scope but not outside of it. If you assign to an existing local, it +_always_ updates that existing local: you can only shadow a local by explicitly +declaring a new local in a nested scope with the `local` keyword. In particular, +this applies to variables assigned in inner functions, which may surprise users +coming from Python where assignment in an inner function creates a new local +unless the variable is explictly declared to be non-local. + +Mostly this is pretty intuitive, but as with many things that behave +intuitively, the details are more subtle than one might naïvely imagine. + +When `x = ` occurs in a local scope, Julia applies the following rules to decide what the +expression means based on where the assignment expression occurs and what `x` already refers to at +that location: + +1. **Existing local:** If `x` is *already a local variable*, then the existing local `x` is + assigned; +2. **Hard scope:** If `x` is *not already a local variable* and assignment occurs inside of any + hard scope construct (i.e. within a `let` block, function or macro body, comprehension, or + generator), a new local named `x` is created in the scope of the assignment; +3. **Soft scope:** If `x` is *not already a local variable* and all of the scope constructs + containing the assignment are soft scopes (loops, `try`/`catch` blocks, or `struct` blocks), the + behavior depends on whether the global variable `x` is defined: + * if global `x` is *undefined*, a new local named `x` is created in the scope of the + assignment; + * if global `x` is *defined*, the assignment is considered ambiguous: + * in *non-interactive* contexts (files, eval), an ambiguity warning is printed and a new + local is created; + * in *interactive* contexts (REPL, notebooks), the global variable `x` is assigned. + +You may note that in non-interactive contexts the hard and soft scope behaviors are identical except +that a warning is printed when an implicitly local variable (i.e. not declared with `local x`) +shadows a global. In interactive contexts, the rules follow a more complex heuristic for the sake of +convenience. This is covered in depth in examples that follow. + +Now that you know the rules, let's look at some examples. Each example is assumed to be evaluated in +a fresh REPL session so that the only globals in each snippet are the ones that are assigned in that +block of code. + +We'll begin with a nice and clear-cut situation—assignment inside of a hard scope, in this case a +function body, when no local variable by that name already exists: ```jldoctest -julia> for i = 1:10 - z = i +julia> function greet() + x = "hello" # new local + println(x) end +greet (generic function with 1 method) -julia> z -ERROR: UndefVarError: z not defined -``` +julia> greet() +hello -!!! note - In this and all following examples it is assumed that their top-level is a global scope - with a clean workspace, for instance a newly started REPL. +julia> x # global +ERROR: UndefVarError: x not defined +``` -Inner local scopes can, however, update variables in their parent scopes: +Inside of the `greet` function, the assignment `x = "hello"` causes `x` to be a new local variable +in the function's scope. There are two relevant facts: the assignment occurs in local scope and +there is no existing local `x` variable. Since `x` is local, it doesn't matter if there is a global +named `x` or not. Here for example we define `x = 123` before defining and calling `greet`: ```jldoctest -julia> for i = 1:1 - z = i - for j = 1:1 - z = 0 - end - println(z) +julia> x = 123 # global +123 + +julia> function greet() + x = "hello" # new local + println(x) end -0 +greet (generic function with 1 method) + +julia> greet() +hello + +julia> x # global +123 +``` + +Since the `x` in `greet` is local, the value (or lack thereof) of the global `x` is unaffected by +calling `greet`. The hard scope rule doesn't care whether a global named `x` exists or not: +assignment to `x` in a hard scope is local (unless `x` is declared global). + +The next clear cut situation we'll consider is when there is already a local +variable named `x`, in which case `x = ` always assigns to this existing +local `x`. This is true whether the assignment occurs in the same local scope, +an inner local scope in the same function body, or in the body of a function +nested inside of another function, also known as a +[closure](https://en.wikipedia.org/wiki/Closure_(computer_programming)). + +We'll use the `sum_to` function, which computes the sum of integers from one up +to `n`, as an example: + +```julia +function sum_to(n) + s = 0 # new local + for i = 1:n + s = s + i # assign existing local + end + return s # same local +end ``` -Inside a local scope a variable can be forced to be a new local variable using the [`local`](@ref) keyword: +As in the previous example, the first assignment to `s` at the top of `sum_to` causes `s` to be a +new local variable in the body of the function. The `for` loop has its own inner local scope within +the function scope. At the point where `s = s + i` occurs, `s` is already a local variable, so the +assignment updates the existing `s` instead of creating a new local. We can test this out by calling +`sum_to` in the REPL: ```jldoctest -julia> for i = 1:1 - x = i + 1 - for j = 1:1 - local x = 0 +julia> function sum_to(n) + s = 0 # new local + for i = 1:n + s = s + i # assign existing local end - println(x) + return s # same local end -2 +sum_to (generic function with 1 method) + +julia> sum_to(10) +55 + +julia> s # global +ERROR: UndefVarError: s not defined ``` -Inside a local scope a global variable can be assigned to by using the keyword [`global`](@ref): +Since `s` is local to the function `sum_to`, calling the function has no effect on the global +variable `s`. We can also see that the update `s = s + i` in the `for` loop must have updated the same +`s` created by the initialization `s = 0` since we get the correct sum of 55 for the integers 1 +through 10. + +Let's dig into the fact that the `for` loop body has its own scope for a second by writing a slightly +more verbose variation which we'll call `sum_to_def`, in which we save the sum `s + i` in a variable `t` +before updating `s`: ```jldoctest -julia> for i = 1:10 - global z - z = i +julia> function sum_to_def(n) + s = 0 # new local + for i = 1:n + t = s + i # new local `t` + s = t # assign existing local `s` + end + return s, @isdefined(t) end +sum_to_def (generic function with 1 method) -julia> z -10 +julia> sum_to_def(10) +(55, false) ``` -The location of both the `local` and `global` keywords within the scope block is irrelevant. -The following is equivalent to the last example (although stylistically worse): +This version returns `s` as before but it also uses the `@isdefined` macro to return a boolean +indicating whether there is a local variable named `t` defined in the function's outermost local +scope. As you can see, there is no `t` defined outside of the `for` loop body. This is because of the +hard scope rule again: since the assignment to `t` occurs inside of a function, which +introduces a hard scope, the assignment causes `t` to become a new local variable in the local scope +where it appears, i.e. inside of the loop body. Even if there were a global named `t`, it would make +no difference—the hard scope rule isn't affected by anything in global scope. + +Note that the local scope of a for loop body is no different from the local +scope of an inner function. This means that we could rewrite this example so +that the loop body is implemented as a call to an inner helper function and it +behaves the same way: ```jldoctest -julia> for i = 1:10 - z = i - global z +julia> function sum_to_def_closure(n) + function loop_body(i) + t = s + i # new local `t` + s = t # assign same local `s` as below + end + s = 0 # new local + for i = 1:n + loop_body(i) + end + return s, @isdefined(t) end +sum_to_def_closure (generic function with 1 method) -julia> z -10 +julia> sum_to_def_closure(10) +(55, false) ``` -The `local` and `global` keywords can also be applied to destructuring assignments, e.g. -`local x, y = 1, 2`. In this case the keyword affects all listed variables. +This example illustrates a couple of key points: -In a local scope, all variables are inherited from its parent -global scope block unless: +1. Inner function scopes are just like any other nested local scope. In + particular, if a variable is already a local outside of an inner function and + you assign to it in the inner function, the outer local variable is updated. - * an assignment would result in a modified *global* variable, or - * a variable is specifically marked with the keyword `local`. +2. It doesn't matter if the definition of an outer local happens below where it + is updated, the rule remains the same. The entire enclosing local scope is + parsed and its locals determined before inner local meanings are resolved. -Thus global variables are only inherited for reading, not for writing: +This design means that you can generally move code in or out of an inner +function without changing its meaning, which facilitates a number of common +idioms in the language using closures (see [do blocks](@ref +Do-Block-Syntax-for-Function-Arguments)). -```jldoctest -julia> x, y = 1, 2; +Let's move onto some more ambiguous cases covered by the soft scope rule. We'll explore this by +extracting the bodies of the `greet` and `sum_to_def` functions into soft scope contexts. First, let's put the +body of `greet` in a `for` loop—which is soft, rather than hard—and evaluate it in the REPL: -julia> function foo() - x = 2 # assignment introduces a new local - return x + y # y refers to the global - end; - -julia> foo() -4 +```jldoctest +julia> for i = 1:3 + x = "hello" # new local + println(x) + end +hello +hello +hello julia> x -1 +ERROR: UndefVarError: x not defined ``` -An explicit `global` is needed to assign to a global variable: - -!!! sidebar "Avoiding globals" - Avoiding changing the value of global variables is considered by many - to be a programming best-practice. - Changing the value of a global variable can cause "action at a distance", - making the behavior of a program harder to reason about. - This is why the scope blocks that introduce local scope require the `global` - keyword to declare the intent to modify a global variable. - -```jldoctest -julia> x = 1; - -julia> function foobar() - global x = 2 - end; - -julia> foobar(); - -julia> x -2 +Since the global `x` is not defined when the `for` loop is evaluated, the first clause of the soft +scope rule applies and `x` is created as local to the `for` loop and therefore global `x` remains +undefined after the loop executes. Next, let's consider the body of `sum_to_def` extracted into global +scope, fixing its argument to `n = 10` + +```julia +s = 0 +for i = 1:10 + t = s + i + s = t +end +s +@isdefined(t) ``` -Note that *nested functions* can modify their parent scope's *local* variables: +What does this code do? Hint: it's a trick question. The answer is "it depends." If this code is +entered interactively, it behaves the same way it does in a function body. But if the code appears +in a file, it prints an ambiguity warning and throws an undefined variable error. Let's see it +working in the REPL first: ```jldoctest -julia> x, y = 1, 2; +julia> s = 0 # global +0 -julia> function baz() - x = 2 # introduces a new local - function bar() - x = 10 # modifies the parent's x - return x + y # y is global - end - return bar() + x # 12 + 10 (x is modified in call of bar()) - end; +julia> for i = 1:10 + t = s + i # new local `t` + s = t # assign global `s` + end -julia> baz() -22 +julia> s # global +55 -julia> x, y # verify that global x and y are unchanged -(1, 2) +julia> @isdefined(t) # global +false ``` -The reason to allow modifying local variables of parent scopes in -nested functions is to allow constructing [`closures`](https://en.wikipedia.org/wiki/Closure_%28computer_programming%29) -which have private state, for instance the `state` variable in the -following example: +The REPL approximates being in the body of a function by deciding whether assignment inside the loop +assigns to a global or creates new local based on whether a global variable by that name is defined +or not. If a global by the name exists, then the assignment updates it. If no global exists, then +the assignment creates a new local variable. In this example we see both cases in action: -```jldoctest -julia> let state = 0 - global counter() = (state += 1) - end; +* There is no global named `t`, so `t = s + i` creates a new `t` that is local to the `for` loop; +* There is a global named `s`, so `s = t` assigns to it. -julia> counter() -1 +The second fact is why execution of the loop changes the global value of `s` and the first fact is +why `t` is still undefined after the loop executes. Now, let's try evaluating this same code as +though it were in a file instead: -julia> counter() -2 +```jldoctest +julia> code = """ + s = 0 # global + for i = 1:10 + t = s + i # new local `t` + s = t # new local `s` with warning + end + s, # global + @isdefined(t) # global + """; + +julia> include_string(Main, code) +┌ Warning: Assignment to `s` in soft scope is ambiguous because a global variable by the same name exists: `s` will be treated as a new local. Disambiguate by using `local s` to suppress this warning or `global s` to assign to the existing global variable. +└ @ string:4 +ERROR: LoadError: UndefVarError: s not defined ``` -See also the closures in the examples in the next two sections. A variable, -such as `x` in the first example and `state` in the second, that is inherited -from the enclosing scope by the inner function is sometimes called a -*captured* variable. Captured variables can present performance challenges -discussed in [performance tips](@ref man-performance-tips). +Here we use [`include_string`](@ref), to evaluate `code` as though it were the contents of a file. +We could also save `code` to a file and then call `include` on that file—the result would be the +same. As you can see, this behaves quite different from evaluating the same code in the REPL. Let's +break down what's happening here: + +* global `s` is defined with the value `0` before the loop is evaluated +* the assignment `s = t` occurs in a soft scope—a `for` loop outside of any function body or other hard + scope construct +* therefore the second clause of the soft scope rule applies, and the assignment is ambiguous so a + warning is emitted +* execution continues, making `s` local to the `for` loop body +* since `s` is local to the `for` loop, it is undefined when `t = s + i` is evaluated, causing an error +* evaluation stops there, but if it got to `s` and `@isdefined(t)`, it would return `0` and `false`. + +This demonstrates some important aspects of scope: in a scope, each variable can only have one +meaning, and that meaning is determined regardless of the order of expressions. The presence of the +expression `s = t` in the loop causes `s` to be local to the loop, which means that it is also local +when it appears on the right hand side of `t = s + i`, even though that expression appears first and is +evaluated first. One might imagine that the `s` on the first line of the loop could be global while +the `s` on the second line of the loop is local, but that's not possible since the two lines are in +the same scope block and each variable can only mean one thing in a given scope. + +#### On Soft Scope + +We have now covered all the local scope rules, but before wrapping up this section, perhaps a few +words should be said about why the ambiguous soft scope case is handled differently in interactive +and non-interactive contexts. There are two obvious questions one could ask: + +1. Why doesn't it just work like the REPL everywhere? +2. Why doesn't it just work like in files everywhere? And maybe skip the warning? + +In Julia ≤ 0.6, all global scopes did work like the current REPL: when `x = ` occurred in a +loop (or `try`/`catch`, or `struct` body) but outside of a function body (or `let` block or comprehension), +it was decided based on whether a global named `x` was defined or not whether `x` should be local to +the loop. This behavior has the advantage of being intuitive and convenient since it approximates +the behavior inside of a function body as closely as possible. In particular, it makes it easy to +move code back and forth between a function body and the REPL when trying to debug the behavior of a +function. However, it has some downsides. First, it's quite a complex behavior: many people over the +years were confused about this behavior and complained that it was complicated and hard both to +explain and understand. Fair point. Second, and arguably worse, is that it's bad for programming "at +scale." When you see a small piece of code in one place like this, it's quite clear what's going on: + +```julia +s = 0 +for i = 1:10 + s += i +end +``` -The distinction between inheriting global scope and nesting local scope -can lead to some slight differences between functions -defined in local versus global scopes for variable assignments. -Consider the modification of the last example by moving `bar` to the global scope: +Obviously the intention is to modify the existing global variable `s`. What else could it mean? +However, not all real world code is so short or so clear. We found that code like the following +often occurs in the wild: -```jldoctest -julia> x, y = 1, 2; +```julia +x = 123 -julia> function bar() - x = 10 # local, no longer a closure variable - return x + y - end; +# much later +# maybe in a different file -julia> function quz() - x = 2 # local - return bar() + x # 12 + 2 (x is not modified) - end; +for i = 1:10 + x = "hello" + println(x) +end -julia> quz() -14 +# much later +# maybe in yet another file +# or maybe back in the first one where `x = 123` -julia> x, y # verify that global x and y are unchanged -(1, 2) +y = x + 234 ``` -Note that the above nesting rules do not pertain to type and macro definitions as they can only appear -at the global scope. There are special scoping rules concerning the evaluation of default and -keyword function arguments which are described in the [Function section](@ref man-functions). - -An assignment introducing a variable used inside a function, type or macro definition need not -come before its inner usage: - -```jldoctest -julia> f = y -> y + a; - -julia> f(3) -ERROR: UndefVarError: a not defined -Stacktrace: -[...] - -julia> a = 1 -1 - -julia> f(3) -4 +It's far less clear what should happen here. Since `x + "hello"` is a method error, it seems +probable that the intention is for `x` to be local to the `for` loop. But runtime values and what +methods happen to exist cannot be used to determine the scopes of variables. With the Julia ≤ 0.6 +behavior, it's especially concerning that someone might have written the `for` loop first, had it +working just fine, but later when someone else adds a new global far away—possibly in a different +file—the code suddenly changes meaning and either breaks noisily or, worse still, silently does the +wrong thing. This kind of ["spooky action at a distance"](https://en.wikipedia.org/wiki/Action_at_a_distance_(computer_programming)) is something that good programming language +designs should prevent. + +So in Julia 1.0, we simplified the rules for scope: in any local scope, assignment to a name that +wasn't already a local variable created a new local variable. This eliminated the notion of soft +scope entirely as well as removing the potential for spooky action. We uncovered and fixed a significant number of bugs due to the removal of soft scope, vindicating the choice to get rid of it. +And there was much rejoicing! Well, no, not really. Because some people were +angry that they now had to write: + +```julia +s = 0 +for i = 1:10 + global s += i +end ``` -This behavior may seem slightly odd for a normal variable, but allows for named functions -- which -are just normal variables holding function objects -- to be used before they are defined. This -allows functions to be defined in whatever order is intuitive and convenient, rather than forcing -bottom up ordering or requiring forward declarations, as long as they are defined by the time -they are actually called. As an example, here is an inefficient, mutually recursive way to test -if positive integers are even or odd: +Do you see that `global` annotation in there? Hideous. Obviously this situation could not be +tolerated. But seriously, there are two main issues with requiring `global` for this kind of +top-level code: -```jldoctest -julia> even(n) = (n == 0) ? true : odd(n - 1); +1. It's no longer convenient to copy and paste the code from inside a function body into the REPL + to debug it—you have to add `global` annotations and then remove them again to go back; -julia> odd(n) = (n == 0) ? false : even(n - 1); +2. Beginners will write this kind of code without the `global` and have no idea why their code + doesn't work—the error that they get is that `s` is undefined, which does not seem to enlighten + anyone who happens to make this mistake. -julia> even(3) -false +As of Julia 1.5, this code works without the `global` annotation in interactive contexts like the +REPL or Jupyter notebooks (just like Julia 0.6) and in files and other non-interactive contexts, it +prints this very direct warning: -julia> odd(3) -true -``` +> Assignment to `s` in soft scope is ambiguous because a global variable by the same name exists: +> `s` will be treated as a new local. Disambiguate by using `local s` to suppress this warning or +> `global s` to assign to the existing global variable. + +This addresses both issues while preserving the "programming at scale" benefits of the 1.0 behavior: +global variables have no spooky effect on the meaning of code that may be far away; in the REPL +copy-and-paste debugging works and beginners don't have any issues; any time someone either forgets +a `global` annotation or accidentally shadows an existing global with a local in a soft scope, +which would be confusing anyway, they get a nice clear warning. -Julia provides built-in, efficient functions to test for oddness and evenness called [`iseven`](@ref) -and [`isodd`](@ref) so the above definitions should only be considered to be examples of scope, -not efficient design. +An important property of this design is that any code that executes in a file without a warning will +behave the same way in a fresh REPL. And on the flip side, if you take a REPL session and save it to +file, if it behaves differently than it did in the REPL, then you will get a warning. ### Let Blocks -Unlike assignments to local variables, `let` statements allocate new variable bindings each time -they run. An assignment modifies an existing value location, and `let` creates new locations. +`let` statements create a new *hard scope* block (see above) and introduce new variable +bindings each time they run. Whereas assignments might reassign a new value to an existing value location, +`let` always creates a new location. This difference is usually not important, and is only detectable in the case of variables that outlive their scope via closures. The `let` syntax accepts a comma-separated series of assignments and variable names: @@ -393,7 +585,7 @@ julia> Fs[2]() ``` Since the `begin` construct does not introduce a new scope, it can be useful to use a zero-argument -`let` to just introduce a new scope block without creating any new bindings: +`let` to just introduce a new scope block without creating any new bindings immediately: ```jldoctest julia> let @@ -407,13 +599,22 @@ julia> let ``` Since `let` introduces a new scope block, the inner local `x` is a different variable than the -outer local `x`. +outer local `x`. This particular example is equivalent to: + +```jldoctest +julia> let x = 1 + let x = 2 + end + x + end +1 +``` -### For Loops and Comprehensions +### Loops and Comprehensions -`for` loops, `while` loops, and [Comprehensions](@ref) have the following behavior: any new variables +In loops and [comprehensions](@ref man-comprehensions), new variables introduced in their body scopes are freshly allocated for each loop iteration, as if the loop body -were surrounded by a `let` block: +were surrounded by a `let` block, as demonstrated by this example: ```jldoctest julia> Fs = Vector{Any}(undef, 2); @@ -435,6 +636,7 @@ A `for` loop or comprehension iteration variable is always a new variable: julia> function f() i = 0 for i = 1:3 + # empty end return i end; @@ -450,6 +652,7 @@ This can be done conveniently by adding the keyword `outer`: julia> function f() i = 0 for outer i = 1:3 + # empty end return i end; @@ -505,7 +708,7 @@ julia> const y = 1.0 1.0 julia> y = 2.0 -WARNING: redefining constant y +WARNING: redefinition of constant y. This may fail, cause incorrect answers, or produce other errors. 2.0 ``` * if an assignment would not result in the change of variable value no message is given: @@ -516,7 +719,7 @@ julia> const z = 100 julia> z = 100 100 ``` -The last rule applies for immutable objects even if the variable binding would change, e.g.: +The last rule applies to immutable objects even if the variable binding would change, e.g.: ```julia-repl julia> const s1 = "1" "1" @@ -540,21 +743,20 @@ julia> pointer.([s1, s2], 1) However, for mutable objects the warning is printed as expected: ```jldoctest julia> const a = [1] -1-element Array{Int64,1}: +1-element Vector{Int64}: 1 julia> a = [1] -WARNING: redefining constant a -1-element Array{Int64,1}: +WARNING: redefinition of constant a. This may fail, cause incorrect answers, or produce other errors. +1-element Vector{Int64}: 1 ``` -Note that although sometimes possible, changing the value of a `const` variable -is strongly discouraged, and is intended only for convenience during -interactive use. -Changing constants can cause various problems or unexpected behaviors. -For instance, if a method references a constant and is already -compiled before the constant is changed then it might keep using the old value: +Note that although sometimes possible, changing the value of a `const` variable is strongly +discouraged, and is intended only for convenience during interactive use. Changing constants can +cause various problems or unexpected behaviors. For instance, if a method references a constant and +is already compiled before the constant is changed, then it might keep using the old value: + ```jldoctest julia> const x = 1 1 @@ -566,7 +768,7 @@ julia> f() 1 julia> x = 2 -WARNING: redefining constant x +WARNING: redefinition of constant x. This may fail, cause incorrect answers, or produce other errors. 2 julia> f() diff --git a/src/manual/variables-and-scoping.md b/src/manual/variables-and-scoping.md index d15f4a5..2b0b23d 100644 --- a/src/manual/variables-and-scoping.md +++ b/src/manual/variables-and-scoping.md @@ -1,33 +1,37 @@ # [Scope of Variables](@id scope-of-variables) The *scope* of a variable is the region of code within which a variable is visible. Variable scoping -helps avoid variable naming conflicts. The concept is intuitive: two functions can both have arguments -called `x` without the two `x`'s referring to the same thing. Similarly, there are many other cases -where different blocks of code can use the same name without referring to the same thing. The -rules for when the same variable name does or doesn't refer to the same thing are called scope -rules; this section spells them out in detail. +helps avoid variable naming conflicts. The concept is intuitive: two functions can both have +arguments called `x` without the two `x`'s referring to the same thing. Similarly, there are many +other cases where different blocks of code can use the same name without referring to the same +thing. The rules for when the same variable name does or doesn't refer to the same thing are called +scope rules; this section spells them out in detail. Certain constructs in the language introduce *scope blocks*, which are regions of code that are eligible to be the scope of some set of variables. The scope of a variable cannot be an arbitrary -set of source lines; instead, it will always line up with one of these blocks. There are two -main types of scopes in Julia, *global scope* and *local scope*. The latter can be nested. The -constructs introducing scope blocks are: +set of source lines; instead, it will always line up with one of these blocks. There are two main +types of scopes in Julia, *global scope* and *local scope*. The latter can be nested. There is also +a distinction in Julia between constructs which introduce a "hard scope" and those which only +introduce a "soft scope", which affects whether +[shadowing](https://en.wikipedia.org/wiki/Variable_shadowing) +a global variable by the same name is allowed or not. ### [Scope constructs](@id man-scope-table) -Construct | Scope type | Scope blocks it may be nested in ------------- | ------------- |--------------------------- -[`module`](@ref), [`baremodule`](@ref) | global | global -interactive prompt (REPL) | global | global -(mutable) [`struct`](@ref), [`macro`](@ref) | local | global -[`for`](@ref), [`while`](@ref), [`try-catch-finally`](@ref try), [`let`](@ref) |local | global or local -functions (either syntax, anonymous & do-blocks) | local | global or local -comprehensions, broadcast-fusing | local | global or local +The constructs introducing scope blocks are: + +| Construct | Scope type | Allowed within | +|:----------|:-----------|:---------------| +| [`module`](@ref), [`baremodule`](@ref) | global | global | +| [`struct`](@ref) | local (soft) | global | +| [`for`](@ref), [`while`](@ref), [`try`](@ref try) | local (soft) | global, local | +| [`macro`](@ref) | local (hard) | global | +| functions, [`do`](@ref) blocks, [`let`](@ref) blocks, comprehensions, generators | local (hard) | global, local | Notably missing from this table are [begin blocks](@ref man-compound-expressions) and [if blocks](@ref man-conditional-evaluation) which do *not* introduce new scopes. -Both types of scopes follow somewhat different rules which will be explained below. +The three types of scopes follow somewhat different rules which will be explained below. Julia uses [lexical scoping](https://en.wikipedia.org/wiki/Scope_%28computer_science%29#Lexical_scoping_vs._dynamic_scoping), meaning that a function's scope does not inherit from its caller's scope, but from the scope in @@ -52,15 +56,21 @@ julia> Bar.foo() 1 ``` -Thus *lexical scope* means that the scope of variables can be inferred from the source code alone. +Thus *lexical scope* means that what a variable in a particular piece of code refers to can be +deduced from the code in which it appears alone and does not depend on how the program executes. A +scope nested inside another scope can "see" variables in all the outer scopes in which it is +contained. Outer scopes, on the other hand, cannot see variables in inner scopes. ## Global Scope -Each module introduces a new global scope, separate from the global scope of all other modules; -there is no all-encompassing global scope. Modules can introduce variables of other modules into -their scope through the [using or import](@ref modules) statements or through qualified access using the -dot-notation, i.e. each module is a so-called *namespace*. Note that variable bindings can only -be changed within their global scope and not from an outside module. +Each module introduces a new global scope, separate from the global scope of all other modules—there +is no all-encompassing global scope. Modules can introduce variables of other modules into their +scope through the [using or import](@ref modules) statements or through qualified access using the +dot-notation, i.e. each module is a so-called *namespace* as well as a first-class data structure +associating names with values. Note that while variable bindings can be read externally, they can only +be changed within the module to which they belong. As an escape hatch, you can always evaluate code +inside that module to modify a variable; this guarantees, in particular, that module bindings cannot +be modified externally by code that never calls `eval`. ```jldoctest julia> module A @@ -93,249 +103,431 @@ Note that the interactive prompt (aka REPL) is in the global scope of the module ## Local Scope -A new local scope is introduced by most code blocks (see above -[table](@ref man-scope-table) for a complete list). -A local scope inherits all the variables from a parent local scope, -both for reading and writing. -Unlike global scopes, local scopes are not namespaces, -thus variables in an inner scope cannot be retrieved from the parent scope through some sort of -qualified access. - -The following rules and examples pertain to local scopes. -A newly introduced variable in a local scope cannot be referenced by a parent scope. -For example, here the ``z`` is not introduced into the top-level scope: +A new local scope is introduced by most code blocks (see above [table](@ref +man-scope-table) for a complete list). If such a block is syntactically nested +inside of another local scope, the scope it creates is nested inside of all the +local scopes that it appears within, which are all ultimately nested inside of +the global scope of the module in which the code is evaluated. Variables in +outer scopes are visible from any scope they contain — meaning that they can be +read and written in inner scopes — unless there is a local variable with the +same name that "shadows" the outer variable of the same name. This is true even +if the outer local is declared after (in the sense of textually below) an inner +block. When we say that a variable "exists" in a given scope, this means that a +variable by that name exists in any of the scopes that the current scope is +nested inside of, including the current one. + +Some programming languages require explicitly declaring new variables before +using them. Explicit declaration works in Julia too: in any local scope, writing +`local x` declares a new local variable in that scope, regardless of whether +there is already a variable named `x` in an outer scope or not. Declaring each +new variable like this is somewhat verbose and tedious, however, so Julia, like +many other languages, considers assignment to a variable name that doesn't +already exist to implicitly declare that variable. If the current scope is +global, the new variable is global; if the current scope is local, the new +variable is local to the innermost local scope and will be visible inside of +that scope but not outside of it. If you assign to an existing local, it +_always_ updates that existing local: you can only shadow a local by explicitly +declaring a new local in a nested scope with the `local` keyword. In particular, +this applies to variables assigned in inner functions, which may surprise users +coming from Python where assignment in an inner function creates a new local +unless the variable is explictly declared to be non-local. + +Mostly this is pretty intuitive, but as with many things that behave +intuitively, the details are more subtle than one might naïvely imagine. + +When `x = ` occurs in a local scope, Julia applies the following rules to decide what the +expression means based on where the assignment expression occurs and what `x` already refers to at +that location: + +1. **Existing local:** If `x` is *already a local variable*, then the existing local `x` is + assigned; +2. **Hard scope:** If `x` is *not already a local variable* and assignment occurs inside of any + hard scope construct (i.e. within a `let` block, function or macro body, comprehension, or + generator), a new local named `x` is created in the scope of the assignment; +3. **Soft scope:** If `x` is *not already a local variable* and all of the scope constructs + containing the assignment are soft scopes (loops, `try`/`catch` blocks, or `struct` blocks), the + behavior depends on whether the global variable `x` is defined: + * if global `x` is *undefined*, a new local named `x` is created in the scope of the + assignment; + * if global `x` is *defined*, the assignment is considered ambiguous: + * in *non-interactive* contexts (files, eval), an ambiguity warning is printed and a new + local is created; + * in *interactive* contexts (REPL, notebooks), the global variable `x` is assigned. + +You may note that in non-interactive contexts the hard and soft scope behaviors are identical except +that a warning is printed when an implicitly local variable (i.e. not declared with `local x`) +shadows a global. In interactive contexts, the rules follow a more complex heuristic for the sake of +convenience. This is covered in depth in examples that follow. + +Now that you know the rules, let's look at some examples. Each example is assumed to be evaluated in +a fresh REPL session so that the only globals in each snippet are the ones that are assigned in that +block of code. + +We'll begin with a nice and clear-cut situation—assignment inside of a hard scope, in this case a +function body, when no local variable by that name already exists: ```jldoctest -julia> for i = 1:10 - z = i +julia> function greet() + x = "hello" # new local + println(x) end +greet (generic function with 1 method) -julia> z -ERROR: UndefVarError: z not defined -``` +julia> greet() +hello -!!! note - In this and all following examples it is assumed that their top-level is a global scope - with a clean workspace, for instance a newly started REPL. +julia> x # global +ERROR: UndefVarError: x not defined +``` -Inner local scopes can, however, update variables in their parent scopes: +Inside of the `greet` function, the assignment `x = "hello"` causes `x` to be a new local variable +in the function's scope. There are two relevant facts: the assignment occurs in local scope and +there is no existing local `x` variable. Since `x` is local, it doesn't matter if there is a global +named `x` or not. Here for example we define `x = 123` before defining and calling `greet`: ```jldoctest -julia> for i = 1:1 - z = i - for j = 1:1 - z = 0 - end - println(z) +julia> x = 123 # global +123 + +julia> function greet() + x = "hello" # new local + println(x) end -0 +greet (generic function with 1 method) + +julia> greet() +hello + +julia> x # global +123 +``` + +Since the `x` in `greet` is local, the value (or lack thereof) of the global `x` is unaffected by +calling `greet`. The hard scope rule doesn't care whether a global named `x` exists or not: +assignment to `x` in a hard scope is local (unless `x` is declared global). + +The next clear cut situation we'll consider is when there is already a local +variable named `x`, in which case `x = ` always assigns to this existing +local `x`. This is true whether the assignment occurs in the same local scope, +an inner local scope in the same function body, or in the body of a function +nested inside of another function, also known as a +[closure](https://en.wikipedia.org/wiki/Closure_(computer_programming)). + +We'll use the `sum_to` function, which computes the sum of integers from one up +to `n`, as an example: + +```julia +function sum_to(n) + s = 0 # new local + for i = 1:n + s = s + i # assign existing local + end + return s # same local +end ``` -Inside a local scope a variable can be forced to be a new local variable using the [`local`](@ref) keyword: +As in the previous example, the first assignment to `s` at the top of `sum_to` causes `s` to be a +new local variable in the body of the function. The `for` loop has its own inner local scope within +the function scope. At the point where `s = s + i` occurs, `s` is already a local variable, so the +assignment updates the existing `s` instead of creating a new local. We can test this out by calling +`sum_to` in the REPL: ```jldoctest -julia> for i = 1:1 - x = i + 1 - for j = 1:1 - local x = 0 +julia> function sum_to(n) + s = 0 # new local + for i = 1:n + s = s + i # assign existing local end - println(x) + return s # same local end -2 +sum_to (generic function with 1 method) + +julia> sum_to(10) +55 + +julia> s # global +ERROR: UndefVarError: s not defined ``` -Inside a local scope a global variable can be assigned to by using the keyword [`global`](@ref): +Since `s` is local to the function `sum_to`, calling the function has no effect on the global +variable `s`. We can also see that the update `s = s + i` in the `for` loop must have updated the same +`s` created by the initialization `s = 0` since we get the correct sum of 55 for the integers 1 +through 10. + +Let's dig into the fact that the `for` loop body has its own scope for a second by writing a slightly +more verbose variation which we'll call `sum_to_def`, in which we save the sum `s + i` in a variable `t` +before updating `s`: ```jldoctest -julia> for i = 1:10 - global z - z = i +julia> function sum_to_def(n) + s = 0 # new local + for i = 1:n + t = s + i # new local `t` + s = t # assign existing local `s` + end + return s, @isdefined(t) end +sum_to_def (generic function with 1 method) -julia> z -10 +julia> sum_to_def(10) +(55, false) ``` -The location of both the `local` and `global` keywords within the scope block is irrelevant. -The following is equivalent to the last example (although stylistically worse): +This version returns `s` as before but it also uses the `@isdefined` macro to return a boolean +indicating whether there is a local variable named `t` defined in the function's outermost local +scope. As you can see, there is no `t` defined outside of the `for` loop body. This is because of the +hard scope rule again: since the assignment to `t` occurs inside of a function, which +introduces a hard scope, the assignment causes `t` to become a new local variable in the local scope +where it appears, i.e. inside of the loop body. Even if there were a global named `t`, it would make +no difference—the hard scope rule isn't affected by anything in global scope. + +Note that the local scope of a for loop body is no different from the local +scope of an inner function. This means that we could rewrite this example so +that the loop body is implemented as a call to an inner helper function and it +behaves the same way: ```jldoctest -julia> for i = 1:10 - z = i - global z +julia> function sum_to_def_closure(n) + function loop_body(i) + t = s + i # new local `t` + s = t # assign same local `s` as below + end + s = 0 # new local + for i = 1:n + loop_body(i) + end + return s, @isdefined(t) end +sum_to_def_closure (generic function with 1 method) -julia> z -10 +julia> sum_to_def_closure(10) +(55, false) ``` -The `local` and `global` keywords can also be applied to destructuring assignments, e.g. -`local x, y = 1, 2`. In this case the keyword affects all listed variables. +This example illustrates a couple of key points: -In a local scope, all variables are inherited from its parent -global scope block unless: +1. Inner function scopes are just like any other nested local scope. In + particular, if a variable is already a local outside of an inner function and + you assign to it in the inner function, the outer local variable is updated. - * an assignment would result in a modified *global* variable, or - * a variable is specifically marked with the keyword `local`. +2. It doesn't matter if the definition of an outer local happens below where it + is updated, the rule remains the same. The entire enclosing local scope is + parsed and its locals determined before inner local meanings are resolved. -Thus global variables are only inherited for reading, not for writing: +This design means that you can generally move code in or out of an inner +function without changing its meaning, which facilitates a number of common +idioms in the language using closures (see [do blocks](@ref +Do-Block-Syntax-for-Function-Arguments)). -```jldoctest -julia> x, y = 1, 2; +Let's move onto some more ambiguous cases covered by the soft scope rule. We'll explore this by +extracting the bodies of the `greet` and `sum_to_def` functions into soft scope contexts. First, let's put the +body of `greet` in a `for` loop—which is soft, rather than hard—and evaluate it in the REPL: -julia> function foo() - x = 2 # assignment introduces a new local - return x + y # y refers to the global - end; - -julia> foo() -4 +```jldoctest +julia> for i = 1:3 + x = "hello" # new local + println(x) + end +hello +hello +hello julia> x -1 +ERROR: UndefVarError: x not defined ``` -An explicit `global` is needed to assign to a global variable: - -!!! sidebar "Avoiding globals" - Avoiding changing the value of global variables is considered by many - to be a programming best-practice. - Changing the value of a global variable can cause "action at a distance", - making the behavior of a program harder to reason about. - This is why the scope blocks that introduce local scope require the `global` - keyword to declare the intent to modify a global variable. - -```jldoctest -julia> x = 1; - -julia> function foobar() - global x = 2 - end; - -julia> foobar(); - -julia> x -2 +Since the global `x` is not defined when the `for` loop is evaluated, the first clause of the soft +scope rule applies and `x` is created as local to the `for` loop and therefore global `x` remains +undefined after the loop executes. Next, let's consider the body of `sum_to_def` extracted into global +scope, fixing its argument to `n = 10` + +```julia +s = 0 +for i = 1:10 + t = s + i + s = t +end +s +@isdefined(t) ``` -Note that *nested functions* can modify their parent scope's *local* variables: +What does this code do? Hint: it's a trick question. The answer is "it depends." If this code is +entered interactively, it behaves the same way it does in a function body. But if the code appears +in a file, it prints an ambiguity warning and throws an undefined variable error. Let's see it +working in the REPL first: ```jldoctest -julia> x, y = 1, 2; +julia> s = 0 # global +0 -julia> function baz() - x = 2 # introduces a new local - function bar() - x = 10 # modifies the parent's x - return x + y # y is global - end - return bar() + x # 12 + 10 (x is modified in call of bar()) - end; +julia> for i = 1:10 + t = s + i # new local `t` + s = t # assign global `s` + end -julia> baz() -22 +julia> s # global +55 -julia> x, y # verify that global x and y are unchanged -(1, 2) +julia> @isdefined(t) # global +false ``` -The reason to allow modifying local variables of parent scopes in -nested functions is to allow constructing [`closures`](https://en.wikipedia.org/wiki/Closure_%28computer_programming%29) -which have private state, for instance the `state` variable in the -following example: +The REPL approximates being in the body of a function by deciding whether assignment inside the loop +assigns to a global or creates new local based on whether a global variable by that name is defined +or not. If a global by the name exists, then the assignment updates it. If no global exists, then +the assignment creates a new local variable. In this example we see both cases in action: -```jldoctest -julia> let state = 0 - global counter() = (state += 1) - end; +* There is no global named `t`, so `t = s + i` creates a new `t` that is local to the `for` loop; +* There is a global named `s`, so `s = t` assigns to it. -julia> counter() -1 +The second fact is why execution of the loop changes the global value of `s` and the first fact is +why `t` is still undefined after the loop executes. Now, let's try evaluating this same code as +though it were in a file instead: -julia> counter() -2 +```jldoctest +julia> code = """ + s = 0 # global + for i = 1:10 + t = s + i # new local `t` + s = t # new local `s` with warning + end + s, # global + @isdefined(t) # global + """; + +julia> include_string(Main, code) +┌ Warning: Assignment to `s` in soft scope is ambiguous because a global variable by the same name exists: `s` will be treated as a new local. Disambiguate by using `local s` to suppress this warning or `global s` to assign to the existing global variable. +└ @ string:4 +ERROR: LoadError: UndefVarError: s not defined ``` -See also the closures in the examples in the next two sections. A variable, -such as `x` in the first example and `state` in the second, that is inherited -from the enclosing scope by the inner function is sometimes called a -*captured* variable. Captured variables can present performance challenges -discussed in [performance tips](@ref man-performance-tips). +Here we use [`include_string`](@ref), to evaluate `code` as though it were the contents of a file. +We could also save `code` to a file and then call `include` on that file—the result would be the +same. As you can see, this behaves quite different from evaluating the same code in the REPL. Let's +break down what's happening here: + +* global `s` is defined with the value `0` before the loop is evaluated +* the assignment `s = t` occurs in a soft scope—a `for` loop outside of any function body or other hard + scope construct +* therefore the second clause of the soft scope rule applies, and the assignment is ambiguous so a + warning is emitted +* execution continues, making `s` local to the `for` loop body +* since `s` is local to the `for` loop, it is undefined when `t = s + i` is evaluated, causing an error +* evaluation stops there, but if it got to `s` and `@isdefined(t)`, it would return `0` and `false`. + +This demonstrates some important aspects of scope: in a scope, each variable can only have one +meaning, and that meaning is determined regardless of the order of expressions. The presence of the +expression `s = t` in the loop causes `s` to be local to the loop, which means that it is also local +when it appears on the right hand side of `t = s + i`, even though that expression appears first and is +evaluated first. One might imagine that the `s` on the first line of the loop could be global while +the `s` on the second line of the loop is local, but that's not possible since the two lines are in +the same scope block and each variable can only mean one thing in a given scope. + +#### On Soft Scope + +We have now covered all the local scope rules, but before wrapping up this section, perhaps a few +words should be said about why the ambiguous soft scope case is handled differently in interactive +and non-interactive contexts. There are two obvious questions one could ask: + +1. Why doesn't it just work like the REPL everywhere? +2. Why doesn't it just work like in files everywhere? And maybe skip the warning? + +In Julia ≤ 0.6, all global scopes did work like the current REPL: when `x = ` occurred in a +loop (or `try`/`catch`, or `struct` body) but outside of a function body (or `let` block or comprehension), +it was decided based on whether a global named `x` was defined or not whether `x` should be local to +the loop. This behavior has the advantage of being intuitive and convenient since it approximates +the behavior inside of a function body as closely as possible. In particular, it makes it easy to +move code back and forth between a function body and the REPL when trying to debug the behavior of a +function. However, it has some downsides. First, it's quite a complex behavior: many people over the +years were confused about this behavior and complained that it was complicated and hard both to +explain and understand. Fair point. Second, and arguably worse, is that it's bad for programming "at +scale." When you see a small piece of code in one place like this, it's quite clear what's going on: + +```julia +s = 0 +for i = 1:10 + s += i +end +``` -The distinction between inheriting global scope and nesting local scope -can lead to some slight differences between functions -defined in local versus global scopes for variable assignments. -Consider the modification of the last example by moving `bar` to the global scope: +Obviously the intention is to modify the existing global variable `s`. What else could it mean? +However, not all real world code is so short or so clear. We found that code like the following +often occurs in the wild: -```jldoctest -julia> x, y = 1, 2; +```julia +x = 123 -julia> function bar() - x = 10 # local, no longer a closure variable - return x + y - end; +# much later +# maybe in a different file -julia> function quz() - x = 2 # local - return bar() + x # 12 + 2 (x is not modified) - end; +for i = 1:10 + x = "hello" + println(x) +end -julia> quz() -14 +# much later +# maybe in yet another file +# or maybe back in the first one where `x = 123` -julia> x, y # verify that global x and y are unchanged -(1, 2) +y = x + 234 ``` -Note that the above nesting rules do not pertain to type and macro definitions as they can only appear -at the global scope. There are special scoping rules concerning the evaluation of default and -keyword function arguments which are described in the [Function section](@ref man-functions). - -An assignment introducing a variable used inside a function, type or macro definition need not -come before its inner usage: - -```jldoctest -julia> f = y -> y + a; - -julia> f(3) -ERROR: UndefVarError: a not defined -Stacktrace: -[...] - -julia> a = 1 -1 - -julia> f(3) -4 +It's far less clear what should happen here. Since `x + "hello"` is a method error, it seems +probable that the intention is for `x` to be local to the `for` loop. But runtime values and what +methods happen to exist cannot be used to determine the scopes of variables. With the Julia ≤ 0.6 +behavior, it's especially concerning that someone might have written the `for` loop first, had it +working just fine, but later when someone else adds a new global far away—possibly in a different +file—the code suddenly changes meaning and either breaks noisily or, worse still, silently does the +wrong thing. This kind of ["spooky action at a distance"](https://en.wikipedia.org/wiki/Action_at_a_distance_(computer_programming)) is something that good programming language +designs should prevent. + +So in Julia 1.0, we simplified the rules for scope: in any local scope, assignment to a name that +wasn't already a local variable created a new local variable. This eliminated the notion of soft +scope entirely as well as removing the potential for spooky action. We uncovered and fixed a significant number of bugs due to the removal of soft scope, vindicating the choice to get rid of it. +And there was much rejoicing! Well, no, not really. Because some people were +angry that they now had to write: + +```julia +s = 0 +for i = 1:10 + global s += i +end ``` -This behavior may seem slightly odd for a normal variable, but allows for named functions -- which -are just normal variables holding function objects -- to be used before they are defined. This -allows functions to be defined in whatever order is intuitive and convenient, rather than forcing -bottom up ordering or requiring forward declarations, as long as they are defined by the time -they are actually called. As an example, here is an inefficient, mutually recursive way to test -if positive integers are even or odd: +Do you see that `global` annotation in there? Hideous. Obviously this situation could not be +tolerated. But seriously, there are two main issues with requiring `global` for this kind of +top-level code: -```jldoctest -julia> even(n) = (n == 0) ? true : odd(n - 1); +1. It's no longer convenient to copy and paste the code from inside a function body into the REPL + to debug it—you have to add `global` annotations and then remove them again to go back; -julia> odd(n) = (n == 0) ? false : even(n - 1); +2. Beginners will write this kind of code without the `global` and have no idea why their code + doesn't work—the error that they get is that `s` is undefined, which does not seem to enlighten + anyone who happens to make this mistake. -julia> even(3) -false +As of Julia 1.5, this code works without the `global` annotation in interactive contexts like the +REPL or Jupyter notebooks (just like Julia 0.6) and in files and other non-interactive contexts, it +prints this very direct warning: -julia> odd(3) -true -``` +> Assignment to `s` in soft scope is ambiguous because a global variable by the same name exists: +> `s` will be treated as a new local. Disambiguate by using `local s` to suppress this warning or +> `global s` to assign to the existing global variable. + +This addresses both issues while preserving the "programming at scale" benefits of the 1.0 behavior: +global variables have no spooky effect on the meaning of code that may be far away; in the REPL +copy-and-paste debugging works and beginners don't have any issues; any time someone either forgets +a `global` annotation or accidentally shadows an existing global with a local in a soft scope, +which would be confusing anyway, they get a nice clear warning. -Julia provides built-in, efficient functions to test for oddness and evenness called [`iseven`](@ref) -and [`isodd`](@ref) so the above definitions should only be considered to be examples of scope, -not efficient design. +An important property of this design is that any code that executes in a file without a warning will +behave the same way in a fresh REPL. And on the flip side, if you take a REPL session and save it to +file, if it behaves differently than it did in the REPL, then you will get a warning. ### Let Blocks -Unlike assignments to local variables, `let` statements allocate new variable bindings each time -they run. An assignment modifies an existing value location, and `let` creates new locations. +`let` statements create a new *hard scope* block (see above) and introduce new variable +bindings each time they run. Whereas assignments might reassign a new value to an existing value location, +`let` always creates a new location. This difference is usually not important, and is only detectable in the case of variables that outlive their scope via closures. The `let` syntax accepts a comma-separated series of assignments and variable names: @@ -393,7 +585,7 @@ julia> Fs[2]() ``` Since the `begin` construct does not introduce a new scope, it can be useful to use a zero-argument -`let` to just introduce a new scope block without creating any new bindings: +`let` to just introduce a new scope block without creating any new bindings immediately: ```jldoctest julia> let @@ -407,13 +599,22 @@ julia> let ``` Since `let` introduces a new scope block, the inner local `x` is a different variable than the -outer local `x`. +outer local `x`. This particular example is equivalent to: + +```jldoctest +julia> let x = 1 + let x = 2 + end + x + end +1 +``` -### For Loops and Comprehensions +### Loops and Comprehensions -`for` loops, `while` loops, and [Comprehensions](@ref) have the following behavior: any new variables +In loops and [comprehensions](@ref man-comprehensions), new variables introduced in their body scopes are freshly allocated for each loop iteration, as if the loop body -were surrounded by a `let` block: +were surrounded by a `let` block, as demonstrated by this example: ```jldoctest julia> Fs = Vector{Any}(undef, 2); @@ -435,6 +636,7 @@ A `for` loop or comprehension iteration variable is always a new variable: julia> function f() i = 0 for i = 1:3 + # empty end return i end; @@ -450,6 +652,7 @@ This can be done conveniently by adding the keyword `outer`: julia> function f() i = 0 for outer i = 1:3 + # empty end return i end; @@ -505,7 +708,7 @@ julia> const y = 1.0 1.0 julia> y = 2.0 -WARNING: redefining constant y +WARNING: redefinition of constant y. This may fail, cause incorrect answers, or produce other errors. 2.0 ``` * if an assignment would not result in the change of variable value no message is given: @@ -516,7 +719,7 @@ julia> const z = 100 julia> z = 100 100 ``` -The last rule applies for immutable objects even if the variable binding would change, e.g.: +The last rule applies to immutable objects even if the variable binding would change, e.g.: ```julia-repl julia> const s1 = "1" "1" @@ -540,21 +743,20 @@ julia> pointer.([s1, s2], 1) However, for mutable objects the warning is printed as expected: ```jldoctest julia> const a = [1] -1-element Array{Int64,1}: +1-element Vector{Int64}: 1 julia> a = [1] -WARNING: redefining constant a -1-element Array{Int64,1}: +WARNING: redefinition of constant a. This may fail, cause incorrect answers, or produce other errors. +1-element Vector{Int64}: 1 ``` -Note that although sometimes possible, changing the value of a `const` variable -is strongly discouraged, and is intended only for convenience during -interactive use. -Changing constants can cause various problems or unexpected behaviors. -For instance, if a method references a constant and is already -compiled before the constant is changed then it might keep using the old value: +Note that although sometimes possible, changing the value of a `const` variable is strongly +discouraged, and is intended only for convenience during interactive use. Changing constants can +cause various problems or unexpected behaviors. For instance, if a method references a constant and +is already compiled before the constant is changed, then it might keep using the old value: + ```jldoctest julia> const x = 1 1 @@ -566,7 +768,7 @@ julia> f() 1 julia> x = 2 -WARNING: redefining constant x +WARNING: redefinition of constant x. This may fail, cause incorrect answers, or produce other errors. 2 julia> f() From 02e15b050c52512467a9897443315d4aa15e0d6b Mon Sep 17 00:00:00 2001 From: WooKyoung Noh Date: Tue, 27 Apr 2021 00:35:24 +0900 Subject: [PATCH 153/153] update UnicodeData.txt, added codex, src stdlib/Artifacts, stdlib/Downloads.md, stdlib/LazyArtifacts.md, stdlib/SuiteSparse.md, stdlib/TOML.md remove src/NEWS.md --- UnicodeData.txt | 3323 ++++++++++++++++++++++++++++++++- codex/stdlib/Artifacts.md | 21 + codex/stdlib/Downloads.md | 9 + codex/stdlib/LazyArtifacts.md | 10 + codex/stdlib/SuiteSparse.md | 34 + codex/stdlib/TOML.md | 132 ++ make.jl | 6 +- src/NEWS.md | 109 -- src/assets/custom.css | 4 + src/stdlib/Artifacts.md | 21 + src/stdlib/Downloads.md | 9 + src/stdlib/LazyArtifacts.md | 10 + src/stdlib/SuiteSparse.md | 34 + src/stdlib/TOML.md | 132 ++ 14 files changed, 3683 insertions(+), 171 deletions(-) create mode 100644 codex/stdlib/Artifacts.md create mode 100644 codex/stdlib/Downloads.md create mode 100644 codex/stdlib/LazyArtifacts.md create mode 100644 codex/stdlib/SuiteSparse.md create mode 100644 codex/stdlib/TOML.md delete mode 100644 src/NEWS.md create mode 100644 src/stdlib/Artifacts.md create mode 100644 src/stdlib/Downloads.md create mode 100644 src/stdlib/LazyArtifacts.md create mode 100644 src/stdlib/SuiteSparse.md create mode 100644 src/stdlib/TOML.md diff --git a/UnicodeData.txt b/UnicodeData.txt index a756976..e22f967 100644 --- a/UnicodeData.txt +++ b/UnicodeData.txt @@ -640,7 +640,7 @@ 027F;LATIN SMALL LETTER REVERSED R WITH FISHHOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED FISHHOOK R;;;; 0280;LATIN LETTER SMALL CAPITAL R;Ll;0;L;;;;;N;;;01A6;;01A6 0281;LATIN LETTER SMALL CAPITAL INVERTED R;Ll;0;L;;;;;N;;;;; -0282;LATIN SMALL LETTER S WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER S HOOK;;;; +0282;LATIN SMALL LETTER S WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER S HOOK;;A7C5;;A7C5 0283;LATIN SMALL LETTER ESH;Ll;0;L;;;;;N;;;01A9;;01A9 0284;LATIN SMALL LETTER DOTLESS J WITH STROKE AND HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER DOTLESS J BAR HOOK;;;; 0285;LATIN SMALL LETTER SQUAT REVERSED ESH;Ll;0;L;;;;;N;;;;; @@ -1362,6 +1362,7 @@ 055D;ARMENIAN COMMA;Po;0;L;;;;;N;;;;; 055E;ARMENIAN QUESTION MARK;Po;0;L;;;;;N;;;;; 055F;ARMENIAN ABBREVIATION MARK;Po;0;L;;;;;N;;;;; +0560;ARMENIAN SMALL LETTER TURNED AYB;Ll;0;L;;;;;N;;;;; 0561;ARMENIAN SMALL LETTER AYB;Ll;0;L;;;;;N;;;0531;;0531 0562;ARMENIAN SMALL LETTER BEN;Ll;0;L;;;;;N;;;0532;;0532 0563;ARMENIAN SMALL LETTER GIM;Ll;0;L;;;;;N;;;0533;;0533 @@ -1401,6 +1402,7 @@ 0585;ARMENIAN SMALL LETTER OH;Ll;0;L;;;;;N;;;0555;;0555 0586;ARMENIAN SMALL LETTER FEH;Ll;0;L;;;;;N;;;0556;;0556 0587;ARMENIAN SMALL LIGATURE ECH YIWN;Ll;0;L; 0565 0582;;;;N;;;;; +0588;ARMENIAN SMALL LETTER YI WITH STROKE;Ll;0;L;;;;;N;;;;; 0589;ARMENIAN FULL STOP;Po;0;L;;;;;N;ARMENIAN PERIOD;;;; 058A;ARMENIAN HYPHEN;Pd;0;ON;;;;;N;;;;; 058D;RIGHT-FACING ARMENIAN ETERNITY SIGN;So;0;ON;;;;;N;;;;; @@ -1488,6 +1490,7 @@ 05E8;HEBREW LETTER RESH;Lo;0;R;;;;;N;;;;; 05E9;HEBREW LETTER SHIN;Lo;0;R;;;;;N;;;;; 05EA;HEBREW LETTER TAV;Lo;0;R;;;;;N;;;;; +05EF;HEBREW YOD TRIANGLE;Lo;0;R;;;;;N;;;;; 05F0;HEBREW LIGATURE YIDDISH DOUBLE VAV;Lo;0;R;;;;;N;HEBREW LETTER DOUBLE VAV;;;; 05F1;HEBREW LIGATURE YIDDISH VAV YOD;Lo;0;R;;;;;N;HEBREW LETTER VAV YOD;;;; 05F2;HEBREW LIGATURE YIDDISH DOUBLE YOD;Lo;0;R;;;;;N;HEBREW LETTER DOUBLE YOD;;;; @@ -1982,6 +1985,9 @@ 07F8;NKO COMMA;Po;0;ON;;;;;N;;;;; 07F9;NKO EXCLAMATION MARK;Po;0;ON;;;;;N;;;;; 07FA;NKO LAJANYALAN;Lm;0;R;;;;;N;;;;; +07FD;NKO DANTAYALAN;Mn;220;NSM;;;;;N;;;;; +07FE;NKO DOROME SIGN;Sc;0;R;;;;;N;;;;; +07FF;NKO TAMAN SIGN;Sc;0;R;;;;;N;;;;; 0800;SAMARITAN LETTER ALAF;Lo;0;R;;;;;N;;;;; 0801;SAMARITAN LETTER BIT;Lo;0;R;;;;;N;;;;; 0802;SAMARITAN LETTER GAMAN;Lo;0;R;;;;;N;;;;; @@ -2072,6 +2078,17 @@ 085A;MANDAIC VOCALIZATION MARK;Mn;220;NSM;;;;;N;;;;; 085B;MANDAIC GEMINATION MARK;Mn;220;NSM;;;;;N;;;;; 085E;MANDAIC PUNCTUATION;Po;0;R;;;;;N;;;;; +0860;SYRIAC LETTER MALAYALAM NGA;Lo;0;AL;;;;;N;;;;; +0861;SYRIAC LETTER MALAYALAM JA;Lo;0;AL;;;;;N;;;;; +0862;SYRIAC LETTER MALAYALAM NYA;Lo;0;AL;;;;;N;;;;; +0863;SYRIAC LETTER MALAYALAM TTA;Lo;0;AL;;;;;N;;;;; +0864;SYRIAC LETTER MALAYALAM NNA;Lo;0;AL;;;;;N;;;;; +0865;SYRIAC LETTER MALAYALAM NNNA;Lo;0;AL;;;;;N;;;;; +0866;SYRIAC LETTER MALAYALAM BHA;Lo;0;AL;;;;;N;;;;; +0867;SYRIAC LETTER MALAYALAM RA;Lo;0;AL;;;;;N;;;;; +0868;SYRIAC LETTER MALAYALAM LLA;Lo;0;AL;;;;;N;;;;; +0869;SYRIAC LETTER MALAYALAM LLLA;Lo;0;AL;;;;;N;;;;; +086A;SYRIAC LETTER MALAYALAM SSA;Lo;0;AL;;;;;N;;;;; 08A0;ARABIC LETTER BEH WITH SMALL V BELOW;Lo;0;AL;;;;;N;;;;; 08A1;ARABIC LETTER BEH WITH HAMZA ABOVE;Lo;0;AL;;;;;N;;;;; 08A2;ARABIC LETTER JEEM WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;; @@ -2101,6 +2118,17 @@ 08BB;ARABIC LETTER AFRICAN FEH;Lo;0;AL;;;;;N;;;;; 08BC;ARABIC LETTER AFRICAN QAF;Lo;0;AL;;;;;N;;;;; 08BD;ARABIC LETTER AFRICAN NOON;Lo;0;AL;;;;;N;;;;; +08BE;ARABIC LETTER PEH WITH SMALL V;Lo;0;AL;;;;;N;;;;; +08BF;ARABIC LETTER TEH WITH SMALL V;Lo;0;AL;;;;;N;;;;; +08C0;ARABIC LETTER TTEH WITH SMALL V;Lo;0;AL;;;;;N;;;;; +08C1;ARABIC LETTER TCHEH WITH SMALL V;Lo;0;AL;;;;;N;;;;; +08C2;ARABIC LETTER KEHEH WITH SMALL V;Lo;0;AL;;;;;N;;;;; +08C3;ARABIC LETTER GHAIN WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +08C4;ARABIC LETTER AFRICAN QAF WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +08C5;ARABIC LETTER JEEM WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;; +08C6;ARABIC LETTER JEEM WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;; +08C7;ARABIC LETTER LAM WITH SMALL ARABIC LETTER TAH ABOVE;Lo;0;AL;;;;;N;;;;; +08D3;ARABIC SMALL LOW WAW;Mn;220;NSM;;;;;N;;;;; 08D4;ARABIC SMALL HIGH WORD AR-RUB;Mn;230;NSM;;;;;N;;;;; 08D5;ARABIC SMALL HIGH SAD;Mn;230;NSM;;;;;N;;;;; 08D6;ARABIC SMALL HIGH AIN;Mn;230;NSM;;;;;N;;;;; @@ -2366,6 +2394,9 @@ 09F9;BENGALI CURRENCY DENOMINATOR SIXTEEN;No;0;L;;;;16;N;;;;; 09FA;BENGALI ISSHAR;So;0;L;;;;;N;;;;; 09FB;BENGALI GANDA MARK;Sc;0;ET;;;;;N;;;;; +09FC;BENGALI LETTER VEDIC ANUSVARA;Lo;0;L;;;;;N;;;;; +09FD;BENGALI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;; +09FE;BENGALI SANDHI MARK;Mn;230;NSM;;;;;N;;;;; 0A01;GURMUKHI SIGN ADAK BINDI;Mn;0;NSM;;;;;N;;;;; 0A02;GURMUKHI SIGN BINDI;Mn;0;NSM;;;;;N;;;;; 0A03;GURMUKHI SIGN VISARGA;Mc;0;L;;;;;N;;;;; @@ -2445,6 +2476,7 @@ 0A73;GURMUKHI URA;Lo;0;L;;;;;N;;;;; 0A74;GURMUKHI EK ONKAR;Lo;0;L;;;;;N;;;;; 0A75;GURMUKHI SIGN YAKASH;Mn;0;NSM;;;;;N;;;;; +0A76;GURMUKHI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;; 0A81;GUJARATI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; 0A82;GUJARATI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; 0A83;GUJARATI SIGN VISARGA;Mc;0;L;;;;;N;;;;; @@ -2530,6 +2562,12 @@ 0AF0;GUJARATI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;; 0AF1;GUJARATI RUPEE SIGN;Sc;0;ET;;;;;N;;;;; 0AF9;GUJARATI LETTER ZHA;Lo;0;L;;;;;N;;;;; +0AFA;GUJARATI SIGN SUKUN;Mn;0;NSM;;;;;N;;;;; +0AFB;GUJARATI SIGN SHADDA;Mn;0;NSM;;;;;N;;;;; +0AFC;GUJARATI SIGN MADDAH;Mn;0;NSM;;;;;N;;;;; +0AFD;GUJARATI SIGN THREE-DOT NUKTA ABOVE;Mn;0;NSM;;;;;N;;;;; +0AFE;GUJARATI SIGN CIRCLE NUKTA ABOVE;Mn;0;NSM;;;;;N;;;;; +0AFF;GUJARATI SIGN TWO-CIRCLE NUKTA ABOVE;Mn;0;NSM;;;;;N;;;;; 0B01;ORIYA SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; 0B02;ORIYA SIGN ANUSVARA;Mc;0;L;;;;;N;;;;; 0B03;ORIYA SIGN VISARGA;Mc;0;L;;;;;N;;;;; @@ -2593,6 +2631,7 @@ 0B4B;ORIYA VOWEL SIGN O;Mc;0;L;0B47 0B3E;;;;N;;;;; 0B4C;ORIYA VOWEL SIGN AU;Mc;0;L;0B47 0B57;;;;N;;;;; 0B4D;ORIYA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +0B55;ORIYA SIGN OVERLINE;Mn;0;NSM;;;;;N;;;;; 0B56;ORIYA AI LENGTH MARK;Mn;0;NSM;;;;;N;;;;; 0B57;ORIYA AU LENGTH MARK;Mc;0;L;;;;;N;;;;; 0B5C;ORIYA LETTER RRA;Lo;0;L;0B21 0B3C;;;;N;;;;; @@ -2696,6 +2735,7 @@ 0C01;TELUGU SIGN CANDRABINDU;Mc;0;L;;;;;N;;;;; 0C02;TELUGU SIGN ANUSVARA;Mc;0;L;;;;;N;;;;; 0C03;TELUGU SIGN VISARGA;Mc;0;L;;;;;N;;;;; +0C04;TELUGU SIGN COMBINING ANUSVARA ABOVE;Mn;0;NSM;;;;;N;;;;; 0C05;TELUGU LETTER A;Lo;0;L;;;;;N;;;;; 0C06;TELUGU LETTER AA;Lo;0;L;;;;;N;;;;; 0C07;TELUGU LETTER I;Lo;0;L;;;;;N;;;;; @@ -2780,6 +2820,7 @@ 0C6D;TELUGU DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; 0C6E;TELUGU DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; 0C6F;TELUGU DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +0C77;TELUGU SIGN SIDDHAM;Po;0;L;;;;;N;;;;; 0C78;TELUGU FRACTION DIGIT ZERO FOR ODD POWERS OF FOUR;No;0;ON;;;;0;N;;;;; 0C79;TELUGU FRACTION DIGIT ONE FOR ODD POWERS OF FOUR;No;0;ON;;;;1;N;;;;; 0C7A;TELUGU FRACTION DIGIT TWO FOR ODD POWERS OF FOUR;No;0;ON;;;;2;N;;;;; @@ -2792,6 +2833,7 @@ 0C81;KANNADA SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; 0C82;KANNADA SIGN ANUSVARA;Mc;0;L;;;;;N;;;;; 0C83;KANNADA SIGN VISARGA;Mc;0;L;;;;;N;;;;; +0C84;KANNADA SIGN SIDDHAM;Po;0;L;;;;;N;;;;; 0C85;KANNADA LETTER A;Lo;0;L;;;;;N;;;;; 0C86;KANNADA LETTER AA;Lo;0;L;;;;;N;;;;; 0C87;KANNADA LETTER I;Lo;0;L;;;;;N;;;;; @@ -2876,9 +2918,11 @@ 0CEF;KANNADA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; 0CF1;KANNADA SIGN JIHVAMULIYA;Lo;0;L;;;;;N;;;;; 0CF2;KANNADA SIGN UPADHMANIYA;Lo;0;L;;;;;N;;;;; +0D00;MALAYALAM SIGN COMBINING ANUSVARA ABOVE;Mn;0;NSM;;;;;N;;;;; 0D01;MALAYALAM SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; 0D02;MALAYALAM SIGN ANUSVARA;Mc;0;L;;;;;N;;;;; 0D03;MALAYALAM SIGN VISARGA;Mc;0;L;;;;;N;;;;; +0D04;MALAYALAM LETTER VEDIC ANUSVARA;Lo;0;L;;;;;N;;;;; 0D05;MALAYALAM LETTER A;Lo;0;L;;;;;N;;;;; 0D06;MALAYALAM LETTER AA;Lo;0;L;;;;;N;;;;; 0D07;MALAYALAM LETTER I;Lo;0;L;;;;;N;;;;; @@ -2931,6 +2975,8 @@ 0D38;MALAYALAM LETTER SA;Lo;0;L;;;;;N;;;;; 0D39;MALAYALAM LETTER HA;Lo;0;L;;;;;N;;;;; 0D3A;MALAYALAM LETTER TTTA;Lo;0;L;;;;;N;;;;; +0D3B;MALAYALAM SIGN VERTICAL BAR VIRAMA;Mn;9;NSM;;;;;N;;;;; +0D3C;MALAYALAM SIGN CIRCULAR VIRAMA;Mn;9;NSM;;;;;N;;;;; 0D3D;MALAYALAM SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;; 0D3E;MALAYALAM VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; 0D3F;MALAYALAM VOWEL SIGN I;Mc;0;L;;;;;N;;;;; @@ -2990,6 +3036,7 @@ 0D7D;MALAYALAM LETTER CHILLU L;Lo;0;L;;;;;N;;;;; 0D7E;MALAYALAM LETTER CHILLU LL;Lo;0;L;;;;;N;;;;; 0D7F;MALAYALAM LETTER CHILLU K;Lo;0;L;;;;;N;;;;; +0D81;SINHALA SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; 0D82;SINHALA SIGN ANUSVARAYA;Mc;0;L;;;;;N;;;;; 0D83;SINHALA SIGN VISARGAYA;Mc;0;L;;;;;N;;;;; 0D85;SINHALA LETTER AYANNA;Lo;0;L;;;;;N;;;;; @@ -3170,14 +3217,24 @@ 0E81;LAO LETTER KO;Lo;0;L;;;;;N;;;;; 0E82;LAO LETTER KHO SUNG;Lo;0;L;;;;;N;;;;; 0E84;LAO LETTER KHO TAM;Lo;0;L;;;;;N;;;;; +0E86;LAO LETTER PALI GHA;Lo;0;L;;;;;N;;;;; 0E87;LAO LETTER NGO;Lo;0;L;;;;;N;;;;; 0E88;LAO LETTER CO;Lo;0;L;;;;;N;;;;; +0E89;LAO LETTER PALI CHA;Lo;0;L;;;;;N;;;;; 0E8A;LAO LETTER SO TAM;Lo;0;L;;;;;N;;;;; +0E8C;LAO LETTER PALI JHA;Lo;0;L;;;;;N;;;;; 0E8D;LAO LETTER NYO;Lo;0;L;;;;;N;;;;; +0E8E;LAO LETTER PALI NYA;Lo;0;L;;;;;N;;;;; +0E8F;LAO LETTER PALI TTA;Lo;0;L;;;;;N;;;;; +0E90;LAO LETTER PALI TTHA;Lo;0;L;;;;;N;;;;; +0E91;LAO LETTER PALI DDA;Lo;0;L;;;;;N;;;;; +0E92;LAO LETTER PALI DDHA;Lo;0;L;;;;;N;;;;; +0E93;LAO LETTER PALI NNA;Lo;0;L;;;;;N;;;;; 0E94;LAO LETTER DO;Lo;0;L;;;;;N;;;;; 0E95;LAO LETTER TO;Lo;0;L;;;;;N;;;;; 0E96;LAO LETTER THO SUNG;Lo;0;L;;;;;N;;;;; 0E97;LAO LETTER THO TAM;Lo;0;L;;;;;N;;;;; +0E98;LAO LETTER PALI DHA;Lo;0;L;;;;;N;;;;; 0E99;LAO LETTER NO;Lo;0;L;;;;;N;;;;; 0E9A;LAO LETTER BO;Lo;0;L;;;;;N;;;;; 0E9B;LAO LETTER PO;Lo;0;L;;;;;N;;;;; @@ -3185,13 +3242,17 @@ 0E9D;LAO LETTER FO TAM;Lo;0;L;;;;;N;;;;; 0E9E;LAO LETTER PHO TAM;Lo;0;L;;;;;N;;;;; 0E9F;LAO LETTER FO SUNG;Lo;0;L;;;;;N;;;;; +0EA0;LAO LETTER PALI BHA;Lo;0;L;;;;;N;;;;; 0EA1;LAO LETTER MO;Lo;0;L;;;;;N;;;;; 0EA2;LAO LETTER YO;Lo;0;L;;;;;N;;;;; 0EA3;LAO LETTER LO LING;Lo;0;L;;;;;N;;;;; 0EA5;LAO LETTER LO LOOT;Lo;0;L;;;;;N;;;;; 0EA7;LAO LETTER WO;Lo;0;L;;;;;N;;;;; +0EA8;LAO LETTER SANSKRIT SHA;Lo;0;L;;;;;N;;;;; +0EA9;LAO LETTER SANSKRIT SSA;Lo;0;L;;;;;N;;;;; 0EAA;LAO LETTER SO SUNG;Lo;0;L;;;;;N;;;;; 0EAB;LAO LETTER HO SUNG;Lo;0;L;;;;;N;;;;; +0EAC;LAO LETTER PALI LLA;Lo;0;L;;;;;N;;;;; 0EAD;LAO LETTER O;Lo;0;L;;;;;N;;;;; 0EAE;LAO LETTER HO TAM;Lo;0;L;;;;;N;;;;; 0EAF;LAO ELLIPSIS;Lo;0;L;;;;;N;;;;; @@ -3205,6 +3266,7 @@ 0EB7;LAO VOWEL SIGN YY;Mn;0;NSM;;;;;N;;;;; 0EB8;LAO VOWEL SIGN U;Mn;118;NSM;;;;;N;;;;; 0EB9;LAO VOWEL SIGN UU;Mn;118;NSM;;;;;N;;;;; +0EBA;LAO SIGN PALI VIRAMA;Mn;9;NSM;;;;;N;;;;; 0EBB;LAO VOWEL SIGN MAI KON;Mn;0;NSM;;;;;N;;;;; 0EBC;LAO SEMIVOWEL SIGN LO;Mn;0;NSM;;;;;N;;;;; 0EBD;LAO SEMIVOWEL SIGN NYO;Lo;0;L;;;;;N;;;;; @@ -3645,54 +3707,54 @@ 10C5;GEORGIAN CAPITAL LETTER HOE;Lu;0;L;;;;;N;;;;2D25; 10C7;GEORGIAN CAPITAL LETTER YN;Lu;0;L;;;;;N;;;;2D27; 10CD;GEORGIAN CAPITAL LETTER AEN;Lu;0;L;;;;;N;;;;2D2D; -10D0;GEORGIAN LETTER AN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER AN;;;; -10D1;GEORGIAN LETTER BAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER BAN;;;; -10D2;GEORGIAN LETTER GAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER GAN;;;; -10D3;GEORGIAN LETTER DON;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER DON;;;; -10D4;GEORGIAN LETTER EN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER EN;;;; -10D5;GEORGIAN LETTER VIN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER VIN;;;; -10D6;GEORGIAN LETTER ZEN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER ZEN;;;; -10D7;GEORGIAN LETTER TAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER TAN;;;; -10D8;GEORGIAN LETTER IN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER IN;;;; -10D9;GEORGIAN LETTER KAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER KAN;;;; -10DA;GEORGIAN LETTER LAS;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER LAS;;;; -10DB;GEORGIAN LETTER MAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER MAN;;;; -10DC;GEORGIAN LETTER NAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER NAR;;;; -10DD;GEORGIAN LETTER ON;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER ON;;;; -10DE;GEORGIAN LETTER PAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER PAR;;;; -10DF;GEORGIAN LETTER ZHAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER ZHAR;;;; -10E0;GEORGIAN LETTER RAE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER RAE;;;; -10E1;GEORGIAN LETTER SAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER SAN;;;; -10E2;GEORGIAN LETTER TAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER TAR;;;; -10E3;GEORGIAN LETTER UN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER UN;;;; -10E4;GEORGIAN LETTER PHAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER PHAR;;;; -10E5;GEORGIAN LETTER KHAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER KHAR;;;; -10E6;GEORGIAN LETTER GHAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER GHAN;;;; -10E7;GEORGIAN LETTER QAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER QAR;;;; -10E8;GEORGIAN LETTER SHIN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER SHIN;;;; -10E9;GEORGIAN LETTER CHIN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER CHIN;;;; -10EA;GEORGIAN LETTER CAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER CAN;;;; -10EB;GEORGIAN LETTER JIL;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER JIL;;;; -10EC;GEORGIAN LETTER CIL;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER CIL;;;; -10ED;GEORGIAN LETTER CHAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER CHAR;;;; -10EE;GEORGIAN LETTER XAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER XAN;;;; -10EF;GEORGIAN LETTER JHAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER JHAN;;;; -10F0;GEORGIAN LETTER HAE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HAE;;;; -10F1;GEORGIAN LETTER HE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HE;;;; -10F2;GEORGIAN LETTER HIE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HIE;;;; -10F3;GEORGIAN LETTER WE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER WE;;;; -10F4;GEORGIAN LETTER HAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HAR;;;; -10F5;GEORGIAN LETTER HOE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HOE;;;; -10F6;GEORGIAN LETTER FI;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER FI;;;; -10F7;GEORGIAN LETTER YN;Lo;0;L;;;;;N;;;;; -10F8;GEORGIAN LETTER ELIFI;Lo;0;L;;;;;N;;;;; -10F9;GEORGIAN LETTER TURNED GAN;Lo;0;L;;;;;N;;;;; -10FA;GEORGIAN LETTER AIN;Lo;0;L;;;;;N;;;;; +10D0;GEORGIAN LETTER AN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER AN;;1C90;;10D0 +10D1;GEORGIAN LETTER BAN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER BAN;;1C91;;10D1 +10D2;GEORGIAN LETTER GAN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER GAN;;1C92;;10D2 +10D3;GEORGIAN LETTER DON;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER DON;;1C93;;10D3 +10D4;GEORGIAN LETTER EN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER EN;;1C94;;10D4 +10D5;GEORGIAN LETTER VIN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER VIN;;1C95;;10D5 +10D6;GEORGIAN LETTER ZEN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER ZEN;;1C96;;10D6 +10D7;GEORGIAN LETTER TAN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER TAN;;1C97;;10D7 +10D8;GEORGIAN LETTER IN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER IN;;1C98;;10D8 +10D9;GEORGIAN LETTER KAN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER KAN;;1C99;;10D9 +10DA;GEORGIAN LETTER LAS;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER LAS;;1C9A;;10DA +10DB;GEORGIAN LETTER MAN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER MAN;;1C9B;;10DB +10DC;GEORGIAN LETTER NAR;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER NAR;;1C9C;;10DC +10DD;GEORGIAN LETTER ON;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER ON;;1C9D;;10DD +10DE;GEORGIAN LETTER PAR;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER PAR;;1C9E;;10DE +10DF;GEORGIAN LETTER ZHAR;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER ZHAR;;1C9F;;10DF +10E0;GEORGIAN LETTER RAE;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER RAE;;1CA0;;10E0 +10E1;GEORGIAN LETTER SAN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER SAN;;1CA1;;10E1 +10E2;GEORGIAN LETTER TAR;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER TAR;;1CA2;;10E2 +10E3;GEORGIAN LETTER UN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER UN;;1CA3;;10E3 +10E4;GEORGIAN LETTER PHAR;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER PHAR;;1CA4;;10E4 +10E5;GEORGIAN LETTER KHAR;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER KHAR;;1CA5;;10E5 +10E6;GEORGIAN LETTER GHAN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER GHAN;;1CA6;;10E6 +10E7;GEORGIAN LETTER QAR;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER QAR;;1CA7;;10E7 +10E8;GEORGIAN LETTER SHIN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER SHIN;;1CA8;;10E8 +10E9;GEORGIAN LETTER CHIN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER CHIN;;1CA9;;10E9 +10EA;GEORGIAN LETTER CAN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER CAN;;1CAA;;10EA +10EB;GEORGIAN LETTER JIL;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER JIL;;1CAB;;10EB +10EC;GEORGIAN LETTER CIL;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER CIL;;1CAC;;10EC +10ED;GEORGIAN LETTER CHAR;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER CHAR;;1CAD;;10ED +10EE;GEORGIAN LETTER XAN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER XAN;;1CAE;;10EE +10EF;GEORGIAN LETTER JHAN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER JHAN;;1CAF;;10EF +10F0;GEORGIAN LETTER HAE;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER HAE;;1CB0;;10F0 +10F1;GEORGIAN LETTER HE;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER HE;;1CB1;;10F1 +10F2;GEORGIAN LETTER HIE;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER HIE;;1CB2;;10F2 +10F3;GEORGIAN LETTER WE;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER WE;;1CB3;;10F3 +10F4;GEORGIAN LETTER HAR;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER HAR;;1CB4;;10F4 +10F5;GEORGIAN LETTER HOE;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER HOE;;1CB5;;10F5 +10F6;GEORGIAN LETTER FI;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER FI;;1CB6;;10F6 +10F7;GEORGIAN LETTER YN;Ll;0;L;;;;;N;;;1CB7;;10F7 +10F8;GEORGIAN LETTER ELIFI;Ll;0;L;;;;;N;;;1CB8;;10F8 +10F9;GEORGIAN LETTER TURNED GAN;Ll;0;L;;;;;N;;;1CB9;;10F9 +10FA;GEORGIAN LETTER AIN;Ll;0;L;;;;;N;;;1CBA;;10FA 10FB;GEORGIAN PARAGRAPH SEPARATOR;Po;0;L;;;;;N;;;;; 10FC;MODIFIER LETTER GEORGIAN NAR;Lm;0;L; 10DC;;;;N;;;;; -10FD;GEORGIAN LETTER AEN;Lo;0;L;;;;;N;;;;; -10FE;GEORGIAN LETTER HARD SIGN;Lo;0;L;;;;;N;;;;; -10FF;GEORGIAN LETTER LABIAL SIGN;Lo;0;L;;;;;N;;;;; +10FD;GEORGIAN LETTER AEN;Ll;0;L;;;;;N;;;1CBD;;10FD +10FE;GEORGIAN LETTER HARD SIGN;Ll;0;L;;;;;N;;;1CBE;;10FE +10FF;GEORGIAN LETTER LABIAL SIGN;Ll;0;L;;;;;N;;;1CBF;;10FF 1100;HANGUL CHOSEONG KIYEOK;Lo;0;L;;;;;N;;;;; 1101;HANGUL CHOSEONG SSANGKIYEOK;Lo;0;L;;;;;N;;;;; 1102;HANGUL CHOSEONG NIEUN;Lo;0;L;;;;;N;;;;; @@ -5046,7 +5108,7 @@ 166A;CANADIAN SYLLABICS CARRIER TTSEE;Lo;0;L;;;;;N;;;;; 166B;CANADIAN SYLLABICS CARRIER TTSI;Lo;0;L;;;;;N;;;;; 166C;CANADIAN SYLLABICS CARRIER TTSA;Lo;0;L;;;;;N;;;;; -166D;CANADIAN SYLLABICS CHI SIGN;Po;0;L;;;;;N;;;;; +166D;CANADIAN SYLLABICS CHI SIGN;So;0;L;;;;;N;;;;; 166E;CANADIAN SYLLABICS FULL STOP;Po;0;L;;;;;N;;;;; 166F;CANADIAN SYLLABICS QAI;Lo;0;L;;;;;N;;;;; 1670;CANADIAN SYLLABICS NGAI;Lo;0;L;;;;;N;;;;; @@ -5491,6 +5553,7 @@ 1875;MONGOLIAN LETTER MANCHU RA;Lo;0;L;;;;;N;;;;; 1876;MONGOLIAN LETTER MANCHU FA;Lo;0;L;;;;;N;;;;; 1877;MONGOLIAN LETTER MANCHU ZHA;Lo;0;L;;;;;N;;;;; +1878;MONGOLIAN LETTER CHA WITH TWO DOTS;Lo;0;L;;;;;N;;;;; 1880;MONGOLIAN LETTER ALI GALI ANUSVARA ONE;Lo;0;L;;;;;N;;;;; 1881;MONGOLIAN LETTER ALI GALI VISARGA ONE;Lo;0;L;;;;;N;;;;; 1882;MONGOLIAN LETTER ALI GALI DAMARU;Lo;0;L;;;;;N;;;;; @@ -5994,6 +6057,8 @@ 1ABC;COMBINING DOUBLE PARENTHESES ABOVE;Mn;230;NSM;;;;;N;;;;; 1ABD;COMBINING PARENTHESES BELOW;Mn;220;NSM;;;;;N;;;;; 1ABE;COMBINING PARENTHESES OVERLAY;Me;0;NSM;;;;;N;;;;; +1ABF;COMBINING LATIN SMALL LETTER W BELOW;Mn;220;NSM;;;;;N;;;;; +1AC0;COMBINING LATIN SMALL LETTER TURNED W BELOW;Mn;220;NSM;;;;;N;;;;; 1B00;BALINESE SIGN ULU RICEM;Mn;0;NSM;;;;;N;;;;; 1B01;BALINESE SIGN ULU CANDRA;Mn;0;NSM;;;;;N;;;;; 1B02;BALINESE SIGN CECEK;Mn;0;NSM;;;;;N;;;;; @@ -6366,6 +6431,52 @@ 1C86;CYRILLIC SMALL LETTER TALL HARD SIGN;Ll;0;L;;;;;N;;;042A;;042A 1C87;CYRILLIC SMALL LETTER TALL YAT;Ll;0;L;;;;;N;;;0462;;0462 1C88;CYRILLIC SMALL LETTER UNBLENDED UK;Ll;0;L;;;;;N;;;A64A;;A64A +1C90;GEORGIAN MTAVRULI CAPITAL LETTER AN;Lu;0;L;;;;;N;;;;10D0; +1C91;GEORGIAN MTAVRULI CAPITAL LETTER BAN;Lu;0;L;;;;;N;;;;10D1; +1C92;GEORGIAN MTAVRULI CAPITAL LETTER GAN;Lu;0;L;;;;;N;;;;10D2; +1C93;GEORGIAN MTAVRULI CAPITAL LETTER DON;Lu;0;L;;;;;N;;;;10D3; +1C94;GEORGIAN MTAVRULI CAPITAL LETTER EN;Lu;0;L;;;;;N;;;;10D4; +1C95;GEORGIAN MTAVRULI CAPITAL LETTER VIN;Lu;0;L;;;;;N;;;;10D5; +1C96;GEORGIAN MTAVRULI CAPITAL LETTER ZEN;Lu;0;L;;;;;N;;;;10D6; +1C97;GEORGIAN MTAVRULI CAPITAL LETTER TAN;Lu;0;L;;;;;N;;;;10D7; +1C98;GEORGIAN MTAVRULI CAPITAL LETTER IN;Lu;0;L;;;;;N;;;;10D8; +1C99;GEORGIAN MTAVRULI CAPITAL LETTER KAN;Lu;0;L;;;;;N;;;;10D9; +1C9A;GEORGIAN MTAVRULI CAPITAL LETTER LAS;Lu;0;L;;;;;N;;;;10DA; +1C9B;GEORGIAN MTAVRULI CAPITAL LETTER MAN;Lu;0;L;;;;;N;;;;10DB; +1C9C;GEORGIAN MTAVRULI CAPITAL LETTER NAR;Lu;0;L;;;;;N;;;;10DC; +1C9D;GEORGIAN MTAVRULI CAPITAL LETTER ON;Lu;0;L;;;;;N;;;;10DD; +1C9E;GEORGIAN MTAVRULI CAPITAL LETTER PAR;Lu;0;L;;;;;N;;;;10DE; +1C9F;GEORGIAN MTAVRULI CAPITAL LETTER ZHAR;Lu;0;L;;;;;N;;;;10DF; +1CA0;GEORGIAN MTAVRULI CAPITAL LETTER RAE;Lu;0;L;;;;;N;;;;10E0; +1CA1;GEORGIAN MTAVRULI CAPITAL LETTER SAN;Lu;0;L;;;;;N;;;;10E1; +1CA2;GEORGIAN MTAVRULI CAPITAL LETTER TAR;Lu;0;L;;;;;N;;;;10E2; +1CA3;GEORGIAN MTAVRULI CAPITAL LETTER UN;Lu;0;L;;;;;N;;;;10E3; +1CA4;GEORGIAN MTAVRULI CAPITAL LETTER PHAR;Lu;0;L;;;;;N;;;;10E4; +1CA5;GEORGIAN MTAVRULI CAPITAL LETTER KHAR;Lu;0;L;;;;;N;;;;10E5; +1CA6;GEORGIAN MTAVRULI CAPITAL LETTER GHAN;Lu;0;L;;;;;N;;;;10E6; +1CA7;GEORGIAN MTAVRULI CAPITAL LETTER QAR;Lu;0;L;;;;;N;;;;10E7; +1CA8;GEORGIAN MTAVRULI CAPITAL LETTER SHIN;Lu;0;L;;;;;N;;;;10E8; +1CA9;GEORGIAN MTAVRULI CAPITAL LETTER CHIN;Lu;0;L;;;;;N;;;;10E9; +1CAA;GEORGIAN MTAVRULI CAPITAL LETTER CAN;Lu;0;L;;;;;N;;;;10EA; +1CAB;GEORGIAN MTAVRULI CAPITAL LETTER JIL;Lu;0;L;;;;;N;;;;10EB; +1CAC;GEORGIAN MTAVRULI CAPITAL LETTER CIL;Lu;0;L;;;;;N;;;;10EC; +1CAD;GEORGIAN MTAVRULI CAPITAL LETTER CHAR;Lu;0;L;;;;;N;;;;10ED; +1CAE;GEORGIAN MTAVRULI CAPITAL LETTER XAN;Lu;0;L;;;;;N;;;;10EE; +1CAF;GEORGIAN MTAVRULI CAPITAL LETTER JHAN;Lu;0;L;;;;;N;;;;10EF; +1CB0;GEORGIAN MTAVRULI CAPITAL LETTER HAE;Lu;0;L;;;;;N;;;;10F0; +1CB1;GEORGIAN MTAVRULI CAPITAL LETTER HE;Lu;0;L;;;;;N;;;;10F1; +1CB2;GEORGIAN MTAVRULI CAPITAL LETTER HIE;Lu;0;L;;;;;N;;;;10F2; +1CB3;GEORGIAN MTAVRULI CAPITAL LETTER WE;Lu;0;L;;;;;N;;;;10F3; +1CB4;GEORGIAN MTAVRULI CAPITAL LETTER HAR;Lu;0;L;;;;;N;;;;10F4; +1CB5;GEORGIAN MTAVRULI CAPITAL LETTER HOE;Lu;0;L;;;;;N;;;;10F5; +1CB6;GEORGIAN MTAVRULI CAPITAL LETTER FI;Lu;0;L;;;;;N;;;;10F6; +1CB7;GEORGIAN MTAVRULI CAPITAL LETTER YN;Lu;0;L;;;;;N;;;;10F7; +1CB8;GEORGIAN MTAVRULI CAPITAL LETTER ELIFI;Lu;0;L;;;;;N;;;;10F8; +1CB9;GEORGIAN MTAVRULI CAPITAL LETTER TURNED GAN;Lu;0;L;;;;;N;;;;10F9; +1CBA;GEORGIAN MTAVRULI CAPITAL LETTER AIN;Lu;0;L;;;;;N;;;;10FA; +1CBD;GEORGIAN MTAVRULI CAPITAL LETTER AEN;Lu;0;L;;;;;N;;;;10FD; +1CBE;GEORGIAN MTAVRULI CAPITAL LETTER HARD SIGN;Lu;0;L;;;;;N;;;;10FE; +1CBF;GEORGIAN MTAVRULI CAPITAL LETTER LABIAL SIGN;Lu;0;L;;;;;N;;;;10FF; 1CC0;SUNDANESE PUNCTUATION BINDU SURYA;Po;0;L;;;;;N;;;;; 1CC1;SUNDANESE PUNCTUATION BINDU PANGLONG;Po;0;L;;;;;N;;;;; 1CC2;SUNDANESE PUNCTUATION BINDU PURNAMA;Po;0;L;;;;;N;;;;; @@ -6408,13 +6519,15 @@ 1CEF;VEDIC SIGN LONG ANUSVARA;Lo;0;L;;;;;N;;;;; 1CF0;VEDIC SIGN RTHANG LONG ANUSVARA;Lo;0;L;;;;;N;;;;; 1CF1;VEDIC SIGN ANUSVARA UBHAYATO MUKHA;Lo;0;L;;;;;N;;;;; -1CF2;VEDIC SIGN ARDHAVISARGA;Mc;0;L;;;;;N;;;;; -1CF3;VEDIC SIGN ROTATED ARDHAVISARGA;Mc;0;L;;;;;N;;;;; +1CF2;VEDIC SIGN ARDHAVISARGA;Lo;0;L;;;;;N;;;;; +1CF3;VEDIC SIGN ROTATED ARDHAVISARGA;Lo;0;L;;;;;N;;;;; 1CF4;VEDIC TONE CANDRA ABOVE;Mn;230;NSM;;;;;N;;;;; 1CF5;VEDIC SIGN JIHVAMULIYA;Lo;0;L;;;;;N;;;;; 1CF6;VEDIC SIGN UPADHMANIYA;Lo;0;L;;;;;N;;;;; +1CF7;VEDIC SIGN ATIKRAMA;Mc;0;L;;;;;N;;;;; 1CF8;VEDIC TONE RING ABOVE;Mn;230;NSM;;;;;N;;;;; 1CF9;VEDIC TONE DOUBLE RING ABOVE;Mn;230;NSM;;;;;N;;;;; +1CFA;VEDIC SIGN DOUBLE ANUSVARA ANTARGOMUKHA;Lo;0;L;;;;;N;;;;; 1D00;LATIN LETTER SMALL CAPITAL A;Ll;0;L;;;;;N;;;;; 1D01;LATIN LETTER SMALL CAPITAL AE;Ll;0;L;;;;;N;;;;; 1D02;LATIN SMALL LETTER TURNED AE;Ll;0;L;;;;;N;;;;; @@ -6557,7 +6670,7 @@ 1D8B;LATIN SMALL LETTER ESH WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; 1D8C;LATIN SMALL LETTER V WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; 1D8D;LATIN SMALL LETTER X WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; -1D8E;LATIN SMALL LETTER Z WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +1D8E;LATIN SMALL LETTER Z WITH PALATAL HOOK;Ll;0;L;;;;;N;;;A7C6;;A7C6 1D8F;LATIN SMALL LETTER A WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; 1D90;LATIN SMALL LETTER ALPHA WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; 1D91;LATIN SMALL LETTER D WITH HOOK AND TAIL;Ll;0;L;;;;;N;;;;; @@ -6661,6 +6774,10 @@ 1DF3;COMBINING LATIN SMALL LETTER O WITH DIAERESIS;Mn;230;NSM;;;;;N;;;;; 1DF4;COMBINING LATIN SMALL LETTER U WITH DIAERESIS;Mn;230;NSM;;;;;N;;;;; 1DF5;COMBINING UP TACK ABOVE;Mn;230;NSM;;;;;N;;;;; +1DF6;COMBINING KAVYKA ABOVE RIGHT;Mn;232;NSM;;;;;N;;;;; +1DF7;COMBINING KAVYKA ABOVE LEFT;Mn;228;NSM;;;;;N;;;;; +1DF8;COMBINING DOT ABOVE LEFT;Mn;228;NSM;;;;;N;;;;; +1DF9;COMBINING WIDE INVERTED BRIDGE BELOW;Mn;220;NSM;;;;;N;;;;; 1DFB;COMBINING DELETION MARK;Mn;230;NSM;;;;;N;;;;; 1DFC;COMBINING DOUBLE INVERTED BREVE BELOW;Mn;233;NSM;;;;;N;;;;; 1DFD;COMBINING ALMOST EQUAL TO BELOW;Mn;220;NSM;;;;;N;;;;; @@ -7339,6 +7456,7 @@ 20BC;MANAT SIGN;Sc;0;ET;;;;;N;;;;; 20BD;RUBLE SIGN;Sc;0;ET;;;;;N;;;;; 20BE;LARI SIGN;Sc;0;ET;;;;;N;;;;; +20BF;BITCOIN SIGN;Sc;0;ET;;;;;N;;;;; 20D0;COMBINING LEFT HARPOON ABOVE;Mn;230;NSM;;;;;N;NON-SPACING LEFT HARPOON ABOVE;;;; 20D1;COMBINING RIGHT HARPOON ABOVE;Mn;230;NSM;;;;;N;NON-SPACING RIGHT HARPOON ABOVE;;;; 20D2;COMBINING LONG VERTICAL LINE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING LONG VERTICAL BAR OVERLAY;;;; @@ -8135,6 +8253,7 @@ 23FC;POWER ON-OFF SYMBOL;So;0;ON;;;;;N;;;;; 23FD;POWER ON SYMBOL;So;0;ON;;;;;N;;;;; 23FE;POWER SLEEP SYMBOL;So;0;ON;;;;;N;;;;; +23FF;OBSERVER EYE SYMBOL;So;0;ON;;;;;N;;;;; 2400;SYMBOL FOR NULL;So;0;ON;;;;;N;GRAPHIC FOR NULL;;;; 2401;SYMBOL FOR START OF HEADING;So;0;ON;;;;;N;GRAPHIC FOR START OF HEADING;;;; 2402;SYMBOL FOR START OF TEXT;So;0;ON;;;;;N;GRAPHIC FOR START OF TEXT;;;; @@ -9530,7 +9649,7 @@ 299E;ANGLE WITH S INSIDE;Sm;0;ON;;;;;Y;;;;; 299F;ACUTE ANGLE;Sm;0;ON;;;;;Y;;;;; 29A0;SPHERICAL ANGLE OPENING LEFT;Sm;0;ON;;;;;Y;;;;; -29A1;SPHERICAL ANGLE OPENING UP;Sm;0;ON;;;;;Y;;;;; +29A1;SPHERICAL ANGLE OPENING UP;Sm;0;ON;;;;;N;;;;; 29A2;TURNED ANGLE;Sm;0;ON;;;;;Y;;;;; 29A3;REVERSED ANGLE;Sm;0;ON;;;;;Y;;;;; 29A4;ANGLE WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;; @@ -10029,6 +10148,7 @@ 2B93;NEWLINE RIGHT;So;0;ON;;;;;N;;;;; 2B94;FOUR CORNER ARROWS CIRCLING ANTICLOCKWISE;So;0;ON;;;;;N;;;;; 2B95;RIGHTWARDS BLACK ARROW;So;0;ON;;;;;N;;;;; +2B97;SYMBOL FOR TYPE A ELECTRONICS;So;0;ON;;;;;N;;;;; 2B98;THREE-D TOP-LIGHTED LEFTWARDS EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;; 2B99;THREE-D RIGHT-LIGHTED UPWARDS EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;; 2B9A;THREE-D TOP-LIGHTED RIGHTWARDS EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;; @@ -10063,6 +10183,9 @@ 2BB7;RIBBON ARROW RIGHT DOWN;So;0;ON;;;;;N;;;;; 2BB8;UPWARDS WHITE ARROW FROM BAR WITH HORIZONTAL BAR;So;0;ON;;;;;N;;;;; 2BB9;UP ARROWHEAD IN A RECTANGLE BOX;So;0;ON;;;;;N;;;;; +2BBA;OVERLAPPING WHITE SQUARES;So;0;ON;;;;;N;;;;; +2BBB;OVERLAPPING WHITE AND BLACK SQUARES;So;0;ON;;;;;N;;;;; +2BBC;OVERLAPPING BLACK SQUARES;So;0;ON;;;;;N;;;;; 2BBD;BALLOT BOX WITH LIGHT X;So;0;ON;;;;;N;;;;; 2BBE;CIRCLED X;So;0;ON;;;;;N;;;;; 2BBF;CIRCLED BOLD X;So;0;ON;;;;;N;;;;; @@ -10075,6 +10198,7 @@ 2BC6;BLACK MEDIUM DOWN-POINTING TRIANGLE CENTRED;So;0;ON;;;;;N;;;;; 2BC7;BLACK MEDIUM LEFT-POINTING TRIANGLE CENTRED;So;0;ON;;;;;N;;;;; 2BC8;BLACK MEDIUM RIGHT-POINTING TRIANGLE CENTRED;So;0;ON;;;;;N;;;;; +2BC9;NEPTUNE FORM TWO;So;0;ON;;;;;N;;;;; 2BCA;TOP HALF BLACK CIRCLE;So;0;ON;;;;;N;;;;; 2BCB;BOTTOM HALF BLACK CIRCLE;So;0;ON;;;;;N;;;;; 2BCC;LIGHT FOUR POINTED BLACK CUSP;So;0;ON;;;;;N;;;;; @@ -10083,10 +10207,52 @@ 2BCF;ROTATED WHITE FOUR POINTED CUSP;So;0;ON;;;;;N;;;;; 2BD0;SQUARE POSITION INDICATOR;So;0;ON;;;;;N;;;;; 2BD1;UNCERTAINTY SIGN;So;0;ON;;;;;N;;;;; +2BD2;GROUP MARK;So;0;ON;;;;;N;;;;; +2BD3;PLUTO FORM TWO;So;0;ON;;;;;N;;;;; +2BD4;PLUTO FORM THREE;So;0;ON;;;;;N;;;;; +2BD5;PLUTO FORM FOUR;So;0;ON;;;;;N;;;;; +2BD6;PLUTO FORM FIVE;So;0;ON;;;;;N;;;;; +2BD7;TRANSPLUTO;So;0;ON;;;;;N;;;;; +2BD8;PROSERPINA;So;0;ON;;;;;N;;;;; +2BD9;ASTRAEA;So;0;ON;;;;;N;;;;; +2BDA;HYGIEA;So;0;ON;;;;;N;;;;; +2BDB;PHOLUS;So;0;ON;;;;;N;;;;; +2BDC;NESSUS;So;0;ON;;;;;N;;;;; +2BDD;WHITE MOON SELENA;So;0;ON;;;;;N;;;;; +2BDE;BLACK DIAMOND ON CROSS;So;0;ON;;;;;N;;;;; +2BDF;TRUE LIGHT MOON ARTA;So;0;ON;;;;;N;;;;; +2BE0;CUPIDO;So;0;ON;;;;;N;;;;; +2BE1;HADES;So;0;ON;;;;;N;;;;; +2BE2;ZEUS;So;0;ON;;;;;N;;;;; +2BE3;KRONOS;So;0;ON;;;;;N;;;;; +2BE4;APOLLON;So;0;ON;;;;;N;;;;; +2BE5;ADMETOS;So;0;ON;;;;;N;;;;; +2BE6;VULCANUS;So;0;ON;;;;;N;;;;; +2BE7;POSEIDON;So;0;ON;;;;;N;;;;; +2BE8;LEFT HALF BLACK STAR;So;0;ON;;;;;N;;;;; +2BE9;RIGHT HALF BLACK STAR;So;0;ON;;;;;N;;;;; +2BEA;STAR WITH LEFT HALF BLACK;So;0;ON;;;;;N;;;;; +2BEB;STAR WITH RIGHT HALF BLACK;So;0;ON;;;;;N;;;;; 2BEC;LEFTWARDS TWO-HEADED ARROW WITH TRIANGLE ARROWHEADS;So;0;ON;;;;;N;;;;; 2BED;UPWARDS TWO-HEADED ARROW WITH TRIANGLE ARROWHEADS;So;0;ON;;;;;N;;;;; 2BEE;RIGHTWARDS TWO-HEADED ARROW WITH TRIANGLE ARROWHEADS;So;0;ON;;;;;N;;;;; 2BEF;DOWNWARDS TWO-HEADED ARROW WITH TRIANGLE ARROWHEADS;So;0;ON;;;;;N;;;;; +2BF0;ERIS FORM ONE;So;0;ON;;;;;N;;;;; +2BF1;ERIS FORM TWO;So;0;ON;;;;;N;;;;; +2BF2;SEDNA;So;0;ON;;;;;N;;;;; +2BF3;RUSSIAN ASTROLOGICAL SYMBOL VIGINTILE;So;0;ON;;;;;N;;;;; +2BF4;RUSSIAN ASTROLOGICAL SYMBOL NOVILE;So;0;ON;;;;;N;;;;; +2BF5;RUSSIAN ASTROLOGICAL SYMBOL QUINTILE;So;0;ON;;;;;N;;;;; +2BF6;RUSSIAN ASTROLOGICAL SYMBOL BINOVILE;So;0;ON;;;;;N;;;;; +2BF7;RUSSIAN ASTROLOGICAL SYMBOL SENTAGON;So;0;ON;;;;;N;;;;; +2BF8;RUSSIAN ASTROLOGICAL SYMBOL TREDECILE;So;0;ON;;;;;N;;;;; +2BF9;EQUALS SIGN WITH INFINITY BELOW;So;0;ON;;;;;N;;;;; +2BFA;UNITED SYMBOL;So;0;ON;;;;;N;;;;; +2BFB;SEPARATED SYMBOL;So;0;ON;;;;;N;;;;; +2BFC;DOUBLED SYMBOL;So;0;ON;;;;;N;;;;; +2BFD;PASSED SYMBOL;So;0;ON;;;;;N;;;;; +2BFE;REVERSED RIGHT ANGLE;So;0;ON;;;;;Y;;;;; +2BFF;HELLSCHREIBER PAUSE SYMBOL;So;0;ON;;;;;N;;;;; 2C00;GLAGOLITIC CAPITAL LETTER AZU;Lu;0;L;;;;;N;;;;2C30; 2C01;GLAGOLITIC CAPITAL LETTER BUKY;Lu;0;L;;;;;N;;;;2C31; 2C02;GLAGOLITIC CAPITAL LETTER VEDE;Lu;0;L;;;;;N;;;;2C32; @@ -10615,6 +10781,20 @@ 2E42;DOUBLE LOW-REVERSED-9 QUOTATION MARK;Ps;0;ON;;;;;N;;;;; 2E43;DASH WITH LEFT UPTURN;Po;0;ON;;;;;N;;;;; 2E44;DOUBLE SUSPENSION MARK;Po;0;ON;;;;;N;;;;; +2E45;INVERTED LOW KAVYKA;Po;0;ON;;;;;N;;;;; +2E46;INVERTED LOW KAVYKA WITH KAVYKA ABOVE;Po;0;ON;;;;;N;;;;; +2E47;LOW KAVYKA;Po;0;ON;;;;;N;;;;; +2E48;LOW KAVYKA WITH DOT;Po;0;ON;;;;;N;;;;; +2E49;DOUBLE STACKED COMMA;Po;0;ON;;;;;N;;;;; +2E4A;DOTTED SOLIDUS;Po;0;ON;;;;;N;;;;; +2E4B;TRIPLE DAGGER;Po;0;ON;;;;;N;;;;; +2E4C;MEDIEVAL COMMA;Po;0;ON;;;;;N;;;;; +2E4D;PARAGRAPHUS MARK;Po;0;ON;;;;;N;;;;; +2E4E;PUNCTUS ELEVATUS MARK;Po;0;ON;;;;;N;;;;; +2E4F;CORNISH VERSE DIVIDER;Po;0;ON;;;;;N;;;;; +2E50;CROSS PATTY WITH RIGHT CROSSBAR;So;0;ON;;;;;N;;;;; +2E51;CROSS PATTY WITH LEFT CROSSBAR;So;0;ON;;;;;N;;;;; +2E52;TIRONIAN SIGN CAPITAL ET;Po;0;ON;;;;;N;;;;; 2E80;CJK RADICAL REPEAT;So;0;ON;;;;;N;;;;; 2E81;CJK RADICAL CLIFF;So;0;ON;;;;;N;;;;; 2E82;CJK RADICAL SECOND ONE;So;0;ON;;;;;N;;;;; @@ -11250,6 +11430,8 @@ 312B;BOPOMOFO LETTER NG;Lo;0;L;;;;;N;;;;; 312C;BOPOMOFO LETTER GN;Lo;0;L;;;;;N;;;;; 312D;BOPOMOFO LETTER IH;Lo;0;L;;;;;N;;;;; +312E;BOPOMOFO LETTER O WITH DOT ABOVE;Lo;0;L;;;;;N;;;;; +312F;BOPOMOFO LETTER NN;Lo;0;L;;;;;N;;;;; 3131;HANGUL LETTER KIYEOK;Lo;0;L; 1100;;;;N;HANGUL LETTER GIYEOG;;;; 3132;HANGUL LETTER SSANGKIYEOK;Lo;0;L; 1101;;;;N;HANGUL LETTER SSANG GIYEOG;;;; 3133;HANGUL LETTER KIYEOK-SIOS;Lo;0;L; 11AA;;;;N;HANGUL LETTER GIYEOG SIOS;;;; @@ -11387,6 +11569,11 @@ 31B8;BOPOMOFO LETTER GH;Lo;0;L;;;;;N;;;;; 31B9;BOPOMOFO LETTER LH;Lo;0;L;;;;;N;;;;; 31BA;BOPOMOFO LETTER ZY;Lo;0;L;;;;;N;;;;; +31BB;BOPOMOFO FINAL LETTER G;Lo;0;L;;;;;N;;;;; +31BC;BOPOMOFO LETTER GW;Lo;0;L;;;;;N;;;;; +31BD;BOPOMOFO LETTER KW;Lo;0;L;;;;;N;;;;; +31BE;BOPOMOFO LETTER OE;Lo;0;L;;;;;N;;;;; +31BF;BOPOMOFO LETTER AH;Lo;0;L;;;;;N;;;;; 31C0;CJK STROKE T;So;0;ON;;;;;N;;;;; 31C1;CJK STROKE WG;So;0;ON;;;;;N;;;;; 31C2;CJK STROKE XG;So;0;ON;;;;;N;;;;; @@ -11693,6 +11880,7 @@ 32FC;CIRCLED KATAKANA WI;So;0;L; 30F0;;;;N;;;;; 32FD;CIRCLED KATAKANA WE;So;0;L; 30F1;;;;N;;;;; 32FE;CIRCLED KATAKANA WO;So;0;L; 30F2;;;;N;;;;; +32FF;SQUARE ERA NAME REIWA;So;0;L; 4EE4 548C;;;;N;;;;; 3300;SQUARE APAATO;So;0;L; 30A2 30D1 30FC 30C8;;;;N;SQUARED APAATO;;;; 3301;SQUARE ARUHUA;So;0;L; 30A2 30EB 30D5 30A1;;;;N;SQUARED ARUHUA;;;; 3302;SQUARE ANPEA;So;0;L; 30A2 30F3 30DA 30A2;;;;N;SQUARED ANPEA;;;; @@ -11950,7 +12138,7 @@ 33FE;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTY-ONE;So;0;L; 0033 0031 65E5;;;;N;;;;; 33FF;SQUARE GAL;So;0;ON; 0067 0061 006C;;;;N;;;;; 3400;;Lo;0;L;;;;;N;;;;; -4DB5;;Lo;0;L;;;;;N;;;;; +4DBF;;Lo;0;L;;;;;N;;;;; 4DC0;HEXAGRAM FOR THE CREATIVE HEAVEN;So;0;ON;;;;;N;;;;; 4DC1;HEXAGRAM FOR THE RECEPTIVE EARTH;So;0;ON;;;;;N;;;;; 4DC2;HEXAGRAM FOR DIFFICULTY AT THE BEGINNING;So;0;ON;;;;;N;;;;; @@ -12016,7 +12204,7 @@ 4DFE;HEXAGRAM FOR AFTER COMPLETION;So;0;ON;;;;;N;;;;; 4DFF;HEXAGRAM FOR BEFORE COMPLETION;So;0;ON;;;;;N;;;;; 4E00;;Lo;0;L;;;;;N;;;;; -9FD5;;Lo;0;L;;;;;N;;;;; +9FFC;;Lo;0;L;;;;;N;;;;; A000;YI SYLLABLE IT;Lo;0;L;;;;;N;;;;; A001;YI SYLLABLE IX;Lo;0;L;;;;;N;;;;; A002;YI SYLLABLE I;Lo;0;L;;;;;N;;;;; @@ -13917,7 +14105,7 @@ A790;LATIN CAPITAL LETTER N WITH DESCENDER;Lu;0;L;;;;;N;;;;A791; A791;LATIN SMALL LETTER N WITH DESCENDER;Ll;0;L;;;;;N;;;A790;;A790 A792;LATIN CAPITAL LETTER C WITH BAR;Lu;0;L;;;;;N;;;;A793; A793;LATIN SMALL LETTER C WITH BAR;Ll;0;L;;;;;N;;;A792;;A792 -A794;LATIN SMALL LETTER C WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; +A794;LATIN SMALL LETTER C WITH PALATAL HOOK;Ll;0;L;;;;;N;;;A7C4;;A7C4 A795;LATIN SMALL LETTER H WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;; A796;LATIN CAPITAL LETTER B WITH FLOURISH;Lu;0;L;;;;;N;;;;A797; A797;LATIN SMALL LETTER B WITH FLOURISH;Ll;0;L;;;;;N;;;A796;;A796 @@ -13944,6 +14132,7 @@ A7AB;LATIN CAPITAL LETTER REVERSED OPEN E;Lu;0;L;;;;;N;;;;025C; A7AC;LATIN CAPITAL LETTER SCRIPT G;Lu;0;L;;;;;N;;;;0261; A7AD;LATIN CAPITAL LETTER L WITH BELT;Lu;0;L;;;;;N;;;;026C; A7AE;LATIN CAPITAL LETTER SMALL CAPITAL I;Lu;0;L;;;;;N;;;;026A; +A7AF;LATIN LETTER SMALL CAPITAL Q;Ll;0;L;;;;;N;;;;; A7B0;LATIN CAPITAL LETTER TURNED K;Lu;0;L;;;;;N;;;;029E; A7B1;LATIN CAPITAL LETTER TURNED T;Lu;0;L;;;;;N;;;;0287; A7B2;LATIN CAPITAL LETTER J WITH CROSSED-TAIL;Lu;0;L;;;;;N;;;;029D; @@ -13952,6 +14141,25 @@ A7B4;LATIN CAPITAL LETTER BETA;Lu;0;L;;;;;N;;;;A7B5; A7B5;LATIN SMALL LETTER BETA;Ll;0;L;;;;;N;;;A7B4;;A7B4 A7B6;LATIN CAPITAL LETTER OMEGA;Lu;0;L;;;;;N;;;;A7B7; A7B7;LATIN SMALL LETTER OMEGA;Ll;0;L;;;;;N;;;A7B6;;A7B6 +A7B8;LATIN CAPITAL LETTER U WITH STROKE;Lu;0;L;;;;;N;;;;A7B9; +A7B9;LATIN SMALL LETTER U WITH STROKE;Ll;0;L;;;;;N;;;A7B8;;A7B8 +A7BA;LATIN CAPITAL LETTER GLOTTAL A;Lu;0;L;;;;;N;;;;A7BB; +A7BB;LATIN SMALL LETTER GLOTTAL A;Ll;0;L;;;;;N;;;A7BA;;A7BA +A7BC;LATIN CAPITAL LETTER GLOTTAL I;Lu;0;L;;;;;N;;;;A7BD; +A7BD;LATIN SMALL LETTER GLOTTAL I;Ll;0;L;;;;;N;;;A7BC;;A7BC +A7BE;LATIN CAPITAL LETTER GLOTTAL U;Lu;0;L;;;;;N;;;;A7BF; +A7BF;LATIN SMALL LETTER GLOTTAL U;Ll;0;L;;;;;N;;;A7BE;;A7BE +A7C2;LATIN CAPITAL LETTER ANGLICANA W;Lu;0;L;;;;;N;;;;A7C3; +A7C3;LATIN SMALL LETTER ANGLICANA W;Ll;0;L;;;;;N;;;A7C2;;A7C2 +A7C4;LATIN CAPITAL LETTER C WITH PALATAL HOOK;Lu;0;L;;;;;N;;;;A794; +A7C5;LATIN CAPITAL LETTER S WITH HOOK;Lu;0;L;;;;;N;;;;0282; +A7C6;LATIN CAPITAL LETTER Z WITH PALATAL HOOK;Lu;0;L;;;;;N;;;;1D8E; +A7C7;LATIN CAPITAL LETTER D WITH SHORT STROKE OVERLAY;Lu;0;L;;;;;N;;;;A7C8; +A7C8;LATIN SMALL LETTER D WITH SHORT STROKE OVERLAY;Ll;0;L;;;;;N;;;A7C7;;A7C7 +A7C9;LATIN CAPITAL LETTER S WITH SHORT STROKE OVERLAY;Lu;0;L;;;;;N;;;;A7CA; +A7CA;LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY;Ll;0;L;;;;;N;;;A7C9;;A7C9 +A7F5;LATIN CAPITAL LETTER REVERSED HALF H;Lu;0;L;;;;;N;;;;A7F6; +A7F6;LATIN SMALL LETTER REVERSED HALF H;Ll;0;L;;;;;N;;;A7F5;;A7F5 A7F7;LATIN EPIGRAPHIC LETTER SIDEWAYS I;Lo;0;L;;;;;N;;;;; A7F8;MODIFIER LETTER CAPITAL H WITH STROKE;Lm;0;L; 0126;;;;N;;;;; A7F9;MODIFIER LETTER SMALL LIGATURE OE;Lm;0;L; 0153;;;;N;;;;; @@ -14005,6 +14213,7 @@ A828;SYLOTI NAGRI POETRY MARK-1;So;0;ON;;;;;N;;;;; A829;SYLOTI NAGRI POETRY MARK-2;So;0;ON;;;;;N;;;;; A82A;SYLOTI NAGRI POETRY MARK-3;So;0;ON;;;;;N;;;;; A82B;SYLOTI NAGRI POETRY MARK-4;So;0;ON;;;;;N;;;;; +A82C;SYLOTI NAGRI SIGN ALTERNATE HASANTA;Mn;9;NSM;;;;;N;;;;; A830;NORTH INDIC FRACTION ONE QUARTER;No;0;L;;;;1/4;N;;;;; A831;NORTH INDIC FRACTION ONE HALF;No;0;L;;;;1/2;N;;;;; A832;NORTH INDIC FRACTION THREE QUARTERS;No;0;L;;;;3/4;N;;;;; @@ -14183,6 +14392,8 @@ A8FA;DEVANAGARI CARET;Po;0;L;;;;;N;;;;; A8FB;DEVANAGARI HEADSTROKE;Lo;0;L;;;;;N;;;;; A8FC;DEVANAGARI SIGN SIDDHAM;Po;0;L;;;;;N;;;;; A8FD;DEVANAGARI JAIN OM;Lo;0;L;;;;;N;;;;; +A8FE;DEVANAGARI LETTER AY;Lo;0;L;;;;;N;;;;; +A8FF;DEVANAGARI VOWEL SIGN AY;Mn;0;NSM;;;;;N;;;;; A900;KAYAH LI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; A901;KAYAH LI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; A902;KAYAH LI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; @@ -14358,7 +14569,7 @@ A9B9;JAVANESE VOWEL SIGN SUKU MENDUT;Mn;0;NSM;;;;;N;;;;; A9BA;JAVANESE VOWEL SIGN TALING;Mc;0;L;;;;;N;;;;; A9BB;JAVANESE VOWEL SIGN DIRGA MURE;Mc;0;L;;;;;N;;;;; A9BC;JAVANESE VOWEL SIGN PEPET;Mn;0;NSM;;;;;N;;;;; -A9BD;JAVANESE CONSONANT SIGN KERET;Mc;0;L;;;;;N;;;;; +A9BD;JAVANESE CONSONANT SIGN KERET;Mn;0;NSM;;;;;N;;;;; A9BE;JAVANESE CONSONANT SIGN PENGKAL;Mc;0;L;;;;;N;;;;; A9BF;JAVANESE CONSONANT SIGN CAKRA;Mc;0;L;;;;;N;;;;; A9C0;JAVANESE PANGKON;Mc;9;L;;;;;N;;;;; @@ -14715,6 +14926,12 @@ AB62;LATIN SMALL LETTER OPEN OE;Ll;0;L;;;;;N;;;;; AB63;LATIN SMALL LETTER UO;Ll;0;L;;;;;N;;;;; AB64;LATIN SMALL LETTER INVERTED ALPHA;Ll;0;L;;;;;N;;;;; AB65;GREEK LETTER SMALL CAPITAL OMEGA;Ll;0;L;;;;;N;;;;; +AB66;LATIN SMALL LETTER DZ DIGRAPH WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +AB67;LATIN SMALL LETTER TS DIGRAPH WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;; +AB68;LATIN SMALL LETTER TURNED R WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;; +AB69;MODIFIER LETTER SMALL TURNED W;Lm;0;L; 028D;;;;N;;;;; +AB6A;MODIFIER LETTER LEFT TACK;Sk;0;ON;;;;;N;;;;; +AB6B;MODIFIER LETTER RIGHT TACK;Sk;0;ON;;;;;N;;;;; AB70;CHEROKEE SMALL LETTER A;Ll;0;L;;;;;N;;;13A0;;13A0 AB71;CHEROKEE SMALL LETTER E;Ll;0;L;;;;;N;;;13A1;;13A1 AB72;CHEROKEE SMALL LETTER I;Ll;0;L;;;;;N;;;13A2;;13A2 @@ -16904,6 +17121,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 10199;ROMAN DUPONDIUS SIGN;So;0;ON;;;;;N;;;;; 1019A;ROMAN AS SIGN;So;0;ON;;;;;N;;;;; 1019B;ROMAN CENTURIAL SIGN;So;0;ON;;;;;N;;;;; +1019C;ASCIA SYMBOL;So;0;ON;;;;;N;;;;; 101A0;GREEK SYMBOL TAU RHO;So;0;ON;;;;;N;;;;; 101D0;PHAISTOS DISC SIGN PEDESTRIAN;So;0;L;;;;;N;;;;; 101D1;PHAISTOS DISC SIGN PLUMED HEAD;So;0;L;;;;;N;;;;; @@ -17093,6 +17311,9 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 10321;OLD ITALIC NUMERAL FIVE;No;0;L;;;;5;N;;;;; 10322;OLD ITALIC NUMERAL TEN;No;0;L;;;;10;N;;;;; 10323;OLD ITALIC NUMERAL FIFTY;No;0;L;;;;50;N;;;;; +1032D;OLD ITALIC LETTER YE;Lo;0;L;;;;;N;;;;; +1032E;OLD ITALIC LETTER NORTHERN TSE;Lo;0;L;;;;;N;;;;; +1032F;OLD ITALIC LETTER SOUTHERN TSE;Lo;0;L;;;;;N;;;;; 10330;GOTHIC LETTER AHSA;Lo;0;L;;;;;N;;;;; 10331;GOTHIC LETTER BAIRKAN;Lo;0;L;;;;;N;;;;; 10332;GOTHIC LETTER GIBA;Lo;0;L;;;;;N;;;;; @@ -18324,6 +18545,8 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 10A31;KHAROSHTHI LETTER HA;Lo;0;R;;;;;N;;;;; 10A32;KHAROSHTHI LETTER KKA;Lo;0;R;;;;;N;;;;; 10A33;KHAROSHTHI LETTER TTTHA;Lo;0;R;;;;;N;;;;; +10A34;KHAROSHTHI LETTER TTTA;Lo;0;R;;;;;N;;;;; +10A35;KHAROSHTHI LETTER VHA;Lo;0;R;;;;;N;;;;; 10A38;KHAROSHTHI SIGN BAR ABOVE;Mn;230;NSM;;;;;N;;;;; 10A39;KHAROSHTHI SIGN CAUDA;Mn;1;NSM;;;;;N;;;;; 10A3A;KHAROSHTHI SIGN DOT BELOW;Mn;220;NSM;;;;;N;;;;; @@ -18336,6 +18559,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 10A45;KHAROSHTHI NUMBER TWENTY;No;0;R;;;;20;N;;;;; 10A46;KHAROSHTHI NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;; 10A47;KHAROSHTHI NUMBER ONE THOUSAND;No;0;R;;;;1000;N;;;;; +10A48;KHAROSHTHI FRACTION ONE HALF;No;0;R;;;;1/2;N;;;;; 10A50;KHAROSHTHI PUNCTUATION DOT;Po;0;R;;;;;N;;;;; 10A51;KHAROSHTHI PUNCTUATION SMALL CIRCLE;Po;0;R;;;;;N;;;;; 10A52;KHAROSHTHI PUNCTUATION CIRCLE;Po;0;R;;;;;N;;;;; @@ -18788,6 +19012,56 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 10CFD;OLD HUNGARIAN NUMBER FIFTY;No;0;R;;;;50;N;;;;; 10CFE;OLD HUNGARIAN NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;; 10CFF;OLD HUNGARIAN NUMBER ONE THOUSAND;No;0;R;;;;1000;N;;;;; +10D00;HANIFI ROHINGYA LETTER A;Lo;0;AL;;;;;N;;;;; +10D01;HANIFI ROHINGYA LETTER BA;Lo;0;AL;;;;;N;;;;; +10D02;HANIFI ROHINGYA LETTER PA;Lo;0;AL;;;;;N;;;;; +10D03;HANIFI ROHINGYA LETTER TA;Lo;0;AL;;;;;N;;;;; +10D04;HANIFI ROHINGYA LETTER TTA;Lo;0;AL;;;;;N;;;;; +10D05;HANIFI ROHINGYA LETTER JA;Lo;0;AL;;;;;N;;;;; +10D06;HANIFI ROHINGYA LETTER CA;Lo;0;AL;;;;;N;;;;; +10D07;HANIFI ROHINGYA LETTER HA;Lo;0;AL;;;;;N;;;;; +10D08;HANIFI ROHINGYA LETTER KHA;Lo;0;AL;;;;;N;;;;; +10D09;HANIFI ROHINGYA LETTER FA;Lo;0;AL;;;;;N;;;;; +10D0A;HANIFI ROHINGYA LETTER DA;Lo;0;AL;;;;;N;;;;; +10D0B;HANIFI ROHINGYA LETTER DDA;Lo;0;AL;;;;;N;;;;; +10D0C;HANIFI ROHINGYA LETTER RA;Lo;0;AL;;;;;N;;;;; +10D0D;HANIFI ROHINGYA LETTER RRA;Lo;0;AL;;;;;N;;;;; +10D0E;HANIFI ROHINGYA LETTER ZA;Lo;0;AL;;;;;N;;;;; +10D0F;HANIFI ROHINGYA LETTER SA;Lo;0;AL;;;;;N;;;;; +10D10;HANIFI ROHINGYA LETTER SHA;Lo;0;AL;;;;;N;;;;; +10D11;HANIFI ROHINGYA LETTER KA;Lo;0;AL;;;;;N;;;;; +10D12;HANIFI ROHINGYA LETTER GA;Lo;0;AL;;;;;N;;;;; +10D13;HANIFI ROHINGYA LETTER LA;Lo;0;AL;;;;;N;;;;; +10D14;HANIFI ROHINGYA LETTER MA;Lo;0;AL;;;;;N;;;;; +10D15;HANIFI ROHINGYA LETTER NA;Lo;0;AL;;;;;N;;;;; +10D16;HANIFI ROHINGYA LETTER WA;Lo;0;AL;;;;;N;;;;; +10D17;HANIFI ROHINGYA LETTER KINNA WA;Lo;0;AL;;;;;N;;;;; +10D18;HANIFI ROHINGYA LETTER YA;Lo;0;AL;;;;;N;;;;; +10D19;HANIFI ROHINGYA LETTER KINNA YA;Lo;0;AL;;;;;N;;;;; +10D1A;HANIFI ROHINGYA LETTER NGA;Lo;0;AL;;;;;N;;;;; +10D1B;HANIFI ROHINGYA LETTER NYA;Lo;0;AL;;;;;N;;;;; +10D1C;HANIFI ROHINGYA LETTER VA;Lo;0;AL;;;;;N;;;;; +10D1D;HANIFI ROHINGYA VOWEL A;Lo;0;AL;;;;;N;;;;; +10D1E;HANIFI ROHINGYA VOWEL I;Lo;0;AL;;;;;N;;;;; +10D1F;HANIFI ROHINGYA VOWEL U;Lo;0;AL;;;;;N;;;;; +10D20;HANIFI ROHINGYA VOWEL E;Lo;0;AL;;;;;N;;;;; +10D21;HANIFI ROHINGYA VOWEL O;Lo;0;AL;;;;;N;;;;; +10D22;HANIFI ROHINGYA MARK SAKIN;Lo;0;AL;;;;;N;;;;; +10D23;HANIFI ROHINGYA MARK NA KHONNA;Lo;0;AL;;;;;N;;;;; +10D24;HANIFI ROHINGYA SIGN HARBAHAY;Mn;230;NSM;;;;;N;;;;; +10D25;HANIFI ROHINGYA SIGN TAHALA;Mn;230;NSM;;;;;N;;;;; +10D26;HANIFI ROHINGYA SIGN TANA;Mn;230;NSM;;;;;N;;;;; +10D27;HANIFI ROHINGYA SIGN TASSI;Mn;230;NSM;;;;;N;;;;; +10D30;HANIFI ROHINGYA DIGIT ZERO;Nd;0;AN;;0;0;0;N;;;;; +10D31;HANIFI ROHINGYA DIGIT ONE;Nd;0;AN;;1;1;1;N;;;;; +10D32;HANIFI ROHINGYA DIGIT TWO;Nd;0;AN;;2;2;2;N;;;;; +10D33;HANIFI ROHINGYA DIGIT THREE;Nd;0;AN;;3;3;3;N;;;;; +10D34;HANIFI ROHINGYA DIGIT FOUR;Nd;0;AN;;4;4;4;N;;;;; +10D35;HANIFI ROHINGYA DIGIT FIVE;Nd;0;AN;;5;5;5;N;;;;; +10D36;HANIFI ROHINGYA DIGIT SIX;Nd;0;AN;;6;6;6;N;;;;; +10D37;HANIFI ROHINGYA DIGIT SEVEN;Nd;0;AN;;7;7;7;N;;;;; +10D38;HANIFI ROHINGYA DIGIT EIGHT;Nd;0;AN;;8;8;8;N;;;;; +10D39;HANIFI ROHINGYA DIGIT NINE;Nd;0;AN;;9;9;9;N;;;;; 10E60;RUMI DIGIT ONE;No;0;AN;;;1;1;N;;;;; 10E61;RUMI DIGIT TWO;No;0;AN;;;2;2;N;;;;; 10E62;RUMI DIGIT THREE;No;0;AN;;;3;3;N;;;;; @@ -18819,6 +19093,186 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 10E7C;RUMI FRACTION ONE QUARTER;No;0;AN;;;;1/4;N;;;;; 10E7D;RUMI FRACTION ONE THIRD;No;0;AN;;;;1/3;N;;;;; 10E7E;RUMI FRACTION TWO THIRDS;No;0;AN;;;;2/3;N;;;;; +10E80;YEZIDI LETTER ELIF;Lo;0;R;;;;;N;;;;; +10E81;YEZIDI LETTER BE;Lo;0;R;;;;;N;;;;; +10E82;YEZIDI LETTER PE;Lo;0;R;;;;;N;;;;; +10E83;YEZIDI LETTER PHE;Lo;0;R;;;;;N;;;;; +10E84;YEZIDI LETTER THE;Lo;0;R;;;;;N;;;;; +10E85;YEZIDI LETTER SE;Lo;0;R;;;;;N;;;;; +10E86;YEZIDI LETTER CIM;Lo;0;R;;;;;N;;;;; +10E87;YEZIDI LETTER CHIM;Lo;0;R;;;;;N;;;;; +10E88;YEZIDI LETTER CHHIM;Lo;0;R;;;;;N;;;;; +10E89;YEZIDI LETTER HHA;Lo;0;R;;;;;N;;;;; +10E8A;YEZIDI LETTER XA;Lo;0;R;;;;;N;;;;; +10E8B;YEZIDI LETTER DAL;Lo;0;R;;;;;N;;;;; +10E8C;YEZIDI LETTER ZAL;Lo;0;R;;;;;N;;;;; +10E8D;YEZIDI LETTER RA;Lo;0;R;;;;;N;;;;; +10E8E;YEZIDI LETTER RHA;Lo;0;R;;;;;N;;;;; +10E8F;YEZIDI LETTER ZA;Lo;0;R;;;;;N;;;;; +10E90;YEZIDI LETTER JA;Lo;0;R;;;;;N;;;;; +10E91;YEZIDI LETTER SIN;Lo;0;R;;;;;N;;;;; +10E92;YEZIDI LETTER SHIN;Lo;0;R;;;;;N;;;;; +10E93;YEZIDI LETTER SAD;Lo;0;R;;;;;N;;;;; +10E94;YEZIDI LETTER DAD;Lo;0;R;;;;;N;;;;; +10E95;YEZIDI LETTER TA;Lo;0;R;;;;;N;;;;; +10E96;YEZIDI LETTER ZE;Lo;0;R;;;;;N;;;;; +10E97;YEZIDI LETTER EYN;Lo;0;R;;;;;N;;;;; +10E98;YEZIDI LETTER XHEYN;Lo;0;R;;;;;N;;;;; +10E99;YEZIDI LETTER FA;Lo;0;R;;;;;N;;;;; +10E9A;YEZIDI LETTER VA;Lo;0;R;;;;;N;;;;; +10E9B;YEZIDI LETTER VA ALTERNATE FORM;Lo;0;R;;;;;N;;;;; +10E9C;YEZIDI LETTER QAF;Lo;0;R;;;;;N;;;;; +10E9D;YEZIDI LETTER KAF;Lo;0;R;;;;;N;;;;; +10E9E;YEZIDI LETTER KHAF;Lo;0;R;;;;;N;;;;; +10E9F;YEZIDI LETTER GAF;Lo;0;R;;;;;N;;;;; +10EA0;YEZIDI LETTER LAM;Lo;0;R;;;;;N;;;;; +10EA1;YEZIDI LETTER MIM;Lo;0;R;;;;;N;;;;; +10EA2;YEZIDI LETTER NUN;Lo;0;R;;;;;N;;;;; +10EA3;YEZIDI LETTER UM;Lo;0;R;;;;;N;;;;; +10EA4;YEZIDI LETTER WAW;Lo;0;R;;;;;N;;;;; +10EA5;YEZIDI LETTER OW;Lo;0;R;;;;;N;;;;; +10EA6;YEZIDI LETTER EW;Lo;0;R;;;;;N;;;;; +10EA7;YEZIDI LETTER HAY;Lo;0;R;;;;;N;;;;; +10EA8;YEZIDI LETTER YOT;Lo;0;R;;;;;N;;;;; +10EA9;YEZIDI LETTER ET;Lo;0;R;;;;;N;;;;; +10EAB;YEZIDI COMBINING HAMZA MARK;Mn;230;NSM;;;;;N;;;;; +10EAC;YEZIDI COMBINING MADDA MARK;Mn;230;NSM;;;;;N;;;;; +10EAD;YEZIDI HYPHENATION MARK;Pd;0;R;;;;;N;;;;; +10EB0;YEZIDI LETTER LAM WITH DOT ABOVE;Lo;0;R;;;;;N;;;;; +10EB1;YEZIDI LETTER YOT WITH CIRCUMFLEX ABOVE;Lo;0;R;;;;;N;;;;; +10F00;OLD SOGDIAN LETTER ALEPH;Lo;0;R;;;;;N;;;;; +10F01;OLD SOGDIAN LETTER FINAL ALEPH;Lo;0;R;;;;;N;;;;; +10F02;OLD SOGDIAN LETTER BETH;Lo;0;R;;;;;N;;;;; +10F03;OLD SOGDIAN LETTER FINAL BETH;Lo;0;R;;;;;N;;;;; +10F04;OLD SOGDIAN LETTER GIMEL;Lo;0;R;;;;;N;;;;; +10F05;OLD SOGDIAN LETTER HE;Lo;0;R;;;;;N;;;;; +10F06;OLD SOGDIAN LETTER FINAL HE;Lo;0;R;;;;;N;;;;; +10F07;OLD SOGDIAN LETTER WAW;Lo;0;R;;;;;N;;;;; +10F08;OLD SOGDIAN LETTER ZAYIN;Lo;0;R;;;;;N;;;;; +10F09;OLD SOGDIAN LETTER HETH;Lo;0;R;;;;;N;;;;; +10F0A;OLD SOGDIAN LETTER YODH;Lo;0;R;;;;;N;;;;; +10F0B;OLD SOGDIAN LETTER KAPH;Lo;0;R;;;;;N;;;;; +10F0C;OLD SOGDIAN LETTER LAMEDH;Lo;0;R;;;;;N;;;;; +10F0D;OLD SOGDIAN LETTER MEM;Lo;0;R;;;;;N;;;;; +10F0E;OLD SOGDIAN LETTER NUN;Lo;0;R;;;;;N;;;;; +10F0F;OLD SOGDIAN LETTER FINAL NUN;Lo;0;R;;;;;N;;;;; +10F10;OLD SOGDIAN LETTER FINAL NUN WITH VERTICAL TAIL;Lo;0;R;;;;;N;;;;; +10F11;OLD SOGDIAN LETTER SAMEKH;Lo;0;R;;;;;N;;;;; +10F12;OLD SOGDIAN LETTER AYIN;Lo;0;R;;;;;N;;;;; +10F13;OLD SOGDIAN LETTER ALTERNATE AYIN;Lo;0;R;;;;;N;;;;; +10F14;OLD SOGDIAN LETTER PE;Lo;0;R;;;;;N;;;;; +10F15;OLD SOGDIAN LETTER SADHE;Lo;0;R;;;;;N;;;;; +10F16;OLD SOGDIAN LETTER FINAL SADHE;Lo;0;R;;;;;N;;;;; +10F17;OLD SOGDIAN LETTER FINAL SADHE WITH VERTICAL TAIL;Lo;0;R;;;;;N;;;;; +10F18;OLD SOGDIAN LETTER RESH-AYIN-DALETH;Lo;0;R;;;;;N;;;;; +10F19;OLD SOGDIAN LETTER SHIN;Lo;0;R;;;;;N;;;;; +10F1A;OLD SOGDIAN LETTER TAW;Lo;0;R;;;;;N;;;;; +10F1B;OLD SOGDIAN LETTER FINAL TAW;Lo;0;R;;;;;N;;;;; +10F1C;OLD SOGDIAN LETTER FINAL TAW WITH VERTICAL TAIL;Lo;0;R;;;;;N;;;;; +10F1D;OLD SOGDIAN NUMBER ONE;No;0;R;;;;1;N;;;;; +10F1E;OLD SOGDIAN NUMBER TWO;No;0;R;;;;2;N;;;;; +10F1F;OLD SOGDIAN NUMBER THREE;No;0;R;;;;3;N;;;;; +10F20;OLD SOGDIAN NUMBER FOUR;No;0;R;;;;4;N;;;;; +10F21;OLD SOGDIAN NUMBER FIVE;No;0;R;;;;5;N;;;;; +10F22;OLD SOGDIAN NUMBER TEN;No;0;R;;;;10;N;;;;; +10F23;OLD SOGDIAN NUMBER TWENTY;No;0;R;;;;20;N;;;;; +10F24;OLD SOGDIAN NUMBER THIRTY;No;0;R;;;;30;N;;;;; +10F25;OLD SOGDIAN NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;; +10F26;OLD SOGDIAN FRACTION ONE HALF;No;0;R;;;;1/2;N;;;;; +10F27;OLD SOGDIAN LIGATURE AYIN-DALETH;Lo;0;R;;;;;N;;;;; +10F30;SOGDIAN LETTER ALEPH;Lo;0;AL;;;;;N;;;;; +10F31;SOGDIAN LETTER BETH;Lo;0;AL;;;;;N;;;;; +10F32;SOGDIAN LETTER GIMEL;Lo;0;AL;;;;;N;;;;; +10F33;SOGDIAN LETTER HE;Lo;0;AL;;;;;N;;;;; +10F34;SOGDIAN LETTER WAW;Lo;0;AL;;;;;N;;;;; +10F35;SOGDIAN LETTER ZAYIN;Lo;0;AL;;;;;N;;;;; +10F36;SOGDIAN LETTER HETH;Lo;0;AL;;;;;N;;;;; +10F37;SOGDIAN LETTER YODH;Lo;0;AL;;;;;N;;;;; +10F38;SOGDIAN LETTER KAPH;Lo;0;AL;;;;;N;;;;; +10F39;SOGDIAN LETTER LAMEDH;Lo;0;AL;;;;;N;;;;; +10F3A;SOGDIAN LETTER MEM;Lo;0;AL;;;;;N;;;;; +10F3B;SOGDIAN LETTER NUN;Lo;0;AL;;;;;N;;;;; +10F3C;SOGDIAN LETTER SAMEKH;Lo;0;AL;;;;;N;;;;; +10F3D;SOGDIAN LETTER AYIN;Lo;0;AL;;;;;N;;;;; +10F3E;SOGDIAN LETTER PE;Lo;0;AL;;;;;N;;;;; +10F3F;SOGDIAN LETTER SADHE;Lo;0;AL;;;;;N;;;;; +10F40;SOGDIAN LETTER RESH-AYIN;Lo;0;AL;;;;;N;;;;; +10F41;SOGDIAN LETTER SHIN;Lo;0;AL;;;;;N;;;;; +10F42;SOGDIAN LETTER TAW;Lo;0;AL;;;;;N;;;;; +10F43;SOGDIAN LETTER FETH;Lo;0;AL;;;;;N;;;;; +10F44;SOGDIAN LETTER LESH;Lo;0;AL;;;;;N;;;;; +10F45;SOGDIAN INDEPENDENT SHIN;Lo;0;AL;;;;;N;;;;; +10F46;SOGDIAN COMBINING DOT BELOW;Mn;220;NSM;;;;;N;;;;; +10F47;SOGDIAN COMBINING TWO DOTS BELOW;Mn;220;NSM;;;;;N;;;;; +10F48;SOGDIAN COMBINING DOT ABOVE;Mn;230;NSM;;;;;N;;;;; +10F49;SOGDIAN COMBINING TWO DOTS ABOVE;Mn;230;NSM;;;;;N;;;;; +10F4A;SOGDIAN COMBINING CURVE ABOVE;Mn;230;NSM;;;;;N;;;;; +10F4B;SOGDIAN COMBINING CURVE BELOW;Mn;220;NSM;;;;;N;;;;; +10F4C;SOGDIAN COMBINING HOOK ABOVE;Mn;230;NSM;;;;;N;;;;; +10F4D;SOGDIAN COMBINING HOOK BELOW;Mn;220;NSM;;;;;N;;;;; +10F4E;SOGDIAN COMBINING LONG HOOK BELOW;Mn;220;NSM;;;;;N;;;;; +10F4F;SOGDIAN COMBINING RESH BELOW;Mn;220;NSM;;;;;N;;;;; +10F50;SOGDIAN COMBINING STROKE BELOW;Mn;220;NSM;;;;;N;;;;; +10F51;SOGDIAN NUMBER ONE;No;0;AL;;;;1;N;;;;; +10F52;SOGDIAN NUMBER TEN;No;0;AL;;;;10;N;;;;; +10F53;SOGDIAN NUMBER TWENTY;No;0;AL;;;;20;N;;;;; +10F54;SOGDIAN NUMBER ONE HUNDRED;No;0;AL;;;;100;N;;;;; +10F55;SOGDIAN PUNCTUATION TWO VERTICAL BARS;Po;0;AL;;;;;N;;;;; +10F56;SOGDIAN PUNCTUATION TWO VERTICAL BARS WITH DOTS;Po;0;AL;;;;;N;;;;; +10F57;SOGDIAN PUNCTUATION CIRCLE WITH DOT;Po;0;AL;;;;;N;;;;; +10F58;SOGDIAN PUNCTUATION TWO CIRCLES WITH DOTS;Po;0;AL;;;;;N;;;;; +10F59;SOGDIAN PUNCTUATION HALF CIRCLE WITH DOT;Po;0;AL;;;;;N;;;;; +10FB0;CHORASMIAN LETTER ALEPH;Lo;0;R;;;;;N;;;;; +10FB1;CHORASMIAN LETTER SMALL ALEPH;Lo;0;R;;;;;N;;;;; +10FB2;CHORASMIAN LETTER BETH;Lo;0;R;;;;;N;;;;; +10FB3;CHORASMIAN LETTER GIMEL;Lo;0;R;;;;;N;;;;; +10FB4;CHORASMIAN LETTER DALETH;Lo;0;R;;;;;N;;;;; +10FB5;CHORASMIAN LETTER HE;Lo;0;R;;;;;N;;;;; +10FB6;CHORASMIAN LETTER WAW;Lo;0;R;;;;;N;;;;; +10FB7;CHORASMIAN LETTER CURLED WAW;Lo;0;R;;;;;N;;;;; +10FB8;CHORASMIAN LETTER ZAYIN;Lo;0;R;;;;;N;;;;; +10FB9;CHORASMIAN LETTER HETH;Lo;0;R;;;;;N;;;;; +10FBA;CHORASMIAN LETTER YODH;Lo;0;R;;;;;N;;;;; +10FBB;CHORASMIAN LETTER KAPH;Lo;0;R;;;;;N;;;;; +10FBC;CHORASMIAN LETTER LAMEDH;Lo;0;R;;;;;N;;;;; +10FBD;CHORASMIAN LETTER MEM;Lo;0;R;;;;;N;;;;; +10FBE;CHORASMIAN LETTER NUN;Lo;0;R;;;;;N;;;;; +10FBF;CHORASMIAN LETTER SAMEKH;Lo;0;R;;;;;N;;;;; +10FC0;CHORASMIAN LETTER AYIN;Lo;0;R;;;;;N;;;;; +10FC1;CHORASMIAN LETTER PE;Lo;0;R;;;;;N;;;;; +10FC2;CHORASMIAN LETTER RESH;Lo;0;R;;;;;N;;;;; +10FC3;CHORASMIAN LETTER SHIN;Lo;0;R;;;;;N;;;;; +10FC4;CHORASMIAN LETTER TAW;Lo;0;R;;;;;N;;;;; +10FC5;CHORASMIAN NUMBER ONE;No;0;R;;;;1;N;;;;; +10FC6;CHORASMIAN NUMBER TWO;No;0;R;;;;2;N;;;;; +10FC7;CHORASMIAN NUMBER THREE;No;0;R;;;;3;N;;;;; +10FC8;CHORASMIAN NUMBER FOUR;No;0;R;;;;4;N;;;;; +10FC9;CHORASMIAN NUMBER TEN;No;0;R;;;;10;N;;;;; +10FCA;CHORASMIAN NUMBER TWENTY;No;0;R;;;;20;N;;;;; +10FCB;CHORASMIAN NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;; +10FE0;ELYMAIC LETTER ALEPH;Lo;0;R;;;;;N;;;;; +10FE1;ELYMAIC LETTER BETH;Lo;0;R;;;;;N;;;;; +10FE2;ELYMAIC LETTER GIMEL;Lo;0;R;;;;;N;;;;; +10FE3;ELYMAIC LETTER DALETH;Lo;0;R;;;;;N;;;;; +10FE4;ELYMAIC LETTER HE;Lo;0;R;;;;;N;;;;; +10FE5;ELYMAIC LETTER WAW;Lo;0;R;;;;;N;;;;; +10FE6;ELYMAIC LETTER ZAYIN;Lo;0;R;;;;;N;;;;; +10FE7;ELYMAIC LETTER HETH;Lo;0;R;;;;;N;;;;; +10FE8;ELYMAIC LETTER TETH;Lo;0;R;;;;;N;;;;; +10FE9;ELYMAIC LETTER YODH;Lo;0;R;;;;;N;;;;; +10FEA;ELYMAIC LETTER KAPH;Lo;0;R;;;;;N;;;;; +10FEB;ELYMAIC LETTER LAMEDH;Lo;0;R;;;;;N;;;;; +10FEC;ELYMAIC LETTER MEM;Lo;0;R;;;;;N;;;;; +10FED;ELYMAIC LETTER NUN;Lo;0;R;;;;;N;;;;; +10FEE;ELYMAIC LETTER SAMEKH;Lo;0;R;;;;;N;;;;; +10FEF;ELYMAIC LETTER AYIN;Lo;0;R;;;;;N;;;;; +10FF0;ELYMAIC LETTER PE;Lo;0;R;;;;;N;;;;; +10FF1;ELYMAIC LETTER SADHE;Lo;0;R;;;;;N;;;;; +10FF2;ELYMAIC LETTER QOPH;Lo;0;R;;;;;N;;;;; +10FF3;ELYMAIC LETTER RESH;Lo;0;R;;;;;N;;;;; +10FF4;ELYMAIC LETTER SHIN;Lo;0;R;;;;;N;;;;; +10FF5;ELYMAIC LETTER TAW;Lo;0;R;;;;;N;;;;; +10FF6;ELYMAIC LIGATURE ZAYIN-YODH;Lo;0;R;;;;;N;;;;; 11000;BRAHMI SIGN CANDRABINDU;Mc;0;L;;;;;N;;;;; 11001;BRAHMI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; 11002;BRAHMI SIGN VISARGA;Mc;0;L;;;;;N;;;;; @@ -18994,6 +19448,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 110BF;KAITHI DOUBLE SECTION MARK;Po;0;L;;;;;N;;;;; 110C0;KAITHI DANDA;Po;0;L;;;;;N;;;;; 110C1;KAITHI DOUBLE DANDA;Po;0;L;;;;;N;;;;; +110CD;KAITHI NUMBER SIGN ABOVE;Cf;0;L;;;;;N;;;;; 110D0;SORA SOMPENG LETTER SAH;Lo;0;L;;;;;N;;;;; 110D1;SORA SOMPENG LETTER TAH;Lo;0;L;;;;;N;;;;; 110D2;SORA SOMPENG LETTER BAH;Lo;0;L;;;;;N;;;;; @@ -19096,6 +19551,10 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 11141;CHAKMA DANDA;Po;0;L;;;;;N;;;;; 11142;CHAKMA DOUBLE DANDA;Po;0;L;;;;;N;;;;; 11143;CHAKMA QUESTION MARK;Po;0;L;;;;;N;;;;; +11144;CHAKMA LETTER LHAA;Lo;0;L;;;;;N;;;;; +11145;CHAKMA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +11146;CHAKMA VOWEL SIGN EI;Mc;0;L;;;;;N;;;;; +11147;CHAKMA LETTER VAA;Lo;0;L;;;;;N;;;;; 11150;MAHAJANI LETTER A;Lo;0;L;;;;;N;;;;; 11151;MAHAJANI LETTER I;Lo;0;L;;;;;N;;;;; 11152;MAHAJANI LETTER U;Lo;0;L;;;;;N;;;;; @@ -19208,11 +19667,13 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 111C6;SHARADA DOUBLE DANDA;Po;0;L;;;;;N;;;;; 111C7;SHARADA ABBREVIATION SIGN;Po;0;L;;;;;N;;;;; 111C8;SHARADA SEPARATOR;Po;0;L;;;;;N;;;;; -111C9;SHARADA SANDHI MARK;Po;0;L;;;;;N;;;;; +111C9;SHARADA SANDHI MARK;Mn;0;NSM;;;;;N;;;;; 111CA;SHARADA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; 111CB;SHARADA VOWEL MODIFIER MARK;Mn;0;NSM;;;;;N;;;;; 111CC;SHARADA EXTRA SHORT VOWEL MARK;Mn;0;NSM;;;;;N;;;;; 111CD;SHARADA SUTRA MARK;Po;0;L;;;;;N;;;;; +111CE;SHARADA VOWEL SIGN PRISHTHAMATRA E;Mc;0;L;;;;;N;;;;; +111CF;SHARADA SIGN INVERTED CANDRABINDU;Mn;0;NSM;;;;;N;;;;; 111D0;SHARADA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; 111D1;SHARADA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; 111D2;SHARADA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; @@ -19468,6 +19929,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 11337;GRANTHA LETTER SSA;Lo;0;L;;;;;N;;;;; 11338;GRANTHA LETTER SA;Lo;0;L;;;;;N;;;;; 11339;GRANTHA LETTER HA;Lo;0;L;;;;;N;;;;; +1133B;COMBINING BINDU BELOW;Mn;7;NSM;;;;;N;;;;; 1133C;GRANTHA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; 1133D;GRANTHA SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;; 1133E;GRANTHA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; @@ -19593,8 +20055,13 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 11457;NEWA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; 11458;NEWA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; 11459;NEWA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +1145A;NEWA DOUBLE COMMA;Po;0;L;;;;;N;;;;; 1145B;NEWA PLACEHOLDER MARK;Po;0;L;;;;;N;;;;; 1145D;NEWA INSERTION SIGN;Po;0;L;;;;;N;;;;; +1145E;NEWA SANDHI MARK;Mn;230;NSM;;;;;N;;;;; +1145F;NEWA LETTER VEDIC ANUSVARA;Lo;0;L;;;;;N;;;;; +11460;NEWA SIGN JIHVAMULIYA;Lo;0;L;;;;;N;;;;; +11461;NEWA SIGN UPADHMANIYA;Lo;0;L;;;;;N;;;;; 11480;TIRHUTA ANJI;Lo;0;L;;;;;N;;;;; 11481;TIRHUTA LETTER A;Lo;0;L;;;;;N;;;;; 11482;TIRHUTA LETTER AA;Lo;0;L;;;;;N;;;;; @@ -19917,6 +20384,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 116B5;TAKRI VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;; 116B6;TAKRI SIGN VIRAMA;Mc;9;L;;;;;N;;;;; 116B7;TAKRI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +116B8;TAKRI LETTER ARCHAIC KHA;Lo;0;L;;;;;N;;;;; 116C0;TAKRI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; 116C1;TAKRI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; 116C2;TAKRI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; @@ -19953,6 +20421,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 11717;AHOM LETTER GHA;Lo;0;L;;;;;N;;;;; 11718;AHOM LETTER BHA;Lo;0;L;;;;;N;;;;; 11719;AHOM LETTER JHA;Lo;0;L;;;;;N;;;;; +1171A;AHOM LETTER ALTERNATE BA;Lo;0;L;;;;;N;;;;; 1171D;AHOM CONSONANT SIGN MEDIAL LA;Mn;0;NSM;;;;;N;;;;; 1171E;AHOM CONSONANT SIGN MEDIAL RA;Mn;0;NSM;;;;;N;;;;; 1171F;AHOM CONSONANT SIGN MEDIAL LIGATING RA;Mn;0;NSM;;;;;N;;;;; @@ -19984,6 +20453,66 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1173D;AHOM SIGN SECTION;Po;0;L;;;;;N;;;;; 1173E;AHOM SIGN RULAI;Po;0;L;;;;;N;;;;; 1173F;AHOM SYMBOL VI;So;0;L;;;;;N;;;;; +11800;DOGRA LETTER A;Lo;0;L;;;;;N;;;;; +11801;DOGRA LETTER AA;Lo;0;L;;;;;N;;;;; +11802;DOGRA LETTER I;Lo;0;L;;;;;N;;;;; +11803;DOGRA LETTER II;Lo;0;L;;;;;N;;;;; +11804;DOGRA LETTER U;Lo;0;L;;;;;N;;;;; +11805;DOGRA LETTER UU;Lo;0;L;;;;;N;;;;; +11806;DOGRA LETTER E;Lo;0;L;;;;;N;;;;; +11807;DOGRA LETTER AI;Lo;0;L;;;;;N;;;;; +11808;DOGRA LETTER O;Lo;0;L;;;;;N;;;;; +11809;DOGRA LETTER AU;Lo;0;L;;;;;N;;;;; +1180A;DOGRA LETTER KA;Lo;0;L;;;;;N;;;;; +1180B;DOGRA LETTER KHA;Lo;0;L;;;;;N;;;;; +1180C;DOGRA LETTER GA;Lo;0;L;;;;;N;;;;; +1180D;DOGRA LETTER GHA;Lo;0;L;;;;;N;;;;; +1180E;DOGRA LETTER NGA;Lo;0;L;;;;;N;;;;; +1180F;DOGRA LETTER CA;Lo;0;L;;;;;N;;;;; +11810;DOGRA LETTER CHA;Lo;0;L;;;;;N;;;;; +11811;DOGRA LETTER JA;Lo;0;L;;;;;N;;;;; +11812;DOGRA LETTER JHA;Lo;0;L;;;;;N;;;;; +11813;DOGRA LETTER NYA;Lo;0;L;;;;;N;;;;; +11814;DOGRA LETTER TTA;Lo;0;L;;;;;N;;;;; +11815;DOGRA LETTER TTHA;Lo;0;L;;;;;N;;;;; +11816;DOGRA LETTER DDA;Lo;0;L;;;;;N;;;;; +11817;DOGRA LETTER DDHA;Lo;0;L;;;;;N;;;;; +11818;DOGRA LETTER NNA;Lo;0;L;;;;;N;;;;; +11819;DOGRA LETTER TA;Lo;0;L;;;;;N;;;;; +1181A;DOGRA LETTER THA;Lo;0;L;;;;;N;;;;; +1181B;DOGRA LETTER DA;Lo;0;L;;;;;N;;;;; +1181C;DOGRA LETTER DHA;Lo;0;L;;;;;N;;;;; +1181D;DOGRA LETTER NA;Lo;0;L;;;;;N;;;;; +1181E;DOGRA LETTER PA;Lo;0;L;;;;;N;;;;; +1181F;DOGRA LETTER PHA;Lo;0;L;;;;;N;;;;; +11820;DOGRA LETTER BA;Lo;0;L;;;;;N;;;;; +11821;DOGRA LETTER BHA;Lo;0;L;;;;;N;;;;; +11822;DOGRA LETTER MA;Lo;0;L;;;;;N;;;;; +11823;DOGRA LETTER YA;Lo;0;L;;;;;N;;;;; +11824;DOGRA LETTER RA;Lo;0;L;;;;;N;;;;; +11825;DOGRA LETTER LA;Lo;0;L;;;;;N;;;;; +11826;DOGRA LETTER VA;Lo;0;L;;;;;N;;;;; +11827;DOGRA LETTER SHA;Lo;0;L;;;;;N;;;;; +11828;DOGRA LETTER SSA;Lo;0;L;;;;;N;;;;; +11829;DOGRA LETTER SA;Lo;0;L;;;;;N;;;;; +1182A;DOGRA LETTER HA;Lo;0;L;;;;;N;;;;; +1182B;DOGRA LETTER RRA;Lo;0;L;;;;;N;;;;; +1182C;DOGRA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +1182D;DOGRA VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +1182E;DOGRA VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +1182F;DOGRA VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +11830;DOGRA VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +11831;DOGRA VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; +11832;DOGRA VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;; +11833;DOGRA VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +11834;DOGRA VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; +11835;DOGRA VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;; +11836;DOGRA VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;; +11837;DOGRA SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +11838;DOGRA SIGN VISARGA;Mc;0;L;;;;;N;;;;; +11839;DOGRA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +1183A;DOGRA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +1183B;DOGRA ABBREVIATION SIGN;Po;0;L;;;;;N;;;;; 118A0;WARANG CITI CAPITAL LETTER NGAA;Lu;0;L;;;;;N;;;;118C0; 118A1;WARANG CITI CAPITAL LETTER A;Lu;0;L;;;;;N;;;;118C1; 118A2;WARANG CITI CAPITAL LETTER WI;Lu;0;L;;;;;N;;;;118C2; @@ -20068,6 +20597,298 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 118F1;WARANG CITI NUMBER EIGHTY;No;0;L;;;;80;N;;;;; 118F2;WARANG CITI NUMBER NINETY;No;0;L;;;;90;N;;;;; 118FF;WARANG CITI OM;Lo;0;L;;;;;N;;;;; +11900;DIVES AKURU LETTER A;Lo;0;L;;;;;N;;;;; +11901;DIVES AKURU LETTER AA;Lo;0;L;;;;;N;;;;; +11902;DIVES AKURU LETTER I;Lo;0;L;;;;;N;;;;; +11903;DIVES AKURU LETTER II;Lo;0;L;;;;;N;;;;; +11904;DIVES AKURU LETTER U;Lo;0;L;;;;;N;;;;; +11905;DIVES AKURU LETTER UU;Lo;0;L;;;;;N;;;;; +11906;DIVES AKURU LETTER E;Lo;0;L;;;;;N;;;;; +11909;DIVES AKURU LETTER O;Lo;0;L;;;;;N;;;;; +1190C;DIVES AKURU LETTER KA;Lo;0;L;;;;;N;;;;; +1190D;DIVES AKURU LETTER KHA;Lo;0;L;;;;;N;;;;; +1190E;DIVES AKURU LETTER GA;Lo;0;L;;;;;N;;;;; +1190F;DIVES AKURU LETTER GHA;Lo;0;L;;;;;N;;;;; +11910;DIVES AKURU LETTER NGA;Lo;0;L;;;;;N;;;;; +11911;DIVES AKURU LETTER CA;Lo;0;L;;;;;N;;;;; +11912;DIVES AKURU LETTER CHA;Lo;0;L;;;;;N;;;;; +11913;DIVES AKURU LETTER JA;Lo;0;L;;;;;N;;;;; +11915;DIVES AKURU LETTER NYA;Lo;0;L;;;;;N;;;;; +11916;DIVES AKURU LETTER TTA;Lo;0;L;;;;;N;;;;; +11918;DIVES AKURU LETTER DDA;Lo;0;L;;;;;N;;;;; +11919;DIVES AKURU LETTER DDHA;Lo;0;L;;;;;N;;;;; +1191A;DIVES AKURU LETTER NNA;Lo;0;L;;;;;N;;;;; +1191B;DIVES AKURU LETTER TA;Lo;0;L;;;;;N;;;;; +1191C;DIVES AKURU LETTER THA;Lo;0;L;;;;;N;;;;; +1191D;DIVES AKURU LETTER DA;Lo;0;L;;;;;N;;;;; +1191E;DIVES AKURU LETTER DHA;Lo;0;L;;;;;N;;;;; +1191F;DIVES AKURU LETTER NA;Lo;0;L;;;;;N;;;;; +11920;DIVES AKURU LETTER PA;Lo;0;L;;;;;N;;;;; +11921;DIVES AKURU LETTER PHA;Lo;0;L;;;;;N;;;;; +11922;DIVES AKURU LETTER BA;Lo;0;L;;;;;N;;;;; +11923;DIVES AKURU LETTER BHA;Lo;0;L;;;;;N;;;;; +11924;DIVES AKURU LETTER MA;Lo;0;L;;;;;N;;;;; +11925;DIVES AKURU LETTER YA;Lo;0;L;;;;;N;;;;; +11926;DIVES AKURU LETTER YYA;Lo;0;L;;;;;N;;;;; +11927;DIVES AKURU LETTER RA;Lo;0;L;;;;;N;;;;; +11928;DIVES AKURU LETTER LA;Lo;0;L;;;;;N;;;;; +11929;DIVES AKURU LETTER VA;Lo;0;L;;;;;N;;;;; +1192A;DIVES AKURU LETTER SHA;Lo;0;L;;;;;N;;;;; +1192B;DIVES AKURU LETTER SSA;Lo;0;L;;;;;N;;;;; +1192C;DIVES AKURU LETTER SA;Lo;0;L;;;;;N;;;;; +1192D;DIVES AKURU LETTER HA;Lo;0;L;;;;;N;;;;; +1192E;DIVES AKURU LETTER LLA;Lo;0;L;;;;;N;;;;; +1192F;DIVES AKURU LETTER ZA;Lo;0;L;;;;;N;;;;; +11930;DIVES AKURU VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +11931;DIVES AKURU VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +11932;DIVES AKURU VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +11933;DIVES AKURU VOWEL SIGN U;Mc;0;L;;;;;N;;;;; +11934;DIVES AKURU VOWEL SIGN UU;Mc;0;L;;;;;N;;;;; +11935;DIVES AKURU VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +11937;DIVES AKURU VOWEL SIGN AI;Mc;0;L;;;;;N;;;;; +11938;DIVES AKURU VOWEL SIGN O;Mc;0;L;11935 11930;;;;N;;;;; +1193B;DIVES AKURU SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +1193C;DIVES AKURU SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; +1193D;DIVES AKURU SIGN HALANTA;Mc;9;L;;;;;N;;;;; +1193E;DIVES AKURU VIRAMA;Mn;9;NSM;;;;;N;;;;; +1193F;DIVES AKURU PREFIXED NASAL SIGN;Lo;0;L;;;;;N;;;;; +11940;DIVES AKURU MEDIAL YA;Mc;0;L;;;;;N;;;;; +11941;DIVES AKURU INITIAL RA;Lo;0;L;;;;;N;;;;; +11942;DIVES AKURU MEDIAL RA;Mc;0;L;;;;;N;;;;; +11943;DIVES AKURU SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +11944;DIVES AKURU DOUBLE DANDA;Po;0;L;;;;;N;;;;; +11945;DIVES AKURU GAP FILLER;Po;0;L;;;;;N;;;;; +11946;DIVES AKURU END OF TEXT MARK;Po;0;L;;;;;N;;;;; +11950;DIVES AKURU DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +11951;DIVES AKURU DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +11952;DIVES AKURU DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +11953;DIVES AKURU DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +11954;DIVES AKURU DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +11955;DIVES AKURU DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +11956;DIVES AKURU DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +11957;DIVES AKURU DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +11958;DIVES AKURU DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +11959;DIVES AKURU DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +119A0;NANDINAGARI LETTER A;Lo;0;L;;;;;N;;;;; +119A1;NANDINAGARI LETTER AA;Lo;0;L;;;;;N;;;;; +119A2;NANDINAGARI LETTER I;Lo;0;L;;;;;N;;;;; +119A3;NANDINAGARI LETTER II;Lo;0;L;;;;;N;;;;; +119A4;NANDINAGARI LETTER U;Lo;0;L;;;;;N;;;;; +119A5;NANDINAGARI LETTER UU;Lo;0;L;;;;;N;;;;; +119A6;NANDINAGARI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +119A7;NANDINAGARI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +119AA;NANDINAGARI LETTER E;Lo;0;L;;;;;N;;;;; +119AB;NANDINAGARI LETTER AI;Lo;0;L;;;;;N;;;;; +119AC;NANDINAGARI LETTER O;Lo;0;L;;;;;N;;;;; +119AD;NANDINAGARI LETTER AU;Lo;0;L;;;;;N;;;;; +119AE;NANDINAGARI LETTER KA;Lo;0;L;;;;;N;;;;; +119AF;NANDINAGARI LETTER KHA;Lo;0;L;;;;;N;;;;; +119B0;NANDINAGARI LETTER GA;Lo;0;L;;;;;N;;;;; +119B1;NANDINAGARI LETTER GHA;Lo;0;L;;;;;N;;;;; +119B2;NANDINAGARI LETTER NGA;Lo;0;L;;;;;N;;;;; +119B3;NANDINAGARI LETTER CA;Lo;0;L;;;;;N;;;;; +119B4;NANDINAGARI LETTER CHA;Lo;0;L;;;;;N;;;;; +119B5;NANDINAGARI LETTER JA;Lo;0;L;;;;;N;;;;; +119B6;NANDINAGARI LETTER JHA;Lo;0;L;;;;;N;;;;; +119B7;NANDINAGARI LETTER NYA;Lo;0;L;;;;;N;;;;; +119B8;NANDINAGARI LETTER TTA;Lo;0;L;;;;;N;;;;; +119B9;NANDINAGARI LETTER TTHA;Lo;0;L;;;;;N;;;;; +119BA;NANDINAGARI LETTER DDA;Lo;0;L;;;;;N;;;;; +119BB;NANDINAGARI LETTER DDHA;Lo;0;L;;;;;N;;;;; +119BC;NANDINAGARI LETTER NNA;Lo;0;L;;;;;N;;;;; +119BD;NANDINAGARI LETTER TA;Lo;0;L;;;;;N;;;;; +119BE;NANDINAGARI LETTER THA;Lo;0;L;;;;;N;;;;; +119BF;NANDINAGARI LETTER DA;Lo;0;L;;;;;N;;;;; +119C0;NANDINAGARI LETTER DHA;Lo;0;L;;;;;N;;;;; +119C1;NANDINAGARI LETTER NA;Lo;0;L;;;;;N;;;;; +119C2;NANDINAGARI LETTER PA;Lo;0;L;;;;;N;;;;; +119C3;NANDINAGARI LETTER PHA;Lo;0;L;;;;;N;;;;; +119C4;NANDINAGARI LETTER BA;Lo;0;L;;;;;N;;;;; +119C5;NANDINAGARI LETTER BHA;Lo;0;L;;;;;N;;;;; +119C6;NANDINAGARI LETTER MA;Lo;0;L;;;;;N;;;;; +119C7;NANDINAGARI LETTER YA;Lo;0;L;;;;;N;;;;; +119C8;NANDINAGARI LETTER RA;Lo;0;L;;;;;N;;;;; +119C9;NANDINAGARI LETTER LA;Lo;0;L;;;;;N;;;;; +119CA;NANDINAGARI LETTER VA;Lo;0;L;;;;;N;;;;; +119CB;NANDINAGARI LETTER SHA;Lo;0;L;;;;;N;;;;; +119CC;NANDINAGARI LETTER SSA;Lo;0;L;;;;;N;;;;; +119CD;NANDINAGARI LETTER SA;Lo;0;L;;;;;N;;;;; +119CE;NANDINAGARI LETTER HA;Lo;0;L;;;;;N;;;;; +119CF;NANDINAGARI LETTER LLA;Lo;0;L;;;;;N;;;;; +119D0;NANDINAGARI LETTER RRA;Lo;0;L;;;;;N;;;;; +119D1;NANDINAGARI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +119D2;NANDINAGARI VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +119D3;NANDINAGARI VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +119D4;NANDINAGARI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +119D5;NANDINAGARI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +119D6;NANDINAGARI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; +119D7;NANDINAGARI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;; +119DA;NANDINAGARI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +119DB;NANDINAGARI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; +119DC;NANDINAGARI VOWEL SIGN O;Mc;0;L;;;;;N;;;;; +119DD;NANDINAGARI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;; +119DE;NANDINAGARI SIGN ANUSVARA;Mc;0;L;;;;;N;;;;; +119DF;NANDINAGARI SIGN VISARGA;Mc;0;L;;;;;N;;;;; +119E0;NANDINAGARI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +119E1;NANDINAGARI SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;; +119E2;NANDINAGARI SIGN SIDDHAM;Po;0;L;;;;;N;;;;; +119E3;NANDINAGARI HEADSTROKE;Lo;0;L;;;;;N;;;;; +119E4;NANDINAGARI VOWEL SIGN PRISHTHAMATRA E;Mc;0;L;;;;;N;;;;; +11A00;ZANABAZAR SQUARE LETTER A;Lo;0;L;;;;;N;;;;; +11A01;ZANABAZAR SQUARE VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +11A02;ZANABAZAR SQUARE VOWEL SIGN UE;Mn;0;NSM;;;;;N;;;;; +11A03;ZANABAZAR SQUARE VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +11A04;ZANABAZAR SQUARE VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +11A05;ZANABAZAR SQUARE VOWEL SIGN OE;Mn;0;NSM;;;;;N;;;;; +11A06;ZANABAZAR SQUARE VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;; +11A07;ZANABAZAR SQUARE VOWEL SIGN AI;Mn;0;L;;;;;N;;;;; +11A08;ZANABAZAR SQUARE VOWEL SIGN AU;Mn;0;L;;;;;N;;;;; +11A09;ZANABAZAR SQUARE VOWEL SIGN REVERSED I;Mn;0;NSM;;;;;N;;;;; +11A0A;ZANABAZAR SQUARE VOWEL LENGTH MARK;Mn;0;NSM;;;;;N;;;;; +11A0B;ZANABAZAR SQUARE LETTER KA;Lo;0;L;;;;;N;;;;; +11A0C;ZANABAZAR SQUARE LETTER KHA;Lo;0;L;;;;;N;;;;; +11A0D;ZANABAZAR SQUARE LETTER GA;Lo;0;L;;;;;N;;;;; +11A0E;ZANABAZAR SQUARE LETTER GHA;Lo;0;L;;;;;N;;;;; +11A0F;ZANABAZAR SQUARE LETTER NGA;Lo;0;L;;;;;N;;;;; +11A10;ZANABAZAR SQUARE LETTER CA;Lo;0;L;;;;;N;;;;; +11A11;ZANABAZAR SQUARE LETTER CHA;Lo;0;L;;;;;N;;;;; +11A12;ZANABAZAR SQUARE LETTER JA;Lo;0;L;;;;;N;;;;; +11A13;ZANABAZAR SQUARE LETTER NYA;Lo;0;L;;;;;N;;;;; +11A14;ZANABAZAR SQUARE LETTER TTA;Lo;0;L;;;;;N;;;;; +11A15;ZANABAZAR SQUARE LETTER TTHA;Lo;0;L;;;;;N;;;;; +11A16;ZANABAZAR SQUARE LETTER DDA;Lo;0;L;;;;;N;;;;; +11A17;ZANABAZAR SQUARE LETTER DDHA;Lo;0;L;;;;;N;;;;; +11A18;ZANABAZAR SQUARE LETTER NNA;Lo;0;L;;;;;N;;;;; +11A19;ZANABAZAR SQUARE LETTER TA;Lo;0;L;;;;;N;;;;; +11A1A;ZANABAZAR SQUARE LETTER THA;Lo;0;L;;;;;N;;;;; +11A1B;ZANABAZAR SQUARE LETTER DA;Lo;0;L;;;;;N;;;;; +11A1C;ZANABAZAR SQUARE LETTER DHA;Lo;0;L;;;;;N;;;;; +11A1D;ZANABAZAR SQUARE LETTER NA;Lo;0;L;;;;;N;;;;; +11A1E;ZANABAZAR SQUARE LETTER PA;Lo;0;L;;;;;N;;;;; +11A1F;ZANABAZAR SQUARE LETTER PHA;Lo;0;L;;;;;N;;;;; +11A20;ZANABAZAR SQUARE LETTER BA;Lo;0;L;;;;;N;;;;; +11A21;ZANABAZAR SQUARE LETTER BHA;Lo;0;L;;;;;N;;;;; +11A22;ZANABAZAR SQUARE LETTER MA;Lo;0;L;;;;;N;;;;; +11A23;ZANABAZAR SQUARE LETTER TSA;Lo;0;L;;;;;N;;;;; +11A24;ZANABAZAR SQUARE LETTER TSHA;Lo;0;L;;;;;N;;;;; +11A25;ZANABAZAR SQUARE LETTER DZA;Lo;0;L;;;;;N;;;;; +11A26;ZANABAZAR SQUARE LETTER DZHA;Lo;0;L;;;;;N;;;;; +11A27;ZANABAZAR SQUARE LETTER ZHA;Lo;0;L;;;;;N;;;;; +11A28;ZANABAZAR SQUARE LETTER ZA;Lo;0;L;;;;;N;;;;; +11A29;ZANABAZAR SQUARE LETTER -A;Lo;0;L;;;;;N;;;;; +11A2A;ZANABAZAR SQUARE LETTER YA;Lo;0;L;;;;;N;;;;; +11A2B;ZANABAZAR SQUARE LETTER RA;Lo;0;L;;;;;N;;;;; +11A2C;ZANABAZAR SQUARE LETTER LA;Lo;0;L;;;;;N;;;;; +11A2D;ZANABAZAR SQUARE LETTER VA;Lo;0;L;;;;;N;;;;; +11A2E;ZANABAZAR SQUARE LETTER SHA;Lo;0;L;;;;;N;;;;; +11A2F;ZANABAZAR SQUARE LETTER SSA;Lo;0;L;;;;;N;;;;; +11A30;ZANABAZAR SQUARE LETTER SA;Lo;0;L;;;;;N;;;;; +11A31;ZANABAZAR SQUARE LETTER HA;Lo;0;L;;;;;N;;;;; +11A32;ZANABAZAR SQUARE LETTER KSSA;Lo;0;L;;;;;N;;;;; +11A33;ZANABAZAR SQUARE FINAL CONSONANT MARK;Mn;0;NSM;;;;;N;;;;; +11A34;ZANABAZAR SQUARE SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +11A35;ZANABAZAR SQUARE SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; +11A36;ZANABAZAR SQUARE SIGN CANDRABINDU WITH ORNAMENT;Mn;0;NSM;;;;;N;;;;; +11A37;ZANABAZAR SQUARE SIGN CANDRA WITH ORNAMENT;Mn;0;NSM;;;;;N;;;;; +11A38;ZANABAZAR SQUARE SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +11A39;ZANABAZAR SQUARE SIGN VISARGA;Mc;0;L;;;;;N;;;;; +11A3A;ZANABAZAR SQUARE CLUSTER-INITIAL LETTER RA;Lo;0;L;;;;;N;;;;; +11A3B;ZANABAZAR SQUARE CLUSTER-FINAL LETTER YA;Mn;0;NSM;;;;;N;;;;; +11A3C;ZANABAZAR SQUARE CLUSTER-FINAL LETTER RA;Mn;0;NSM;;;;;N;;;;; +11A3D;ZANABAZAR SQUARE CLUSTER-FINAL LETTER LA;Mn;0;NSM;;;;;N;;;;; +11A3E;ZANABAZAR SQUARE CLUSTER-FINAL LETTER VA;Mn;0;NSM;;;;;N;;;;; +11A3F;ZANABAZAR SQUARE INITIAL HEAD MARK;Po;0;L;;;;;N;;;;; +11A40;ZANABAZAR SQUARE CLOSING HEAD MARK;Po;0;L;;;;;N;;;;; +11A41;ZANABAZAR SQUARE MARK TSHEG;Po;0;L;;;;;N;;;;; +11A42;ZANABAZAR SQUARE MARK SHAD;Po;0;L;;;;;N;;;;; +11A43;ZANABAZAR SQUARE MARK DOUBLE SHAD;Po;0;L;;;;;N;;;;; +11A44;ZANABAZAR SQUARE MARK LONG TSHEG;Po;0;L;;;;;N;;;;; +11A45;ZANABAZAR SQUARE INITIAL DOUBLE-LINED HEAD MARK;Po;0;L;;;;;N;;;;; +11A46;ZANABAZAR SQUARE CLOSING DOUBLE-LINED HEAD MARK;Po;0;L;;;;;N;;;;; +11A47;ZANABAZAR SQUARE SUBJOINER;Mn;9;NSM;;;;;N;;;;; +11A50;SOYOMBO LETTER A;Lo;0;L;;;;;N;;;;; +11A51;SOYOMBO VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +11A52;SOYOMBO VOWEL SIGN UE;Mn;0;NSM;;;;;N;;;;; +11A53;SOYOMBO VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +11A54;SOYOMBO VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +11A55;SOYOMBO VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;; +11A56;SOYOMBO VOWEL SIGN OE;Mn;0;NSM;;;;;N;;;;; +11A57;SOYOMBO VOWEL SIGN AI;Mc;0;L;;;;;N;;;;; +11A58;SOYOMBO VOWEL SIGN AU;Mc;0;L;;;;;N;;;;; +11A59;SOYOMBO VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; +11A5A;SOYOMBO VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;; +11A5B;SOYOMBO VOWEL LENGTH MARK;Mn;0;NSM;;;;;N;;;;; +11A5C;SOYOMBO LETTER KA;Lo;0;L;;;;;N;;;;; +11A5D;SOYOMBO LETTER KHA;Lo;0;L;;;;;N;;;;; +11A5E;SOYOMBO LETTER GA;Lo;0;L;;;;;N;;;;; +11A5F;SOYOMBO LETTER GHA;Lo;0;L;;;;;N;;;;; +11A60;SOYOMBO LETTER NGA;Lo;0;L;;;;;N;;;;; +11A61;SOYOMBO LETTER CA;Lo;0;L;;;;;N;;;;; +11A62;SOYOMBO LETTER CHA;Lo;0;L;;;;;N;;;;; +11A63;SOYOMBO LETTER JA;Lo;0;L;;;;;N;;;;; +11A64;SOYOMBO LETTER JHA;Lo;0;L;;;;;N;;;;; +11A65;SOYOMBO LETTER NYA;Lo;0;L;;;;;N;;;;; +11A66;SOYOMBO LETTER TTA;Lo;0;L;;;;;N;;;;; +11A67;SOYOMBO LETTER TTHA;Lo;0;L;;;;;N;;;;; +11A68;SOYOMBO LETTER DDA;Lo;0;L;;;;;N;;;;; +11A69;SOYOMBO LETTER DDHA;Lo;0;L;;;;;N;;;;; +11A6A;SOYOMBO LETTER NNA;Lo;0;L;;;;;N;;;;; +11A6B;SOYOMBO LETTER TA;Lo;0;L;;;;;N;;;;; +11A6C;SOYOMBO LETTER THA;Lo;0;L;;;;;N;;;;; +11A6D;SOYOMBO LETTER DA;Lo;0;L;;;;;N;;;;; +11A6E;SOYOMBO LETTER DHA;Lo;0;L;;;;;N;;;;; +11A6F;SOYOMBO LETTER NA;Lo;0;L;;;;;N;;;;; +11A70;SOYOMBO LETTER PA;Lo;0;L;;;;;N;;;;; +11A71;SOYOMBO LETTER PHA;Lo;0;L;;;;;N;;;;; +11A72;SOYOMBO LETTER BA;Lo;0;L;;;;;N;;;;; +11A73;SOYOMBO LETTER BHA;Lo;0;L;;;;;N;;;;; +11A74;SOYOMBO LETTER MA;Lo;0;L;;;;;N;;;;; +11A75;SOYOMBO LETTER TSA;Lo;0;L;;;;;N;;;;; +11A76;SOYOMBO LETTER TSHA;Lo;0;L;;;;;N;;;;; +11A77;SOYOMBO LETTER DZA;Lo;0;L;;;;;N;;;;; +11A78;SOYOMBO LETTER ZHA;Lo;0;L;;;;;N;;;;; +11A79;SOYOMBO LETTER ZA;Lo;0;L;;;;;N;;;;; +11A7A;SOYOMBO LETTER -A;Lo;0;L;;;;;N;;;;; +11A7B;SOYOMBO LETTER YA;Lo;0;L;;;;;N;;;;; +11A7C;SOYOMBO LETTER RA;Lo;0;L;;;;;N;;;;; +11A7D;SOYOMBO LETTER LA;Lo;0;L;;;;;N;;;;; +11A7E;SOYOMBO LETTER VA;Lo;0;L;;;;;N;;;;; +11A7F;SOYOMBO LETTER SHA;Lo;0;L;;;;;N;;;;; +11A80;SOYOMBO LETTER SSA;Lo;0;L;;;;;N;;;;; +11A81;SOYOMBO LETTER SA;Lo;0;L;;;;;N;;;;; +11A82;SOYOMBO LETTER HA;Lo;0;L;;;;;N;;;;; +11A83;SOYOMBO LETTER KSSA;Lo;0;L;;;;;N;;;;; +11A84;SOYOMBO SIGN JIHVAMULIYA;Lo;0;L;;;;;N;;;;; +11A85;SOYOMBO SIGN UPADHMANIYA;Lo;0;L;;;;;N;;;;; +11A86;SOYOMBO CLUSTER-INITIAL LETTER RA;Lo;0;L;;;;;N;;;;; +11A87;SOYOMBO CLUSTER-INITIAL LETTER LA;Lo;0;L;;;;;N;;;;; +11A88;SOYOMBO CLUSTER-INITIAL LETTER SHA;Lo;0;L;;;;;N;;;;; +11A89;SOYOMBO CLUSTER-INITIAL LETTER SA;Lo;0;L;;;;;N;;;;; +11A8A;SOYOMBO FINAL CONSONANT SIGN G;Mn;0;NSM;;;;;N;;;;; +11A8B;SOYOMBO FINAL CONSONANT SIGN K;Mn;0;NSM;;;;;N;;;;; +11A8C;SOYOMBO FINAL CONSONANT SIGN NG;Mn;0;NSM;;;;;N;;;;; +11A8D;SOYOMBO FINAL CONSONANT SIGN D;Mn;0;NSM;;;;;N;;;;; +11A8E;SOYOMBO FINAL CONSONANT SIGN N;Mn;0;NSM;;;;;N;;;;; +11A8F;SOYOMBO FINAL CONSONANT SIGN B;Mn;0;NSM;;;;;N;;;;; +11A90;SOYOMBO FINAL CONSONANT SIGN M;Mn;0;NSM;;;;;N;;;;; +11A91;SOYOMBO FINAL CONSONANT SIGN R;Mn;0;NSM;;;;;N;;;;; +11A92;SOYOMBO FINAL CONSONANT SIGN L;Mn;0;NSM;;;;;N;;;;; +11A93;SOYOMBO FINAL CONSONANT SIGN SH;Mn;0;NSM;;;;;N;;;;; +11A94;SOYOMBO FINAL CONSONANT SIGN S;Mn;0;NSM;;;;;N;;;;; +11A95;SOYOMBO FINAL CONSONANT SIGN -A;Mn;0;NSM;;;;;N;;;;; +11A96;SOYOMBO SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +11A97;SOYOMBO SIGN VISARGA;Mc;0;L;;;;;N;;;;; +11A98;SOYOMBO GEMINATION MARK;Mn;0;NSM;;;;;N;;;;; +11A99;SOYOMBO SUBJOINER;Mn;9;NSM;;;;;N;;;;; +11A9A;SOYOMBO MARK TSHEG;Po;0;L;;;;;N;;;;; +11A9B;SOYOMBO MARK SHAD;Po;0;L;;;;;N;;;;; +11A9C;SOYOMBO MARK DOUBLE SHAD;Po;0;L;;;;;N;;;;; +11A9D;SOYOMBO MARK PLUTA;Lo;0;L;;;;;N;;;;; +11A9E;SOYOMBO HEAD MARK WITH MOON AND SUN AND TRIPLE FLAME;Po;0;L;;;;;N;;;;; +11A9F;SOYOMBO HEAD MARK WITH MOON AND SUN AND FLAME;Po;0;L;;;;;N;;;;; +11AA0;SOYOMBO HEAD MARK WITH MOON AND SUN;Po;0;L;;;;;N;;;;; +11AA1;SOYOMBO TERMINAL MARK-1;Po;0;L;;;;;N;;;;; +11AA2;SOYOMBO TERMINAL MARK-2;Po;0;L;;;;;N;;;;; 11AC0;PAU CIN HAU LETTER PA;Lo;0;L;;;;;N;;;;; 11AC1;PAU CIN HAU LETTER KA;Lo;0;L;;;;;N;;;;; 11AC2;PAU CIN HAU LETTER LA;Lo;0;L;;;;;N;;;;; @@ -20290,6 +21111,221 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 11CB4;MARCHEN VOWEL SIGN O;Mc;0;L;;;;;N;;;;; 11CB5;MARCHEN SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; 11CB6;MARCHEN SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;; +11D00;MASARAM GONDI LETTER A;Lo;0;L;;;;;N;;;;; +11D01;MASARAM GONDI LETTER AA;Lo;0;L;;;;;N;;;;; +11D02;MASARAM GONDI LETTER I;Lo;0;L;;;;;N;;;;; +11D03;MASARAM GONDI LETTER II;Lo;0;L;;;;;N;;;;; +11D04;MASARAM GONDI LETTER U;Lo;0;L;;;;;N;;;;; +11D05;MASARAM GONDI LETTER UU;Lo;0;L;;;;;N;;;;; +11D06;MASARAM GONDI LETTER E;Lo;0;L;;;;;N;;;;; +11D08;MASARAM GONDI LETTER AI;Lo;0;L;;;;;N;;;;; +11D09;MASARAM GONDI LETTER O;Lo;0;L;;;;;N;;;;; +11D0B;MASARAM GONDI LETTER AU;Lo;0;L;;;;;N;;;;; +11D0C;MASARAM GONDI LETTER KA;Lo;0;L;;;;;N;;;;; +11D0D;MASARAM GONDI LETTER KHA;Lo;0;L;;;;;N;;;;; +11D0E;MASARAM GONDI LETTER GA;Lo;0;L;;;;;N;;;;; +11D0F;MASARAM GONDI LETTER GHA;Lo;0;L;;;;;N;;;;; +11D10;MASARAM GONDI LETTER NGA;Lo;0;L;;;;;N;;;;; +11D11;MASARAM GONDI LETTER CA;Lo;0;L;;;;;N;;;;; +11D12;MASARAM GONDI LETTER CHA;Lo;0;L;;;;;N;;;;; +11D13;MASARAM GONDI LETTER JA;Lo;0;L;;;;;N;;;;; +11D14;MASARAM GONDI LETTER JHA;Lo;0;L;;;;;N;;;;; +11D15;MASARAM GONDI LETTER NYA;Lo;0;L;;;;;N;;;;; +11D16;MASARAM GONDI LETTER TTA;Lo;0;L;;;;;N;;;;; +11D17;MASARAM GONDI LETTER TTHA;Lo;0;L;;;;;N;;;;; +11D18;MASARAM GONDI LETTER DDA;Lo;0;L;;;;;N;;;;; +11D19;MASARAM GONDI LETTER DDHA;Lo;0;L;;;;;N;;;;; +11D1A;MASARAM GONDI LETTER NNA;Lo;0;L;;;;;N;;;;; +11D1B;MASARAM GONDI LETTER TA;Lo;0;L;;;;;N;;;;; +11D1C;MASARAM GONDI LETTER THA;Lo;0;L;;;;;N;;;;; +11D1D;MASARAM GONDI LETTER DA;Lo;0;L;;;;;N;;;;; +11D1E;MASARAM GONDI LETTER DHA;Lo;0;L;;;;;N;;;;; +11D1F;MASARAM GONDI LETTER NA;Lo;0;L;;;;;N;;;;; +11D20;MASARAM GONDI LETTER PA;Lo;0;L;;;;;N;;;;; +11D21;MASARAM GONDI LETTER PHA;Lo;0;L;;;;;N;;;;; +11D22;MASARAM GONDI LETTER BA;Lo;0;L;;;;;N;;;;; +11D23;MASARAM GONDI LETTER BHA;Lo;0;L;;;;;N;;;;; +11D24;MASARAM GONDI LETTER MA;Lo;0;L;;;;;N;;;;; +11D25;MASARAM GONDI LETTER YA;Lo;0;L;;;;;N;;;;; +11D26;MASARAM GONDI LETTER RA;Lo;0;L;;;;;N;;;;; +11D27;MASARAM GONDI LETTER LA;Lo;0;L;;;;;N;;;;; +11D28;MASARAM GONDI LETTER VA;Lo;0;L;;;;;N;;;;; +11D29;MASARAM GONDI LETTER SHA;Lo;0;L;;;;;N;;;;; +11D2A;MASARAM GONDI LETTER SSA;Lo;0;L;;;;;N;;;;; +11D2B;MASARAM GONDI LETTER SA;Lo;0;L;;;;;N;;;;; +11D2C;MASARAM GONDI LETTER HA;Lo;0;L;;;;;N;;;;; +11D2D;MASARAM GONDI LETTER LLA;Lo;0;L;;;;;N;;;;; +11D2E;MASARAM GONDI LETTER KSSA;Lo;0;L;;;;;N;;;;; +11D2F;MASARAM GONDI LETTER JNYA;Lo;0;L;;;;;N;;;;; +11D30;MASARAM GONDI LETTER TRA;Lo;0;L;;;;;N;;;;; +11D31;MASARAM GONDI VOWEL SIGN AA;Mn;0;NSM;;;;;N;;;;; +11D32;MASARAM GONDI VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +11D33;MASARAM GONDI VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;; +11D34;MASARAM GONDI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +11D35;MASARAM GONDI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +11D36;MASARAM GONDI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; +11D3A;MASARAM GONDI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;; +11D3C;MASARAM GONDI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; +11D3D;MASARAM GONDI VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;; +11D3F;MASARAM GONDI VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;; +11D40;MASARAM GONDI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +11D41;MASARAM GONDI SIGN VISARGA;Mn;0;NSM;;;;;N;;;;; +11D42;MASARAM GONDI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;; +11D43;MASARAM GONDI SIGN CANDRA;Mn;0;NSM;;;;;N;;;;; +11D44;MASARAM GONDI SIGN HALANTA;Mn;9;NSM;;;;;N;;;;; +11D45;MASARAM GONDI VIRAMA;Mn;9;NSM;;;;;N;;;;; +11D46;MASARAM GONDI REPHA;Lo;0;L;;;;;N;;;;; +11D47;MASARAM GONDI RA-KARA;Mn;0;NSM;;;;;N;;;;; +11D50;MASARAM GONDI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +11D51;MASARAM GONDI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +11D52;MASARAM GONDI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +11D53;MASARAM GONDI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +11D54;MASARAM GONDI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +11D55;MASARAM GONDI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +11D56;MASARAM GONDI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +11D57;MASARAM GONDI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +11D58;MASARAM GONDI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +11D59;MASARAM GONDI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +11D60;GUNJALA GONDI LETTER A;Lo;0;L;;;;;N;;;;; +11D61;GUNJALA GONDI LETTER AA;Lo;0;L;;;;;N;;;;; +11D62;GUNJALA GONDI LETTER I;Lo;0;L;;;;;N;;;;; +11D63;GUNJALA GONDI LETTER II;Lo;0;L;;;;;N;;;;; +11D64;GUNJALA GONDI LETTER U;Lo;0;L;;;;;N;;;;; +11D65;GUNJALA GONDI LETTER UU;Lo;0;L;;;;;N;;;;; +11D67;GUNJALA GONDI LETTER EE;Lo;0;L;;;;;N;;;;; +11D68;GUNJALA GONDI LETTER AI;Lo;0;L;;;;;N;;;;; +11D6A;GUNJALA GONDI LETTER OO;Lo;0;L;;;;;N;;;;; +11D6B;GUNJALA GONDI LETTER AU;Lo;0;L;;;;;N;;;;; +11D6C;GUNJALA GONDI LETTER YA;Lo;0;L;;;;;N;;;;; +11D6D;GUNJALA GONDI LETTER VA;Lo;0;L;;;;;N;;;;; +11D6E;GUNJALA GONDI LETTER BA;Lo;0;L;;;;;N;;;;; +11D6F;GUNJALA GONDI LETTER BHA;Lo;0;L;;;;;N;;;;; +11D70;GUNJALA GONDI LETTER MA;Lo;0;L;;;;;N;;;;; +11D71;GUNJALA GONDI LETTER KA;Lo;0;L;;;;;N;;;;; +11D72;GUNJALA GONDI LETTER KHA;Lo;0;L;;;;;N;;;;; +11D73;GUNJALA GONDI LETTER TA;Lo;0;L;;;;;N;;;;; +11D74;GUNJALA GONDI LETTER THA;Lo;0;L;;;;;N;;;;; +11D75;GUNJALA GONDI LETTER LA;Lo;0;L;;;;;N;;;;; +11D76;GUNJALA GONDI LETTER GA;Lo;0;L;;;;;N;;;;; +11D77;GUNJALA GONDI LETTER GHA;Lo;0;L;;;;;N;;;;; +11D78;GUNJALA GONDI LETTER DA;Lo;0;L;;;;;N;;;;; +11D79;GUNJALA GONDI LETTER DHA;Lo;0;L;;;;;N;;;;; +11D7A;GUNJALA GONDI LETTER NA;Lo;0;L;;;;;N;;;;; +11D7B;GUNJALA GONDI LETTER CA;Lo;0;L;;;;;N;;;;; +11D7C;GUNJALA GONDI LETTER CHA;Lo;0;L;;;;;N;;;;; +11D7D;GUNJALA GONDI LETTER TTA;Lo;0;L;;;;;N;;;;; +11D7E;GUNJALA GONDI LETTER TTHA;Lo;0;L;;;;;N;;;;; +11D7F;GUNJALA GONDI LETTER LLA;Lo;0;L;;;;;N;;;;; +11D80;GUNJALA GONDI LETTER JA;Lo;0;L;;;;;N;;;;; +11D81;GUNJALA GONDI LETTER JHA;Lo;0;L;;;;;N;;;;; +11D82;GUNJALA GONDI LETTER DDA;Lo;0;L;;;;;N;;;;; +11D83;GUNJALA GONDI LETTER DDHA;Lo;0;L;;;;;N;;;;; +11D84;GUNJALA GONDI LETTER NGA;Lo;0;L;;;;;N;;;;; +11D85;GUNJALA GONDI LETTER PA;Lo;0;L;;;;;N;;;;; +11D86;GUNJALA GONDI LETTER PHA;Lo;0;L;;;;;N;;;;; +11D87;GUNJALA GONDI LETTER HA;Lo;0;L;;;;;N;;;;; +11D88;GUNJALA GONDI LETTER RA;Lo;0;L;;;;;N;;;;; +11D89;GUNJALA GONDI LETTER SA;Lo;0;L;;;;;N;;;;; +11D8A;GUNJALA GONDI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +11D8B;GUNJALA GONDI VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +11D8C;GUNJALA GONDI VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +11D8D;GUNJALA GONDI VOWEL SIGN U;Mc;0;L;;;;;N;;;;; +11D8E;GUNJALA GONDI VOWEL SIGN UU;Mc;0;L;;;;;N;;;;; +11D90;GUNJALA GONDI VOWEL SIGN EE;Mn;0;NSM;;;;;N;;;;; +11D91;GUNJALA GONDI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;; +11D93;GUNJALA GONDI VOWEL SIGN OO;Mc;0;L;;;;;N;;;;; +11D94;GUNJALA GONDI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;; +11D95;GUNJALA GONDI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +11D96;GUNJALA GONDI SIGN VISARGA;Mc;0;L;;;;;N;;;;; +11D97;GUNJALA GONDI VIRAMA;Mn;9;NSM;;;;;N;;;;; +11D98;GUNJALA GONDI OM;Lo;0;L;;;;;N;;;;; +11DA0;GUNJALA GONDI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +11DA1;GUNJALA GONDI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +11DA2;GUNJALA GONDI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +11DA3;GUNJALA GONDI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +11DA4;GUNJALA GONDI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +11DA5;GUNJALA GONDI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +11DA6;GUNJALA GONDI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +11DA7;GUNJALA GONDI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +11DA8;GUNJALA GONDI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +11DA9;GUNJALA GONDI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +11EE0;MAKASAR LETTER KA;Lo;0;L;;;;;N;;;;; +11EE1;MAKASAR LETTER GA;Lo;0;L;;;;;N;;;;; +11EE2;MAKASAR LETTER NGA;Lo;0;L;;;;;N;;;;; +11EE3;MAKASAR LETTER PA;Lo;0;L;;;;;N;;;;; +11EE4;MAKASAR LETTER BA;Lo;0;L;;;;;N;;;;; +11EE5;MAKASAR LETTER MA;Lo;0;L;;;;;N;;;;; +11EE6;MAKASAR LETTER TA;Lo;0;L;;;;;N;;;;; +11EE7;MAKASAR LETTER DA;Lo;0;L;;;;;N;;;;; +11EE8;MAKASAR LETTER NA;Lo;0;L;;;;;N;;;;; +11EE9;MAKASAR LETTER CA;Lo;0;L;;;;;N;;;;; +11EEA;MAKASAR LETTER JA;Lo;0;L;;;;;N;;;;; +11EEB;MAKASAR LETTER NYA;Lo;0;L;;;;;N;;;;; +11EEC;MAKASAR LETTER YA;Lo;0;L;;;;;N;;;;; +11EED;MAKASAR LETTER RA;Lo;0;L;;;;;N;;;;; +11EEE;MAKASAR LETTER LA;Lo;0;L;;;;;N;;;;; +11EEF;MAKASAR LETTER VA;Lo;0;L;;;;;N;;;;; +11EF0;MAKASAR LETTER SA;Lo;0;L;;;;;N;;;;; +11EF1;MAKASAR LETTER A;Lo;0;L;;;;;N;;;;; +11EF2;MAKASAR ANGKA;Lo;0;L;;;;;N;;;;; +11EF3;MAKASAR VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +11EF4;MAKASAR VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +11EF5;MAKASAR VOWEL SIGN E;Mc;0;L;;;;;N;;;;; +11EF6;MAKASAR VOWEL SIGN O;Mc;0;L;;;;;N;;;;; +11EF7;MAKASAR PASSIMBANG;Po;0;L;;;;;N;;;;; +11EF8;MAKASAR END OF SECTION;Po;0;L;;;;;N;;;;; +11FB0;LISU LETTER YHA;Lo;0;L;;;;;N;;;;; +11FC0;TAMIL FRACTION ONE THREE-HUNDRED-AND-TWENTIETH;No;0;L;;;;1/320;N;;;;; +11FC1;TAMIL FRACTION ONE ONE-HUNDRED-AND-SIXTIETH;No;0;L;;;;1/160;N;;;;; +11FC2;TAMIL FRACTION ONE EIGHTIETH;No;0;L;;;;1/80;N;;;;; +11FC3;TAMIL FRACTION ONE SIXTY-FOURTH;No;0;L;;;;1/64;N;;;;; +11FC4;TAMIL FRACTION ONE FORTIETH;No;0;L;;;;1/40;N;;;;; +11FC5;TAMIL FRACTION ONE THIRTY-SECOND;No;0;L;;;;1/32;N;;;;; +11FC6;TAMIL FRACTION THREE EIGHTIETHS;No;0;L;;;;3/80;N;;;;; +11FC7;TAMIL FRACTION THREE SIXTY-FOURTHS;No;0;L;;;;3/64;N;;;;; +11FC8;TAMIL FRACTION ONE TWENTIETH;No;0;L;;;;1/20;N;;;;; +11FC9;TAMIL FRACTION ONE SIXTEENTH-1;No;0;L;;;;1/16;N;;;;; +11FCA;TAMIL FRACTION ONE SIXTEENTH-2;No;0;L;;;;1/16;N;;;;; +11FCB;TAMIL FRACTION ONE TENTH;No;0;L;;;;1/10;N;;;;; +11FCC;TAMIL FRACTION ONE EIGHTH;No;0;L;;;;1/8;N;;;;; +11FCD;TAMIL FRACTION THREE TWENTIETHS;No;0;L;;;;3/20;N;;;;; +11FCE;TAMIL FRACTION THREE SIXTEENTHS;No;0;L;;;;3/16;N;;;;; +11FCF;TAMIL FRACTION ONE FIFTH;No;0;L;;;;1/5;N;;;;; +11FD0;TAMIL FRACTION ONE QUARTER;No;0;L;;;;1/4;N;;;;; +11FD1;TAMIL FRACTION ONE HALF-1;No;0;L;;;;1/2;N;;;;; +11FD2;TAMIL FRACTION ONE HALF-2;No;0;L;;;;1/2;N;;;;; +11FD3;TAMIL FRACTION THREE QUARTERS;No;0;L;;;;3/4;N;;;;; +11FD4;TAMIL FRACTION DOWNSCALING FACTOR KIIZH;No;0;L;;;;1/320;N;;;;; +11FD5;TAMIL SIGN NEL;So;0;ON;;;;;N;;;;; +11FD6;TAMIL SIGN CEVITU;So;0;ON;;;;;N;;;;; +11FD7;TAMIL SIGN AAZHAAKKU;So;0;ON;;;;;N;;;;; +11FD8;TAMIL SIGN UZHAKKU;So;0;ON;;;;;N;;;;; +11FD9;TAMIL SIGN MUUVUZHAKKU;So;0;ON;;;;;N;;;;; +11FDA;TAMIL SIGN KURUNI;So;0;ON;;;;;N;;;;; +11FDB;TAMIL SIGN PATHAKKU;So;0;ON;;;;;N;;;;; +11FDC;TAMIL SIGN MUKKURUNI;So;0;ON;;;;;N;;;;; +11FDD;TAMIL SIGN KAACU;Sc;0;ET;;;;;N;;;;; +11FDE;TAMIL SIGN PANAM;Sc;0;ET;;;;;N;;;;; +11FDF;TAMIL SIGN PON;Sc;0;ET;;;;;N;;;;; +11FE0;TAMIL SIGN VARAAKAN;Sc;0;ET;;;;;N;;;;; +11FE1;TAMIL SIGN PAARAM;So;0;ON;;;;;N;;;;; +11FE2;TAMIL SIGN KUZHI;So;0;ON;;;;;N;;;;; +11FE3;TAMIL SIGN VELI;So;0;ON;;;;;N;;;;; +11FE4;TAMIL WET CULTIVATION SIGN;So;0;ON;;;;;N;;;;; +11FE5;TAMIL DRY CULTIVATION SIGN;So;0;ON;;;;;N;;;;; +11FE6;TAMIL LAND SIGN;So;0;ON;;;;;N;;;;; +11FE7;TAMIL SALT PAN SIGN;So;0;ON;;;;;N;;;;; +11FE8;TAMIL TRADITIONAL CREDIT SIGN;So;0;ON;;;;;N;;;;; +11FE9;TAMIL TRADITIONAL NUMBER SIGN;So;0;ON;;;;;N;;;;; +11FEA;TAMIL CURRENT SIGN;So;0;ON;;;;;N;;;;; +11FEB;TAMIL AND ODD SIGN;So;0;ON;;;;;N;;;;; +11FEC;TAMIL SPENT SIGN;So;0;ON;;;;;N;;;;; +11FED;TAMIL TOTAL SIGN;So;0;ON;;;;;N;;;;; +11FEE;TAMIL IN POSSESSION SIGN;So;0;ON;;;;;N;;;;; +11FEF;TAMIL STARTING FROM SIGN;So;0;ON;;;;;N;;;;; +11FF0;TAMIL SIGN MUTHALIYA;So;0;ON;;;;;N;;;;; +11FF1;TAMIL SIGN VAKAIYARAA;So;0;ON;;;;;N;;;;; +11FFF;TAMIL PUNCTUATION END OF TEXT;Po;0;L;;;;;N;;;;; 12000;CUNEIFORM SIGN A;Lo;0;L;;;;;N;;;;; 12001;CUNEIFORM SIGN A TIMES A;Lo;0;L;;;;;N;;;;; 12002;CUNEIFORM SIGN A TIMES BAD;Lo;0;L;;;;;N;;;;; @@ -22595,6 +23631,15 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1342C;EGYPTIAN HIEROGLYPH AA030;Lo;0;L;;;;;N;;;;; 1342D;EGYPTIAN HIEROGLYPH AA031;Lo;0;L;;;;;N;;;;; 1342E;EGYPTIAN HIEROGLYPH AA032;Lo;0;L;;;;;N;;;;; +13430;EGYPTIAN HIEROGLYPH VERTICAL JOINER;Cf;0;L;;;;;N;;;;; +13431;EGYPTIAN HIEROGLYPH HORIZONTAL JOINER;Cf;0;L;;;;;N;;;;; +13432;EGYPTIAN HIEROGLYPH INSERT AT TOP START;Cf;0;L;;;;;N;;;;; +13433;EGYPTIAN HIEROGLYPH INSERT AT BOTTOM START;Cf;0;L;;;;;N;;;;; +13434;EGYPTIAN HIEROGLYPH INSERT AT TOP END;Cf;0;L;;;;;N;;;;; +13435;EGYPTIAN HIEROGLYPH INSERT AT BOTTOM END;Cf;0;L;;;;;N;;;;; +13436;EGYPTIAN HIEROGLYPH OVERLAY MIDDLE;Cf;0;L;;;;;N;;;;; +13437;EGYPTIAN HIEROGLYPH BEGIN SEGMENT;Cf;0;L;;;;;N;;;;; +13438;EGYPTIAN HIEROGLYPH END SEGMENT;Cf;0;L;;;;;N;;;;; 14400;ANATOLIAN HIEROGLYPH A001;Lo;0;L;;;;;N;;;;; 14401;ANATOLIAN HIEROGLYPH A002;Lo;0;L;;;;;N;;;;; 14402;ANATOLIAN HIEROGLYPH A003;Lo;0;L;;;;;N;;;;; @@ -23953,6 +24998,97 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 16B8D;PAHAWH HMONG CLAN SIGN TSWB;Lo;0;L;;;;;N;;;;; 16B8E;PAHAWH HMONG CLAN SIGN KWM;Lo;0;L;;;;;N;;;;; 16B8F;PAHAWH HMONG CLAN SIGN VWJ;Lo;0;L;;;;;N;;;;; +16E40;MEDEFAIDRIN CAPITAL LETTER M;Lu;0;L;;;;;N;;;;16E60; +16E41;MEDEFAIDRIN CAPITAL LETTER S;Lu;0;L;;;;;N;;;;16E61; +16E42;MEDEFAIDRIN CAPITAL LETTER V;Lu;0;L;;;;;N;;;;16E62; +16E43;MEDEFAIDRIN CAPITAL LETTER W;Lu;0;L;;;;;N;;;;16E63; +16E44;MEDEFAIDRIN CAPITAL LETTER ATIU;Lu;0;L;;;;;N;;;;16E64; +16E45;MEDEFAIDRIN CAPITAL LETTER Z;Lu;0;L;;;;;N;;;;16E65; +16E46;MEDEFAIDRIN CAPITAL LETTER KP;Lu;0;L;;;;;N;;;;16E66; +16E47;MEDEFAIDRIN CAPITAL LETTER P;Lu;0;L;;;;;N;;;;16E67; +16E48;MEDEFAIDRIN CAPITAL LETTER T;Lu;0;L;;;;;N;;;;16E68; +16E49;MEDEFAIDRIN CAPITAL LETTER G;Lu;0;L;;;;;N;;;;16E69; +16E4A;MEDEFAIDRIN CAPITAL LETTER F;Lu;0;L;;;;;N;;;;16E6A; +16E4B;MEDEFAIDRIN CAPITAL LETTER I;Lu;0;L;;;;;N;;;;16E6B; +16E4C;MEDEFAIDRIN CAPITAL LETTER K;Lu;0;L;;;;;N;;;;16E6C; +16E4D;MEDEFAIDRIN CAPITAL LETTER A;Lu;0;L;;;;;N;;;;16E6D; +16E4E;MEDEFAIDRIN CAPITAL LETTER J;Lu;0;L;;;;;N;;;;16E6E; +16E4F;MEDEFAIDRIN CAPITAL LETTER E;Lu;0;L;;;;;N;;;;16E6F; +16E50;MEDEFAIDRIN CAPITAL LETTER B;Lu;0;L;;;;;N;;;;16E70; +16E51;MEDEFAIDRIN CAPITAL LETTER C;Lu;0;L;;;;;N;;;;16E71; +16E52;MEDEFAIDRIN CAPITAL LETTER U;Lu;0;L;;;;;N;;;;16E72; +16E53;MEDEFAIDRIN CAPITAL LETTER YU;Lu;0;L;;;;;N;;;;16E73; +16E54;MEDEFAIDRIN CAPITAL LETTER L;Lu;0;L;;;;;N;;;;16E74; +16E55;MEDEFAIDRIN CAPITAL LETTER Q;Lu;0;L;;;;;N;;;;16E75; +16E56;MEDEFAIDRIN CAPITAL LETTER HP;Lu;0;L;;;;;N;;;;16E76; +16E57;MEDEFAIDRIN CAPITAL LETTER NY;Lu;0;L;;;;;N;;;;16E77; +16E58;MEDEFAIDRIN CAPITAL LETTER X;Lu;0;L;;;;;N;;;;16E78; +16E59;MEDEFAIDRIN CAPITAL LETTER D;Lu;0;L;;;;;N;;;;16E79; +16E5A;MEDEFAIDRIN CAPITAL LETTER OE;Lu;0;L;;;;;N;;;;16E7A; +16E5B;MEDEFAIDRIN CAPITAL LETTER N;Lu;0;L;;;;;N;;;;16E7B; +16E5C;MEDEFAIDRIN CAPITAL LETTER R;Lu;0;L;;;;;N;;;;16E7C; +16E5D;MEDEFAIDRIN CAPITAL LETTER O;Lu;0;L;;;;;N;;;;16E7D; +16E5E;MEDEFAIDRIN CAPITAL LETTER AI;Lu;0;L;;;;;N;;;;16E7E; +16E5F;MEDEFAIDRIN CAPITAL LETTER Y;Lu;0;L;;;;;N;;;;16E7F; +16E60;MEDEFAIDRIN SMALL LETTER M;Ll;0;L;;;;;N;;;16E40;;16E40 +16E61;MEDEFAIDRIN SMALL LETTER S;Ll;0;L;;;;;N;;;16E41;;16E41 +16E62;MEDEFAIDRIN SMALL LETTER V;Ll;0;L;;;;;N;;;16E42;;16E42 +16E63;MEDEFAIDRIN SMALL LETTER W;Ll;0;L;;;;;N;;;16E43;;16E43 +16E64;MEDEFAIDRIN SMALL LETTER ATIU;Ll;0;L;;;;;N;;;16E44;;16E44 +16E65;MEDEFAIDRIN SMALL LETTER Z;Ll;0;L;;;;;N;;;16E45;;16E45 +16E66;MEDEFAIDRIN SMALL LETTER KP;Ll;0;L;;;;;N;;;16E46;;16E46 +16E67;MEDEFAIDRIN SMALL LETTER P;Ll;0;L;;;;;N;;;16E47;;16E47 +16E68;MEDEFAIDRIN SMALL LETTER T;Ll;0;L;;;;;N;;;16E48;;16E48 +16E69;MEDEFAIDRIN SMALL LETTER G;Ll;0;L;;;;;N;;;16E49;;16E49 +16E6A;MEDEFAIDRIN SMALL LETTER F;Ll;0;L;;;;;N;;;16E4A;;16E4A +16E6B;MEDEFAIDRIN SMALL LETTER I;Ll;0;L;;;;;N;;;16E4B;;16E4B +16E6C;MEDEFAIDRIN SMALL LETTER K;Ll;0;L;;;;;N;;;16E4C;;16E4C +16E6D;MEDEFAIDRIN SMALL LETTER A;Ll;0;L;;;;;N;;;16E4D;;16E4D +16E6E;MEDEFAIDRIN SMALL LETTER J;Ll;0;L;;;;;N;;;16E4E;;16E4E +16E6F;MEDEFAIDRIN SMALL LETTER E;Ll;0;L;;;;;N;;;16E4F;;16E4F +16E70;MEDEFAIDRIN SMALL LETTER B;Ll;0;L;;;;;N;;;16E50;;16E50 +16E71;MEDEFAIDRIN SMALL LETTER C;Ll;0;L;;;;;N;;;16E51;;16E51 +16E72;MEDEFAIDRIN SMALL LETTER U;Ll;0;L;;;;;N;;;16E52;;16E52 +16E73;MEDEFAIDRIN SMALL LETTER YU;Ll;0;L;;;;;N;;;16E53;;16E53 +16E74;MEDEFAIDRIN SMALL LETTER L;Ll;0;L;;;;;N;;;16E54;;16E54 +16E75;MEDEFAIDRIN SMALL LETTER Q;Ll;0;L;;;;;N;;;16E55;;16E55 +16E76;MEDEFAIDRIN SMALL LETTER HP;Ll;0;L;;;;;N;;;16E56;;16E56 +16E77;MEDEFAIDRIN SMALL LETTER NY;Ll;0;L;;;;;N;;;16E57;;16E57 +16E78;MEDEFAIDRIN SMALL LETTER X;Ll;0;L;;;;;N;;;16E58;;16E58 +16E79;MEDEFAIDRIN SMALL LETTER D;Ll;0;L;;;;;N;;;16E59;;16E59 +16E7A;MEDEFAIDRIN SMALL LETTER OE;Ll;0;L;;;;;N;;;16E5A;;16E5A +16E7B;MEDEFAIDRIN SMALL LETTER N;Ll;0;L;;;;;N;;;16E5B;;16E5B +16E7C;MEDEFAIDRIN SMALL LETTER R;Ll;0;L;;;;;N;;;16E5C;;16E5C +16E7D;MEDEFAIDRIN SMALL LETTER O;Ll;0;L;;;;;N;;;16E5D;;16E5D +16E7E;MEDEFAIDRIN SMALL LETTER AI;Ll;0;L;;;;;N;;;16E5E;;16E5E +16E7F;MEDEFAIDRIN SMALL LETTER Y;Ll;0;L;;;;;N;;;16E5F;;16E5F +16E80;MEDEFAIDRIN DIGIT ZERO;No;0;L;;;;0;N;;;;; +16E81;MEDEFAIDRIN DIGIT ONE;No;0;L;;;;1;N;;;;; +16E82;MEDEFAIDRIN DIGIT TWO;No;0;L;;;;2;N;;;;; +16E83;MEDEFAIDRIN DIGIT THREE;No;0;L;;;;3;N;;;;; +16E84;MEDEFAIDRIN DIGIT FOUR;No;0;L;;;;4;N;;;;; +16E85;MEDEFAIDRIN DIGIT FIVE;No;0;L;;;;5;N;;;;; +16E86;MEDEFAIDRIN DIGIT SIX;No;0;L;;;;6;N;;;;; +16E87;MEDEFAIDRIN DIGIT SEVEN;No;0;L;;;;7;N;;;;; +16E88;MEDEFAIDRIN DIGIT EIGHT;No;0;L;;;;8;N;;;;; +16E89;MEDEFAIDRIN DIGIT NINE;No;0;L;;;;9;N;;;;; +16E8A;MEDEFAIDRIN NUMBER TEN;No;0;L;;;;10;N;;;;; +16E8B;MEDEFAIDRIN NUMBER ELEVEN;No;0;L;;;;11;N;;;;; +16E8C;MEDEFAIDRIN NUMBER TWELVE;No;0;L;;;;12;N;;;;; +16E8D;MEDEFAIDRIN NUMBER THIRTEEN;No;0;L;;;;13;N;;;;; +16E8E;MEDEFAIDRIN NUMBER FOURTEEN;No;0;L;;;;14;N;;;;; +16E8F;MEDEFAIDRIN NUMBER FIFTEEN;No;0;L;;;;15;N;;;;; +16E90;MEDEFAIDRIN NUMBER SIXTEEN;No;0;L;;;;16;N;;;;; +16E91;MEDEFAIDRIN NUMBER SEVENTEEN;No;0;L;;;;17;N;;;;; +16E92;MEDEFAIDRIN NUMBER EIGHTEEN;No;0;L;;;;18;N;;;;; +16E93;MEDEFAIDRIN NUMBER NINETEEN;No;0;L;;;;19;N;;;;; +16E94;MEDEFAIDRIN DIGIT ONE ALTERNATE FORM;No;0;L;;;;1;N;;;;; +16E95;MEDEFAIDRIN DIGIT TWO ALTERNATE FORM;No;0;L;;;;2;N;;;;; +16E96;MEDEFAIDRIN DIGIT THREE ALTERNATE FORM;No;0;L;;;;3;N;;;;; +16E97;MEDEFAIDRIN COMMA;Po;0;L;;;;;N;;;;; +16E98;MEDEFAIDRIN FULL STOP;Po;0;L;;;;;N;;;;; +16E99;MEDEFAIDRIN SYMBOL AIVA;Po;0;L;;;;;N;;;;; +16E9A;MEDEFAIDRIN EXCLAMATION OH;Po;0;L;;;;;N;;;;; 16F00;MIAO LETTER PA;Lo;0;L;;;;;N;;;;; 16F01;MIAO LETTER BA;Lo;0;L;;;;;N;;;;; 16F02;MIAO LETTER YI PA;Lo;0;L;;;;;N;;;;; @@ -24022,6 +25158,13 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 16F42;MIAO LETTER WA;Lo;0;L;;;;;N;;;;; 16F43;MIAO LETTER AH;Lo;0;L;;;;;N;;;;; 16F44;MIAO LETTER HHA;Lo;0;L;;;;;N;;;;; +16F45;MIAO LETTER BRI;Lo;0;L;;;;;N;;;;; +16F46;MIAO LETTER SYI;Lo;0;L;;;;;N;;;;; +16F47;MIAO LETTER DZYI;Lo;0;L;;;;;N;;;;; +16F48;MIAO LETTER TE;Lo;0;L;;;;;N;;;;; +16F49;MIAO LETTER TSE;Lo;0;L;;;;;N;;;;; +16F4A;MIAO LETTER RTE;Lo;0;L;;;;;N;;;;; +16F4F;MIAO SIGN CONSONANT MODIFIER BAR;Mn;0;NSM;;;;;N;;;;; 16F50;MIAO LETTER NASALIZATION;Lo;0;L;;;;;N;;;;; 16F51;MIAO SIGN ASPIRATION;Mc;0;L;;;;;N;;;;; 16F52;MIAO SIGN REFORMED VOICING;Mc;0;L;;;;;N;;;;; @@ -24069,6 +25212,15 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 16F7C;MIAO VOWEL SIGN OU;Mc;0;L;;;;;N;;;;; 16F7D;MIAO VOWEL SIGN N;Mc;0;L;;;;;N;;;;; 16F7E;MIAO VOWEL SIGN NG;Mc;0;L;;;;;N;;;;; +16F7F;MIAO VOWEL SIGN UOG;Mc;0;L;;;;;N;;;;; +16F80;MIAO VOWEL SIGN YUI;Mc;0;L;;;;;N;;;;; +16F81;MIAO VOWEL SIGN OG;Mc;0;L;;;;;N;;;;; +16F82;MIAO VOWEL SIGN OER;Mc;0;L;;;;;N;;;;; +16F83;MIAO VOWEL SIGN VW;Mc;0;L;;;;;N;;;;; +16F84;MIAO VOWEL SIGN IG;Mc;0;L;;;;;N;;;;; +16F85;MIAO VOWEL SIGN EA;Mc;0;L;;;;;N;;;;; +16F86;MIAO VOWEL SIGN IONG;Mc;0;L;;;;;N;;;;; +16F87;MIAO VOWEL SIGN UI;Mc;0;L;;;;;N;;;;; 16F8F;MIAO TONE RIGHT;Mn;0;NSM;;;;;N;;;;; 16F90;MIAO TONE TOP RIGHT;Mn;0;NSM;;;;;N;;;;; 16F91;MIAO TONE ABOVE;Mn;0;NSM;;;;;N;;;;; @@ -24087,8 +25239,14 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 16F9E;MIAO LETTER REFORMED TONE-6;Lm;0;L;;;;;N;;;;; 16F9F;MIAO LETTER REFORMED TONE-8;Lm;0;L;;;;;N;;;;; 16FE0;TANGUT ITERATION MARK;Lm;0;L;;;;;N;;;;; +16FE1;NUSHU ITERATION MARK;Lm;0;L;;;;;N;;;;; +16FE2;OLD CHINESE HOOK MARK;Po;0;ON;;;;;N;;;;; +16FE3;OLD CHINESE ITERATION MARK;Lm;0;L;;;;;N;;;;; +16FE4;KHITAN SMALL SCRIPT FILLER;Mn;0;NSM;;;;;N;;;;; +16FF0;VIETNAMESE ALTERNATE READING MARK CA;Mc;6;L;;;;;N;;;;; +16FF1;VIETNAMESE ALTERNATE READING MARK NHAY;Mc;6;L;;;;;N;;;;; 17000;;Lo;0;L;;;;;N;;;;; -187EC;;Lo;0;L;;;;;N;;;;; +187F7;;Lo;0;L;;;;;N;;;;; 18800;TANGUT COMPONENT-001;Lo;0;L;;;;;N;;;;; 18801;TANGUT COMPONENT-002;Lo;0;L;;;;;N;;;;; 18802;TANGUT COMPONENT-003;Lo;0;L;;;;;N;;;;; @@ -24844,8 +26002,1181 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 18AF0;TANGUT COMPONENT-753;Lo;0;L;;;;;N;;;;; 18AF1;TANGUT COMPONENT-754;Lo;0;L;;;;;N;;;;; 18AF2;TANGUT COMPONENT-755;Lo;0;L;;;;;N;;;;; +18AF3;TANGUT COMPONENT-756;Lo;0;L;;;;;N;;;;; +18AF4;TANGUT COMPONENT-757;Lo;0;L;;;;;N;;;;; +18AF5;TANGUT COMPONENT-758;Lo;0;L;;;;;N;;;;; +18AF6;TANGUT COMPONENT-759;Lo;0;L;;;;;N;;;;; +18AF7;TANGUT COMPONENT-760;Lo;0;L;;;;;N;;;;; +18AF8;TANGUT COMPONENT-761;Lo;0;L;;;;;N;;;;; +18AF9;TANGUT COMPONENT-762;Lo;0;L;;;;;N;;;;; +18AFA;TANGUT COMPONENT-763;Lo;0;L;;;;;N;;;;; +18AFB;TANGUT COMPONENT-764;Lo;0;L;;;;;N;;;;; +18AFC;TANGUT COMPONENT-765;Lo;0;L;;;;;N;;;;; +18AFD;TANGUT COMPONENT-766;Lo;0;L;;;;;N;;;;; +18AFE;TANGUT COMPONENT-767;Lo;0;L;;;;;N;;;;; +18AFF;TANGUT COMPONENT-768;Lo;0;L;;;;;N;;;;; +18B00;KHITAN SMALL SCRIPT CHARACTER-18B00;Lo;0;L;;;;;N;;;;; +18B01;KHITAN SMALL SCRIPT CHARACTER-18B01;Lo;0;L;;;;;N;;;;; +18B02;KHITAN SMALL SCRIPT CHARACTER-18B02;Lo;0;L;;;;;N;;;;; +18B03;KHITAN SMALL SCRIPT CHARACTER-18B03;Lo;0;L;;;;;N;;;;; +18B04;KHITAN SMALL SCRIPT CHARACTER-18B04;Lo;0;L;;;;;N;;;;; +18B05;KHITAN SMALL SCRIPT CHARACTER-18B05;Lo;0;L;;;;;N;;;;; +18B06;KHITAN SMALL SCRIPT CHARACTER-18B06;Lo;0;L;;;;;N;;;;; +18B07;KHITAN SMALL SCRIPT CHARACTER-18B07;Lo;0;L;;;;;N;;;;; +18B08;KHITAN SMALL SCRIPT CHARACTER-18B08;Lo;0;L;;;;;N;;;;; +18B09;KHITAN SMALL SCRIPT CHARACTER-18B09;Lo;0;L;;;;;N;;;;; +18B0A;KHITAN SMALL SCRIPT CHARACTER-18B0A;Lo;0;L;;;;;N;;;;; +18B0B;KHITAN SMALL SCRIPT CHARACTER-18B0B;Lo;0;L;;;;;N;;;;; +18B0C;KHITAN SMALL SCRIPT CHARACTER-18B0C;Lo;0;L;;;;;N;;;;; +18B0D;KHITAN SMALL SCRIPT CHARACTER-18B0D;Lo;0;L;;;;;N;;;;; +18B0E;KHITAN SMALL SCRIPT CHARACTER-18B0E;Lo;0;L;;;;;N;;;;; +18B0F;KHITAN SMALL SCRIPT CHARACTER-18B0F;Lo;0;L;;;;;N;;;;; +18B10;KHITAN SMALL SCRIPT CHARACTER-18B10;Lo;0;L;;;;;N;;;;; +18B11;KHITAN SMALL SCRIPT CHARACTER-18B11;Lo;0;L;;;;;N;;;;; +18B12;KHITAN SMALL SCRIPT CHARACTER-18B12;Lo;0;L;;;;;N;;;;; +18B13;KHITAN SMALL SCRIPT CHARACTER-18B13;Lo;0;L;;;;;N;;;;; +18B14;KHITAN SMALL SCRIPT CHARACTER-18B14;Lo;0;L;;;;;N;;;;; +18B15;KHITAN SMALL SCRIPT CHARACTER-18B15;Lo;0;L;;;;;N;;;;; +18B16;KHITAN SMALL SCRIPT CHARACTER-18B16;Lo;0;L;;;;;N;;;;; +18B17;KHITAN SMALL SCRIPT CHARACTER-18B17;Lo;0;L;;;;;N;;;;; +18B18;KHITAN SMALL SCRIPT CHARACTER-18B18;Lo;0;L;;;;;N;;;;; +18B19;KHITAN SMALL SCRIPT CHARACTER-18B19;Lo;0;L;;;;;N;;;;; +18B1A;KHITAN SMALL SCRIPT CHARACTER-18B1A;Lo;0;L;;;;;N;;;;; +18B1B;KHITAN SMALL SCRIPT CHARACTER-18B1B;Lo;0;L;;;;;N;;;;; +18B1C;KHITAN SMALL SCRIPT CHARACTER-18B1C;Lo;0;L;;;;;N;;;;; +18B1D;KHITAN SMALL SCRIPT CHARACTER-18B1D;Lo;0;L;;;;;N;;;;; +18B1E;KHITAN SMALL SCRIPT CHARACTER-18B1E;Lo;0;L;;;;;N;;;;; +18B1F;KHITAN SMALL SCRIPT CHARACTER-18B1F;Lo;0;L;;;;;N;;;;; +18B20;KHITAN SMALL SCRIPT CHARACTER-18B20;Lo;0;L;;;;;N;;;;; +18B21;KHITAN SMALL SCRIPT CHARACTER-18B21;Lo;0;L;;;;;N;;;;; +18B22;KHITAN SMALL SCRIPT CHARACTER-18B22;Lo;0;L;;;;;N;;;;; +18B23;KHITAN SMALL SCRIPT CHARACTER-18B23;Lo;0;L;;;;;N;;;;; +18B24;KHITAN SMALL SCRIPT CHARACTER-18B24;Lo;0;L;;;;;N;;;;; +18B25;KHITAN SMALL SCRIPT CHARACTER-18B25;Lo;0;L;;;;;N;;;;; +18B26;KHITAN SMALL SCRIPT CHARACTER-18B26;Lo;0;L;;;;;N;;;;; +18B27;KHITAN SMALL SCRIPT CHARACTER-18B27;Lo;0;L;;;;;N;;;;; +18B28;KHITAN SMALL SCRIPT CHARACTER-18B28;Lo;0;L;;;;;N;;;;; +18B29;KHITAN SMALL SCRIPT CHARACTER-18B29;Lo;0;L;;;;;N;;;;; +18B2A;KHITAN SMALL SCRIPT CHARACTER-18B2A;Lo;0;L;;;;;N;;;;; +18B2B;KHITAN SMALL SCRIPT CHARACTER-18B2B;Lo;0;L;;;;;N;;;;; +18B2C;KHITAN SMALL SCRIPT CHARACTER-18B2C;Lo;0;L;;;;;N;;;;; +18B2D;KHITAN SMALL SCRIPT CHARACTER-18B2D;Lo;0;L;;;;;N;;;;; +18B2E;KHITAN SMALL SCRIPT CHARACTER-18B2E;Lo;0;L;;;;;N;;;;; +18B2F;KHITAN SMALL SCRIPT CHARACTER-18B2F;Lo;0;L;;;;;N;;;;; +18B30;KHITAN SMALL SCRIPT CHARACTER-18B30;Lo;0;L;;;;;N;;;;; +18B31;KHITAN SMALL SCRIPT CHARACTER-18B31;Lo;0;L;;;;;N;;;;; +18B32;KHITAN SMALL SCRIPT CHARACTER-18B32;Lo;0;L;;;;;N;;;;; +18B33;KHITAN SMALL SCRIPT CHARACTER-18B33;Lo;0;L;;;;;N;;;;; +18B34;KHITAN SMALL SCRIPT CHARACTER-18B34;Lo;0;L;;;;;N;;;;; +18B35;KHITAN SMALL SCRIPT CHARACTER-18B35;Lo;0;L;;;;;N;;;;; +18B36;KHITAN SMALL SCRIPT CHARACTER-18B36;Lo;0;L;;;;;N;;;;; +18B37;KHITAN SMALL SCRIPT CHARACTER-18B37;Lo;0;L;;;;;N;;;;; +18B38;KHITAN SMALL SCRIPT CHARACTER-18B38;Lo;0;L;;;;;N;;;;; +18B39;KHITAN SMALL SCRIPT CHARACTER-18B39;Lo;0;L;;;;;N;;;;; +18B3A;KHITAN SMALL SCRIPT CHARACTER-18B3A;Lo;0;L;;;;;N;;;;; +18B3B;KHITAN SMALL SCRIPT CHARACTER-18B3B;Lo;0;L;;;;;N;;;;; +18B3C;KHITAN SMALL SCRIPT CHARACTER-18B3C;Lo;0;L;;;;;N;;;;; +18B3D;KHITAN SMALL SCRIPT CHARACTER-18B3D;Lo;0;L;;;;;N;;;;; +18B3E;KHITAN SMALL SCRIPT CHARACTER-18B3E;Lo;0;L;;;;;N;;;;; +18B3F;KHITAN SMALL SCRIPT CHARACTER-18B3F;Lo;0;L;;;;;N;;;;; +18B40;KHITAN SMALL SCRIPT CHARACTER-18B40;Lo;0;L;;;;;N;;;;; +18B41;KHITAN SMALL SCRIPT CHARACTER-18B41;Lo;0;L;;;;;N;;;;; +18B42;KHITAN SMALL SCRIPT CHARACTER-18B42;Lo;0;L;;;;;N;;;;; +18B43;KHITAN SMALL SCRIPT CHARACTER-18B43;Lo;0;L;;;;;N;;;;; +18B44;KHITAN SMALL SCRIPT CHARACTER-18B44;Lo;0;L;;;;;N;;;;; +18B45;KHITAN SMALL SCRIPT CHARACTER-18B45;Lo;0;L;;;;;N;;;;; +18B46;KHITAN SMALL SCRIPT CHARACTER-18B46;Lo;0;L;;;;;N;;;;; +18B47;KHITAN SMALL SCRIPT CHARACTER-18B47;Lo;0;L;;;;;N;;;;; +18B48;KHITAN SMALL SCRIPT CHARACTER-18B48;Lo;0;L;;;;;N;;;;; +18B49;KHITAN SMALL SCRIPT CHARACTER-18B49;Lo;0;L;;;;;N;;;;; +18B4A;KHITAN SMALL SCRIPT CHARACTER-18B4A;Lo;0;L;;;;;N;;;;; +18B4B;KHITAN SMALL SCRIPT CHARACTER-18B4B;Lo;0;L;;;;;N;;;;; +18B4C;KHITAN SMALL SCRIPT CHARACTER-18B4C;Lo;0;L;;;;;N;;;;; +18B4D;KHITAN SMALL SCRIPT CHARACTER-18B4D;Lo;0;L;;;;;N;;;;; +18B4E;KHITAN SMALL SCRIPT CHARACTER-18B4E;Lo;0;L;;;;;N;;;;; +18B4F;KHITAN SMALL SCRIPT CHARACTER-18B4F;Lo;0;L;;;;;N;;;;; +18B50;KHITAN SMALL SCRIPT CHARACTER-18B50;Lo;0;L;;;;;N;;;;; +18B51;KHITAN SMALL SCRIPT CHARACTER-18B51;Lo;0;L;;;;;N;;;;; +18B52;KHITAN SMALL SCRIPT CHARACTER-18B52;Lo;0;L;;;;;N;;;;; +18B53;KHITAN SMALL SCRIPT CHARACTER-18B53;Lo;0;L;;;;;N;;;;; +18B54;KHITAN SMALL SCRIPT CHARACTER-18B54;Lo;0;L;;;;;N;;;;; +18B55;KHITAN SMALL SCRIPT CHARACTER-18B55;Lo;0;L;;;;;N;;;;; +18B56;KHITAN SMALL SCRIPT CHARACTER-18B56;Lo;0;L;;;;;N;;;;; +18B57;KHITAN SMALL SCRIPT CHARACTER-18B57;Lo;0;L;;;;;N;;;;; +18B58;KHITAN SMALL SCRIPT CHARACTER-18B58;Lo;0;L;;;;;N;;;;; +18B59;KHITAN SMALL SCRIPT CHARACTER-18B59;Lo;0;L;;;;;N;;;;; +18B5A;KHITAN SMALL SCRIPT CHARACTER-18B5A;Lo;0;L;;;;;N;;;;; +18B5B;KHITAN SMALL SCRIPT CHARACTER-18B5B;Lo;0;L;;;;;N;;;;; +18B5C;KHITAN SMALL SCRIPT CHARACTER-18B5C;Lo;0;L;;;;;N;;;;; +18B5D;KHITAN SMALL SCRIPT CHARACTER-18B5D;Lo;0;L;;;;;N;;;;; +18B5E;KHITAN SMALL SCRIPT CHARACTER-18B5E;Lo;0;L;;;;;N;;;;; +18B5F;KHITAN SMALL SCRIPT CHARACTER-18B5F;Lo;0;L;;;;;N;;;;; +18B60;KHITAN SMALL SCRIPT CHARACTER-18B60;Lo;0;L;;;;;N;;;;; +18B61;KHITAN SMALL SCRIPT CHARACTER-18B61;Lo;0;L;;;;;N;;;;; +18B62;KHITAN SMALL SCRIPT CHARACTER-18B62;Lo;0;L;;;;;N;;;;; +18B63;KHITAN SMALL SCRIPT CHARACTER-18B63;Lo;0;L;;;;;N;;;;; +18B64;KHITAN SMALL SCRIPT CHARACTER-18B64;Lo;0;L;;;;;N;;;;; +18B65;KHITAN SMALL SCRIPT CHARACTER-18B65;Lo;0;L;;;;;N;;;;; +18B66;KHITAN SMALL SCRIPT CHARACTER-18B66;Lo;0;L;;;;;N;;;;; +18B67;KHITAN SMALL SCRIPT CHARACTER-18B67;Lo;0;L;;;;;N;;;;; +18B68;KHITAN SMALL SCRIPT CHARACTER-18B68;Lo;0;L;;;;;N;;;;; +18B69;KHITAN SMALL SCRIPT CHARACTER-18B69;Lo;0;L;;;;;N;;;;; +18B6A;KHITAN SMALL SCRIPT CHARACTER-18B6A;Lo;0;L;;;;;N;;;;; +18B6B;KHITAN SMALL SCRIPT CHARACTER-18B6B;Lo;0;L;;;;;N;;;;; +18B6C;KHITAN SMALL SCRIPT CHARACTER-18B6C;Lo;0;L;;;;;N;;;;; +18B6D;KHITAN SMALL SCRIPT CHARACTER-18B6D;Lo;0;L;;;;;N;;;;; +18B6E;KHITAN SMALL SCRIPT CHARACTER-18B6E;Lo;0;L;;;;;N;;;;; +18B6F;KHITAN SMALL SCRIPT CHARACTER-18B6F;Lo;0;L;;;;;N;;;;; +18B70;KHITAN SMALL SCRIPT CHARACTER-18B70;Lo;0;L;;;;;N;;;;; +18B71;KHITAN SMALL SCRIPT CHARACTER-18B71;Lo;0;L;;;;;N;;;;; +18B72;KHITAN SMALL SCRIPT CHARACTER-18B72;Lo;0;L;;;;;N;;;;; +18B73;KHITAN SMALL SCRIPT CHARACTER-18B73;Lo;0;L;;;;;N;;;;; +18B74;KHITAN SMALL SCRIPT CHARACTER-18B74;Lo;0;L;;;;;N;;;;; +18B75;KHITAN SMALL SCRIPT CHARACTER-18B75;Lo;0;L;;;;;N;;;;; +18B76;KHITAN SMALL SCRIPT CHARACTER-18B76;Lo;0;L;;;;;N;;;;; +18B77;KHITAN SMALL SCRIPT CHARACTER-18B77;Lo;0;L;;;;;N;;;;; +18B78;KHITAN SMALL SCRIPT CHARACTER-18B78;Lo;0;L;;;;;N;;;;; +18B79;KHITAN SMALL SCRIPT CHARACTER-18B79;Lo;0;L;;;;;N;;;;; +18B7A;KHITAN SMALL SCRIPT CHARACTER-18B7A;Lo;0;L;;;;;N;;;;; +18B7B;KHITAN SMALL SCRIPT CHARACTER-18B7B;Lo;0;L;;;;;N;;;;; +18B7C;KHITAN SMALL SCRIPT CHARACTER-18B7C;Lo;0;L;;;;;N;;;;; +18B7D;KHITAN SMALL SCRIPT CHARACTER-18B7D;Lo;0;L;;;;;N;;;;; +18B7E;KHITAN SMALL SCRIPT CHARACTER-18B7E;Lo;0;L;;;;;N;;;;; +18B7F;KHITAN SMALL SCRIPT CHARACTER-18B7F;Lo;0;L;;;;;N;;;;; +18B80;KHITAN SMALL SCRIPT CHARACTER-18B80;Lo;0;L;;;;;N;;;;; +18B81;KHITAN SMALL SCRIPT CHARACTER-18B81;Lo;0;L;;;;;N;;;;; +18B82;KHITAN SMALL SCRIPT CHARACTER-18B82;Lo;0;L;;;;;N;;;;; +18B83;KHITAN SMALL SCRIPT CHARACTER-18B83;Lo;0;L;;;;;N;;;;; +18B84;KHITAN SMALL SCRIPT CHARACTER-18B84;Lo;0;L;;;;;N;;;;; +18B85;KHITAN SMALL SCRIPT CHARACTER-18B85;Lo;0;L;;;;;N;;;;; +18B86;KHITAN SMALL SCRIPT CHARACTER-18B86;Lo;0;L;;;;;N;;;;; +18B87;KHITAN SMALL SCRIPT CHARACTER-18B87;Lo;0;L;;;;;N;;;;; +18B88;KHITAN SMALL SCRIPT CHARACTER-18B88;Lo;0;L;;;;;N;;;;; +18B89;KHITAN SMALL SCRIPT CHARACTER-18B89;Lo;0;L;;;;;N;;;;; +18B8A;KHITAN SMALL SCRIPT CHARACTER-18B8A;Lo;0;L;;;;;N;;;;; +18B8B;KHITAN SMALL SCRIPT CHARACTER-18B8B;Lo;0;L;;;;;N;;;;; +18B8C;KHITAN SMALL SCRIPT CHARACTER-18B8C;Lo;0;L;;;;;N;;;;; +18B8D;KHITAN SMALL SCRIPT CHARACTER-18B8D;Lo;0;L;;;;;N;;;;; +18B8E;KHITAN SMALL SCRIPT CHARACTER-18B8E;Lo;0;L;;;;;N;;;;; +18B8F;KHITAN SMALL SCRIPT CHARACTER-18B8F;Lo;0;L;;;;;N;;;;; +18B90;KHITAN SMALL SCRIPT CHARACTER-18B90;Lo;0;L;;;;;N;;;;; +18B91;KHITAN SMALL SCRIPT CHARACTER-18B91;Lo;0;L;;;;;N;;;;; +18B92;KHITAN SMALL SCRIPT CHARACTER-18B92;Lo;0;L;;;;;N;;;;; +18B93;KHITAN SMALL SCRIPT CHARACTER-18B93;Lo;0;L;;;;;N;;;;; +18B94;KHITAN SMALL SCRIPT CHARACTER-18B94;Lo;0;L;;;;;N;;;;; +18B95;KHITAN SMALL SCRIPT CHARACTER-18B95;Lo;0;L;;;;;N;;;;; +18B96;KHITAN SMALL SCRIPT CHARACTER-18B96;Lo;0;L;;;;;N;;;;; +18B97;KHITAN SMALL SCRIPT CHARACTER-18B97;Lo;0;L;;;;;N;;;;; +18B98;KHITAN SMALL SCRIPT CHARACTER-18B98;Lo;0;L;;;;;N;;;;; +18B99;KHITAN SMALL SCRIPT CHARACTER-18B99;Lo;0;L;;;;;N;;;;; +18B9A;KHITAN SMALL SCRIPT CHARACTER-18B9A;Lo;0;L;;;;;N;;;;; +18B9B;KHITAN SMALL SCRIPT CHARACTER-18B9B;Lo;0;L;;;;;N;;;;; +18B9C;KHITAN SMALL SCRIPT CHARACTER-18B9C;Lo;0;L;;;;;N;;;;; +18B9D;KHITAN SMALL SCRIPT CHARACTER-18B9D;Lo;0;L;;;;;N;;;;; +18B9E;KHITAN SMALL SCRIPT CHARACTER-18B9E;Lo;0;L;;;;;N;;;;; +18B9F;KHITAN SMALL SCRIPT CHARACTER-18B9F;Lo;0;L;;;;;N;;;;; +18BA0;KHITAN SMALL SCRIPT CHARACTER-18BA0;Lo;0;L;;;;;N;;;;; +18BA1;KHITAN SMALL SCRIPT CHARACTER-18BA1;Lo;0;L;;;;;N;;;;; +18BA2;KHITAN SMALL SCRIPT CHARACTER-18BA2;Lo;0;L;;;;;N;;;;; +18BA3;KHITAN SMALL SCRIPT CHARACTER-18BA3;Lo;0;L;;;;;N;;;;; +18BA4;KHITAN SMALL SCRIPT CHARACTER-18BA4;Lo;0;L;;;;;N;;;;; +18BA5;KHITAN SMALL SCRIPT CHARACTER-18BA5;Lo;0;L;;;;;N;;;;; +18BA6;KHITAN SMALL SCRIPT CHARACTER-18BA6;Lo;0;L;;;;;N;;;;; +18BA7;KHITAN SMALL SCRIPT CHARACTER-18BA7;Lo;0;L;;;;;N;;;;; +18BA8;KHITAN SMALL SCRIPT CHARACTER-18BA8;Lo;0;L;;;;;N;;;;; +18BA9;KHITAN SMALL SCRIPT CHARACTER-18BA9;Lo;0;L;;;;;N;;;;; +18BAA;KHITAN SMALL SCRIPT CHARACTER-18BAA;Lo;0;L;;;;;N;;;;; +18BAB;KHITAN SMALL SCRIPT CHARACTER-18BAB;Lo;0;L;;;;;N;;;;; +18BAC;KHITAN SMALL SCRIPT CHARACTER-18BAC;Lo;0;L;;;;;N;;;;; +18BAD;KHITAN SMALL SCRIPT CHARACTER-18BAD;Lo;0;L;;;;;N;;;;; +18BAE;KHITAN SMALL SCRIPT CHARACTER-18BAE;Lo;0;L;;;;;N;;;;; +18BAF;KHITAN SMALL SCRIPT CHARACTER-18BAF;Lo;0;L;;;;;N;;;;; +18BB0;KHITAN SMALL SCRIPT CHARACTER-18BB0;Lo;0;L;;;;;N;;;;; +18BB1;KHITAN SMALL SCRIPT CHARACTER-18BB1;Lo;0;L;;;;;N;;;;; +18BB2;KHITAN SMALL SCRIPT CHARACTER-18BB2;Lo;0;L;;;;;N;;;;; +18BB3;KHITAN SMALL SCRIPT CHARACTER-18BB3;Lo;0;L;;;;;N;;;;; +18BB4;KHITAN SMALL SCRIPT CHARACTER-18BB4;Lo;0;L;;;;;N;;;;; +18BB5;KHITAN SMALL SCRIPT CHARACTER-18BB5;Lo;0;L;;;;;N;;;;; +18BB6;KHITAN SMALL SCRIPT CHARACTER-18BB6;Lo;0;L;;;;;N;;;;; +18BB7;KHITAN SMALL SCRIPT CHARACTER-18BB7;Lo;0;L;;;;;N;;;;; +18BB8;KHITAN SMALL SCRIPT CHARACTER-18BB8;Lo;0;L;;;;;N;;;;; +18BB9;KHITAN SMALL SCRIPT CHARACTER-18BB9;Lo;0;L;;;;;N;;;;; +18BBA;KHITAN SMALL SCRIPT CHARACTER-18BBA;Lo;0;L;;;;;N;;;;; +18BBB;KHITAN SMALL SCRIPT CHARACTER-18BBB;Lo;0;L;;;;;N;;;;; +18BBC;KHITAN SMALL SCRIPT CHARACTER-18BBC;Lo;0;L;;;;;N;;;;; +18BBD;KHITAN SMALL SCRIPT CHARACTER-18BBD;Lo;0;L;;;;;N;;;;; +18BBE;KHITAN SMALL SCRIPT CHARACTER-18BBE;Lo;0;L;;;;;N;;;;; +18BBF;KHITAN SMALL SCRIPT CHARACTER-18BBF;Lo;0;L;;;;;N;;;;; +18BC0;KHITAN SMALL SCRIPT CHARACTER-18BC0;Lo;0;L;;;;;N;;;;; +18BC1;KHITAN SMALL SCRIPT CHARACTER-18BC1;Lo;0;L;;;;;N;;;;; +18BC2;KHITAN SMALL SCRIPT CHARACTER-18BC2;Lo;0;L;;;;;N;;;;; +18BC3;KHITAN SMALL SCRIPT CHARACTER-18BC3;Lo;0;L;;;;;N;;;;; +18BC4;KHITAN SMALL SCRIPT CHARACTER-18BC4;Lo;0;L;;;;;N;;;;; +18BC5;KHITAN SMALL SCRIPT CHARACTER-18BC5;Lo;0;L;;;;;N;;;;; +18BC6;KHITAN SMALL SCRIPT CHARACTER-18BC6;Lo;0;L;;;;;N;;;;; +18BC7;KHITAN SMALL SCRIPT CHARACTER-18BC7;Lo;0;L;;;;;N;;;;; +18BC8;KHITAN SMALL SCRIPT CHARACTER-18BC8;Lo;0;L;;;;;N;;;;; +18BC9;KHITAN SMALL SCRIPT CHARACTER-18BC9;Lo;0;L;;;;;N;;;;; +18BCA;KHITAN SMALL SCRIPT CHARACTER-18BCA;Lo;0;L;;;;;N;;;;; +18BCB;KHITAN SMALL SCRIPT CHARACTER-18BCB;Lo;0;L;;;;;N;;;;; +18BCC;KHITAN SMALL SCRIPT CHARACTER-18BCC;Lo;0;L;;;;;N;;;;; +18BCD;KHITAN SMALL SCRIPT CHARACTER-18BCD;Lo;0;L;;;;;N;;;;; +18BCE;KHITAN SMALL SCRIPT CHARACTER-18BCE;Lo;0;L;;;;;N;;;;; +18BCF;KHITAN SMALL SCRIPT CHARACTER-18BCF;Lo;0;L;;;;;N;;;;; +18BD0;KHITAN SMALL SCRIPT CHARACTER-18BD0;Lo;0;L;;;;;N;;;;; +18BD1;KHITAN SMALL SCRIPT CHARACTER-18BD1;Lo;0;L;;;;;N;;;;; +18BD2;KHITAN SMALL SCRIPT CHARACTER-18BD2;Lo;0;L;;;;;N;;;;; +18BD3;KHITAN SMALL SCRIPT CHARACTER-18BD3;Lo;0;L;;;;;N;;;;; +18BD4;KHITAN SMALL SCRIPT CHARACTER-18BD4;Lo;0;L;;;;;N;;;;; +18BD5;KHITAN SMALL SCRIPT CHARACTER-18BD5;Lo;0;L;;;;;N;;;;; +18BD6;KHITAN SMALL SCRIPT CHARACTER-18BD6;Lo;0;L;;;;;N;;;;; +18BD7;KHITAN SMALL SCRIPT CHARACTER-18BD7;Lo;0;L;;;;;N;;;;; +18BD8;KHITAN SMALL SCRIPT CHARACTER-18BD8;Lo;0;L;;;;;N;;;;; +18BD9;KHITAN SMALL SCRIPT CHARACTER-18BD9;Lo;0;L;;;;;N;;;;; +18BDA;KHITAN SMALL SCRIPT CHARACTER-18BDA;Lo;0;L;;;;;N;;;;; +18BDB;KHITAN SMALL SCRIPT CHARACTER-18BDB;Lo;0;L;;;;;N;;;;; +18BDC;KHITAN SMALL SCRIPT CHARACTER-18BDC;Lo;0;L;;;;;N;;;;; +18BDD;KHITAN SMALL SCRIPT CHARACTER-18BDD;Lo;0;L;;;;;N;;;;; +18BDE;KHITAN SMALL SCRIPT CHARACTER-18BDE;Lo;0;L;;;;;N;;;;; +18BDF;KHITAN SMALL SCRIPT CHARACTER-18BDF;Lo;0;L;;;;;N;;;;; +18BE0;KHITAN SMALL SCRIPT CHARACTER-18BE0;Lo;0;L;;;;;N;;;;; +18BE1;KHITAN SMALL SCRIPT CHARACTER-18BE1;Lo;0;L;;;;;N;;;;; +18BE2;KHITAN SMALL SCRIPT CHARACTER-18BE2;Lo;0;L;;;;;N;;;;; +18BE3;KHITAN SMALL SCRIPT CHARACTER-18BE3;Lo;0;L;;;;;N;;;;; +18BE4;KHITAN SMALL SCRIPT CHARACTER-18BE4;Lo;0;L;;;;;N;;;;; +18BE5;KHITAN SMALL SCRIPT CHARACTER-18BE5;Lo;0;L;;;;;N;;;;; +18BE6;KHITAN SMALL SCRIPT CHARACTER-18BE6;Lo;0;L;;;;;N;;;;; +18BE7;KHITAN SMALL SCRIPT CHARACTER-18BE7;Lo;0;L;;;;;N;;;;; +18BE8;KHITAN SMALL SCRIPT CHARACTER-18BE8;Lo;0;L;;;;;N;;;;; +18BE9;KHITAN SMALL SCRIPT CHARACTER-18BE9;Lo;0;L;;;;;N;;;;; +18BEA;KHITAN SMALL SCRIPT CHARACTER-18BEA;Lo;0;L;;;;;N;;;;; +18BEB;KHITAN SMALL SCRIPT CHARACTER-18BEB;Lo;0;L;;;;;N;;;;; +18BEC;KHITAN SMALL SCRIPT CHARACTER-18BEC;Lo;0;L;;;;;N;;;;; +18BED;KHITAN SMALL SCRIPT CHARACTER-18BED;Lo;0;L;;;;;N;;;;; +18BEE;KHITAN SMALL SCRIPT CHARACTER-18BEE;Lo;0;L;;;;;N;;;;; +18BEF;KHITAN SMALL SCRIPT CHARACTER-18BEF;Lo;0;L;;;;;N;;;;; +18BF0;KHITAN SMALL SCRIPT CHARACTER-18BF0;Lo;0;L;;;;;N;;;;; +18BF1;KHITAN SMALL SCRIPT CHARACTER-18BF1;Lo;0;L;;;;;N;;;;; +18BF2;KHITAN SMALL SCRIPT CHARACTER-18BF2;Lo;0;L;;;;;N;;;;; +18BF3;KHITAN SMALL SCRIPT CHARACTER-18BF3;Lo;0;L;;;;;N;;;;; +18BF4;KHITAN SMALL SCRIPT CHARACTER-18BF4;Lo;0;L;;;;;N;;;;; +18BF5;KHITAN SMALL SCRIPT CHARACTER-18BF5;Lo;0;L;;;;;N;;;;; +18BF6;KHITAN SMALL SCRIPT CHARACTER-18BF6;Lo;0;L;;;;;N;;;;; +18BF7;KHITAN SMALL SCRIPT CHARACTER-18BF7;Lo;0;L;;;;;N;;;;; +18BF8;KHITAN SMALL SCRIPT CHARACTER-18BF8;Lo;0;L;;;;;N;;;;; +18BF9;KHITAN SMALL SCRIPT CHARACTER-18BF9;Lo;0;L;;;;;N;;;;; +18BFA;KHITAN SMALL SCRIPT CHARACTER-18BFA;Lo;0;L;;;;;N;;;;; +18BFB;KHITAN SMALL SCRIPT CHARACTER-18BFB;Lo;0;L;;;;;N;;;;; +18BFC;KHITAN SMALL SCRIPT CHARACTER-18BFC;Lo;0;L;;;;;N;;;;; +18BFD;KHITAN SMALL SCRIPT CHARACTER-18BFD;Lo;0;L;;;;;N;;;;; +18BFE;KHITAN SMALL SCRIPT CHARACTER-18BFE;Lo;0;L;;;;;N;;;;; +18BFF;KHITAN SMALL SCRIPT CHARACTER-18BFF;Lo;0;L;;;;;N;;;;; +18C00;KHITAN SMALL SCRIPT CHARACTER-18C00;Lo;0;L;;;;;N;;;;; +18C01;KHITAN SMALL SCRIPT CHARACTER-18C01;Lo;0;L;;;;;N;;;;; +18C02;KHITAN SMALL SCRIPT CHARACTER-18C02;Lo;0;L;;;;;N;;;;; +18C03;KHITAN SMALL SCRIPT CHARACTER-18C03;Lo;0;L;;;;;N;;;;; +18C04;KHITAN SMALL SCRIPT CHARACTER-18C04;Lo;0;L;;;;;N;;;;; +18C05;KHITAN SMALL SCRIPT CHARACTER-18C05;Lo;0;L;;;;;N;;;;; +18C06;KHITAN SMALL SCRIPT CHARACTER-18C06;Lo;0;L;;;;;N;;;;; +18C07;KHITAN SMALL SCRIPT CHARACTER-18C07;Lo;0;L;;;;;N;;;;; +18C08;KHITAN SMALL SCRIPT CHARACTER-18C08;Lo;0;L;;;;;N;;;;; +18C09;KHITAN SMALL SCRIPT CHARACTER-18C09;Lo;0;L;;;;;N;;;;; +18C0A;KHITAN SMALL SCRIPT CHARACTER-18C0A;Lo;0;L;;;;;N;;;;; +18C0B;KHITAN SMALL SCRIPT CHARACTER-18C0B;Lo;0;L;;;;;N;;;;; +18C0C;KHITAN SMALL SCRIPT CHARACTER-18C0C;Lo;0;L;;;;;N;;;;; +18C0D;KHITAN SMALL SCRIPT CHARACTER-18C0D;Lo;0;L;;;;;N;;;;; +18C0E;KHITAN SMALL SCRIPT CHARACTER-18C0E;Lo;0;L;;;;;N;;;;; +18C0F;KHITAN SMALL SCRIPT CHARACTER-18C0F;Lo;0;L;;;;;N;;;;; +18C10;KHITAN SMALL SCRIPT CHARACTER-18C10;Lo;0;L;;;;;N;;;;; +18C11;KHITAN SMALL SCRIPT CHARACTER-18C11;Lo;0;L;;;;;N;;;;; +18C12;KHITAN SMALL SCRIPT CHARACTER-18C12;Lo;0;L;;;;;N;;;;; +18C13;KHITAN SMALL SCRIPT CHARACTER-18C13;Lo;0;L;;;;;N;;;;; +18C14;KHITAN SMALL SCRIPT CHARACTER-18C14;Lo;0;L;;;;;N;;;;; +18C15;KHITAN SMALL SCRIPT CHARACTER-18C15;Lo;0;L;;;;;N;;;;; +18C16;KHITAN SMALL SCRIPT CHARACTER-18C16;Lo;0;L;;;;;N;;;;; +18C17;KHITAN SMALL SCRIPT CHARACTER-18C17;Lo;0;L;;;;;N;;;;; +18C18;KHITAN SMALL SCRIPT CHARACTER-18C18;Lo;0;L;;;;;N;;;;; +18C19;KHITAN SMALL SCRIPT CHARACTER-18C19;Lo;0;L;;;;;N;;;;; +18C1A;KHITAN SMALL SCRIPT CHARACTER-18C1A;Lo;0;L;;;;;N;;;;; +18C1B;KHITAN SMALL SCRIPT CHARACTER-18C1B;Lo;0;L;;;;;N;;;;; +18C1C;KHITAN SMALL SCRIPT CHARACTER-18C1C;Lo;0;L;;;;;N;;;;; +18C1D;KHITAN SMALL SCRIPT CHARACTER-18C1D;Lo;0;L;;;;;N;;;;; +18C1E;KHITAN SMALL SCRIPT CHARACTER-18C1E;Lo;0;L;;;;;N;;;;; +18C1F;KHITAN SMALL SCRIPT CHARACTER-18C1F;Lo;0;L;;;;;N;;;;; +18C20;KHITAN SMALL SCRIPT CHARACTER-18C20;Lo;0;L;;;;;N;;;;; +18C21;KHITAN SMALL SCRIPT CHARACTER-18C21;Lo;0;L;;;;;N;;;;; +18C22;KHITAN SMALL SCRIPT CHARACTER-18C22;Lo;0;L;;;;;N;;;;; +18C23;KHITAN SMALL SCRIPT CHARACTER-18C23;Lo;0;L;;;;;N;;;;; +18C24;KHITAN SMALL SCRIPT CHARACTER-18C24;Lo;0;L;;;;;N;;;;; +18C25;KHITAN SMALL SCRIPT CHARACTER-18C25;Lo;0;L;;;;;N;;;;; +18C26;KHITAN SMALL SCRIPT CHARACTER-18C26;Lo;0;L;;;;;N;;;;; +18C27;KHITAN SMALL SCRIPT CHARACTER-18C27;Lo;0;L;;;;;N;;;;; +18C28;KHITAN SMALL SCRIPT CHARACTER-18C28;Lo;0;L;;;;;N;;;;; +18C29;KHITAN SMALL SCRIPT CHARACTER-18C29;Lo;0;L;;;;;N;;;;; +18C2A;KHITAN SMALL SCRIPT CHARACTER-18C2A;Lo;0;L;;;;;N;;;;; +18C2B;KHITAN SMALL SCRIPT CHARACTER-18C2B;Lo;0;L;;;;;N;;;;; +18C2C;KHITAN SMALL SCRIPT CHARACTER-18C2C;Lo;0;L;;;;;N;;;;; +18C2D;KHITAN SMALL SCRIPT CHARACTER-18C2D;Lo;0;L;;;;;N;;;;; +18C2E;KHITAN SMALL SCRIPT CHARACTER-18C2E;Lo;0;L;;;;;N;;;;; +18C2F;KHITAN SMALL SCRIPT CHARACTER-18C2F;Lo;0;L;;;;;N;;;;; +18C30;KHITAN SMALL SCRIPT CHARACTER-18C30;Lo;0;L;;;;;N;;;;; +18C31;KHITAN SMALL SCRIPT CHARACTER-18C31;Lo;0;L;;;;;N;;;;; +18C32;KHITAN SMALL SCRIPT CHARACTER-18C32;Lo;0;L;;;;;N;;;;; +18C33;KHITAN SMALL SCRIPT CHARACTER-18C33;Lo;0;L;;;;;N;;;;; +18C34;KHITAN SMALL SCRIPT CHARACTER-18C34;Lo;0;L;;;;;N;;;;; +18C35;KHITAN SMALL SCRIPT CHARACTER-18C35;Lo;0;L;;;;;N;;;;; +18C36;KHITAN SMALL SCRIPT CHARACTER-18C36;Lo;0;L;;;;;N;;;;; +18C37;KHITAN SMALL SCRIPT CHARACTER-18C37;Lo;0;L;;;;;N;;;;; +18C38;KHITAN SMALL SCRIPT CHARACTER-18C38;Lo;0;L;;;;;N;;;;; +18C39;KHITAN SMALL SCRIPT CHARACTER-18C39;Lo;0;L;;;;;N;;;;; +18C3A;KHITAN SMALL SCRIPT CHARACTER-18C3A;Lo;0;L;;;;;N;;;;; +18C3B;KHITAN SMALL SCRIPT CHARACTER-18C3B;Lo;0;L;;;;;N;;;;; +18C3C;KHITAN SMALL SCRIPT CHARACTER-18C3C;Lo;0;L;;;;;N;;;;; +18C3D;KHITAN SMALL SCRIPT CHARACTER-18C3D;Lo;0;L;;;;;N;;;;; +18C3E;KHITAN SMALL SCRIPT CHARACTER-18C3E;Lo;0;L;;;;;N;;;;; +18C3F;KHITAN SMALL SCRIPT CHARACTER-18C3F;Lo;0;L;;;;;N;;;;; +18C40;KHITAN SMALL SCRIPT CHARACTER-18C40;Lo;0;L;;;;;N;;;;; +18C41;KHITAN SMALL SCRIPT CHARACTER-18C41;Lo;0;L;;;;;N;;;;; +18C42;KHITAN SMALL SCRIPT CHARACTER-18C42;Lo;0;L;;;;;N;;;;; +18C43;KHITAN SMALL SCRIPT CHARACTER-18C43;Lo;0;L;;;;;N;;;;; +18C44;KHITAN SMALL SCRIPT CHARACTER-18C44;Lo;0;L;;;;;N;;;;; +18C45;KHITAN SMALL SCRIPT CHARACTER-18C45;Lo;0;L;;;;;N;;;;; +18C46;KHITAN SMALL SCRIPT CHARACTER-18C46;Lo;0;L;;;;;N;;;;; +18C47;KHITAN SMALL SCRIPT CHARACTER-18C47;Lo;0;L;;;;;N;;;;; +18C48;KHITAN SMALL SCRIPT CHARACTER-18C48;Lo;0;L;;;;;N;;;;; +18C49;KHITAN SMALL SCRIPT CHARACTER-18C49;Lo;0;L;;;;;N;;;;; +18C4A;KHITAN SMALL SCRIPT CHARACTER-18C4A;Lo;0;L;;;;;N;;;;; +18C4B;KHITAN SMALL SCRIPT CHARACTER-18C4B;Lo;0;L;;;;;N;;;;; +18C4C;KHITAN SMALL SCRIPT CHARACTER-18C4C;Lo;0;L;;;;;N;;;;; +18C4D;KHITAN SMALL SCRIPT CHARACTER-18C4D;Lo;0;L;;;;;N;;;;; +18C4E;KHITAN SMALL SCRIPT CHARACTER-18C4E;Lo;0;L;;;;;N;;;;; +18C4F;KHITAN SMALL SCRIPT CHARACTER-18C4F;Lo;0;L;;;;;N;;;;; +18C50;KHITAN SMALL SCRIPT CHARACTER-18C50;Lo;0;L;;;;;N;;;;; +18C51;KHITAN SMALL SCRIPT CHARACTER-18C51;Lo;0;L;;;;;N;;;;; +18C52;KHITAN SMALL SCRIPT CHARACTER-18C52;Lo;0;L;;;;;N;;;;; +18C53;KHITAN SMALL SCRIPT CHARACTER-18C53;Lo;0;L;;;;;N;;;;; +18C54;KHITAN SMALL SCRIPT CHARACTER-18C54;Lo;0;L;;;;;N;;;;; +18C55;KHITAN SMALL SCRIPT CHARACTER-18C55;Lo;0;L;;;;;N;;;;; +18C56;KHITAN SMALL SCRIPT CHARACTER-18C56;Lo;0;L;;;;;N;;;;; +18C57;KHITAN SMALL SCRIPT CHARACTER-18C57;Lo;0;L;;;;;N;;;;; +18C58;KHITAN SMALL SCRIPT CHARACTER-18C58;Lo;0;L;;;;;N;;;;; +18C59;KHITAN SMALL SCRIPT CHARACTER-18C59;Lo;0;L;;;;;N;;;;; +18C5A;KHITAN SMALL SCRIPT CHARACTER-18C5A;Lo;0;L;;;;;N;;;;; +18C5B;KHITAN SMALL SCRIPT CHARACTER-18C5B;Lo;0;L;;;;;N;;;;; +18C5C;KHITAN SMALL SCRIPT CHARACTER-18C5C;Lo;0;L;;;;;N;;;;; +18C5D;KHITAN SMALL SCRIPT CHARACTER-18C5D;Lo;0;L;;;;;N;;;;; +18C5E;KHITAN SMALL SCRIPT CHARACTER-18C5E;Lo;0;L;;;;;N;;;;; +18C5F;KHITAN SMALL SCRIPT CHARACTER-18C5F;Lo;0;L;;;;;N;;;;; +18C60;KHITAN SMALL SCRIPT CHARACTER-18C60;Lo;0;L;;;;;N;;;;; +18C61;KHITAN SMALL SCRIPT CHARACTER-18C61;Lo;0;L;;;;;N;;;;; +18C62;KHITAN SMALL SCRIPT CHARACTER-18C62;Lo;0;L;;;;;N;;;;; +18C63;KHITAN SMALL SCRIPT CHARACTER-18C63;Lo;0;L;;;;;N;;;;; +18C64;KHITAN SMALL SCRIPT CHARACTER-18C64;Lo;0;L;;;;;N;;;;; +18C65;KHITAN SMALL SCRIPT CHARACTER-18C65;Lo;0;L;;;;;N;;;;; +18C66;KHITAN SMALL SCRIPT CHARACTER-18C66;Lo;0;L;;;;;N;;;;; +18C67;KHITAN SMALL SCRIPT CHARACTER-18C67;Lo;0;L;;;;;N;;;;; +18C68;KHITAN SMALL SCRIPT CHARACTER-18C68;Lo;0;L;;;;;N;;;;; +18C69;KHITAN SMALL SCRIPT CHARACTER-18C69;Lo;0;L;;;;;N;;;;; +18C6A;KHITAN SMALL SCRIPT CHARACTER-18C6A;Lo;0;L;;;;;N;;;;; +18C6B;KHITAN SMALL SCRIPT CHARACTER-18C6B;Lo;0;L;;;;;N;;;;; +18C6C;KHITAN SMALL SCRIPT CHARACTER-18C6C;Lo;0;L;;;;;N;;;;; +18C6D;KHITAN SMALL SCRIPT CHARACTER-18C6D;Lo;0;L;;;;;N;;;;; +18C6E;KHITAN SMALL SCRIPT CHARACTER-18C6E;Lo;0;L;;;;;N;;;;; +18C6F;KHITAN SMALL SCRIPT CHARACTER-18C6F;Lo;0;L;;;;;N;;;;; +18C70;KHITAN SMALL SCRIPT CHARACTER-18C70;Lo;0;L;;;;;N;;;;; +18C71;KHITAN SMALL SCRIPT CHARACTER-18C71;Lo;0;L;;;;;N;;;;; +18C72;KHITAN SMALL SCRIPT CHARACTER-18C72;Lo;0;L;;;;;N;;;;; +18C73;KHITAN SMALL SCRIPT CHARACTER-18C73;Lo;0;L;;;;;N;;;;; +18C74;KHITAN SMALL SCRIPT CHARACTER-18C74;Lo;0;L;;;;;N;;;;; +18C75;KHITAN SMALL SCRIPT CHARACTER-18C75;Lo;0;L;;;;;N;;;;; +18C76;KHITAN SMALL SCRIPT CHARACTER-18C76;Lo;0;L;;;;;N;;;;; +18C77;KHITAN SMALL SCRIPT CHARACTER-18C77;Lo;0;L;;;;;N;;;;; +18C78;KHITAN SMALL SCRIPT CHARACTER-18C78;Lo;0;L;;;;;N;;;;; +18C79;KHITAN SMALL SCRIPT CHARACTER-18C79;Lo;0;L;;;;;N;;;;; +18C7A;KHITAN SMALL SCRIPT CHARACTER-18C7A;Lo;0;L;;;;;N;;;;; +18C7B;KHITAN SMALL SCRIPT CHARACTER-18C7B;Lo;0;L;;;;;N;;;;; +18C7C;KHITAN SMALL SCRIPT CHARACTER-18C7C;Lo;0;L;;;;;N;;;;; +18C7D;KHITAN SMALL SCRIPT CHARACTER-18C7D;Lo;0;L;;;;;N;;;;; +18C7E;KHITAN SMALL SCRIPT CHARACTER-18C7E;Lo;0;L;;;;;N;;;;; +18C7F;KHITAN SMALL SCRIPT CHARACTER-18C7F;Lo;0;L;;;;;N;;;;; +18C80;KHITAN SMALL SCRIPT CHARACTER-18C80;Lo;0;L;;;;;N;;;;; +18C81;KHITAN SMALL SCRIPT CHARACTER-18C81;Lo;0;L;;;;;N;;;;; +18C82;KHITAN SMALL SCRIPT CHARACTER-18C82;Lo;0;L;;;;;N;;;;; +18C83;KHITAN SMALL SCRIPT CHARACTER-18C83;Lo;0;L;;;;;N;;;;; +18C84;KHITAN SMALL SCRIPT CHARACTER-18C84;Lo;0;L;;;;;N;;;;; +18C85;KHITAN SMALL SCRIPT CHARACTER-18C85;Lo;0;L;;;;;N;;;;; +18C86;KHITAN SMALL SCRIPT CHARACTER-18C86;Lo;0;L;;;;;N;;;;; +18C87;KHITAN SMALL SCRIPT CHARACTER-18C87;Lo;0;L;;;;;N;;;;; +18C88;KHITAN SMALL SCRIPT CHARACTER-18C88;Lo;0;L;;;;;N;;;;; +18C89;KHITAN SMALL SCRIPT CHARACTER-18C89;Lo;0;L;;;;;N;;;;; +18C8A;KHITAN SMALL SCRIPT CHARACTER-18C8A;Lo;0;L;;;;;N;;;;; +18C8B;KHITAN SMALL SCRIPT CHARACTER-18C8B;Lo;0;L;;;;;N;;;;; +18C8C;KHITAN SMALL SCRIPT CHARACTER-18C8C;Lo;0;L;;;;;N;;;;; +18C8D;KHITAN SMALL SCRIPT CHARACTER-18C8D;Lo;0;L;;;;;N;;;;; +18C8E;KHITAN SMALL SCRIPT CHARACTER-18C8E;Lo;0;L;;;;;N;;;;; +18C8F;KHITAN SMALL SCRIPT CHARACTER-18C8F;Lo;0;L;;;;;N;;;;; +18C90;KHITAN SMALL SCRIPT CHARACTER-18C90;Lo;0;L;;;;;N;;;;; +18C91;KHITAN SMALL SCRIPT CHARACTER-18C91;Lo;0;L;;;;;N;;;;; +18C92;KHITAN SMALL SCRIPT CHARACTER-18C92;Lo;0;L;;;;;N;;;;; +18C93;KHITAN SMALL SCRIPT CHARACTER-18C93;Lo;0;L;;;;;N;;;;; +18C94;KHITAN SMALL SCRIPT CHARACTER-18C94;Lo;0;L;;;;;N;;;;; +18C95;KHITAN SMALL SCRIPT CHARACTER-18C95;Lo;0;L;;;;;N;;;;; +18C96;KHITAN SMALL SCRIPT CHARACTER-18C96;Lo;0;L;;;;;N;;;;; +18C97;KHITAN SMALL SCRIPT CHARACTER-18C97;Lo;0;L;;;;;N;;;;; +18C98;KHITAN SMALL SCRIPT CHARACTER-18C98;Lo;0;L;;;;;N;;;;; +18C99;KHITAN SMALL SCRIPT CHARACTER-18C99;Lo;0;L;;;;;N;;;;; +18C9A;KHITAN SMALL SCRIPT CHARACTER-18C9A;Lo;0;L;;;;;N;;;;; +18C9B;KHITAN SMALL SCRIPT CHARACTER-18C9B;Lo;0;L;;;;;N;;;;; +18C9C;KHITAN SMALL SCRIPT CHARACTER-18C9C;Lo;0;L;;;;;N;;;;; +18C9D;KHITAN SMALL SCRIPT CHARACTER-18C9D;Lo;0;L;;;;;N;;;;; +18C9E;KHITAN SMALL SCRIPT CHARACTER-18C9E;Lo;0;L;;;;;N;;;;; +18C9F;KHITAN SMALL SCRIPT CHARACTER-18C9F;Lo;0;L;;;;;N;;;;; +18CA0;KHITAN SMALL SCRIPT CHARACTER-18CA0;Lo;0;L;;;;;N;;;;; +18CA1;KHITAN SMALL SCRIPT CHARACTER-18CA1;Lo;0;L;;;;;N;;;;; +18CA2;KHITAN SMALL SCRIPT CHARACTER-18CA2;Lo;0;L;;;;;N;;;;; +18CA3;KHITAN SMALL SCRIPT CHARACTER-18CA3;Lo;0;L;;;;;N;;;;; +18CA4;KHITAN SMALL SCRIPT CHARACTER-18CA4;Lo;0;L;;;;;N;;;;; +18CA5;KHITAN SMALL SCRIPT CHARACTER-18CA5;Lo;0;L;;;;;N;;;;; +18CA6;KHITAN SMALL SCRIPT CHARACTER-18CA6;Lo;0;L;;;;;N;;;;; +18CA7;KHITAN SMALL SCRIPT CHARACTER-18CA7;Lo;0;L;;;;;N;;;;; +18CA8;KHITAN SMALL SCRIPT CHARACTER-18CA8;Lo;0;L;;;;;N;;;;; +18CA9;KHITAN SMALL SCRIPT CHARACTER-18CA9;Lo;0;L;;;;;N;;;;; +18CAA;KHITAN SMALL SCRIPT CHARACTER-18CAA;Lo;0;L;;;;;N;;;;; +18CAB;KHITAN SMALL SCRIPT CHARACTER-18CAB;Lo;0;L;;;;;N;;;;; +18CAC;KHITAN SMALL SCRIPT CHARACTER-18CAC;Lo;0;L;;;;;N;;;;; +18CAD;KHITAN SMALL SCRIPT CHARACTER-18CAD;Lo;0;L;;;;;N;;;;; +18CAE;KHITAN SMALL SCRIPT CHARACTER-18CAE;Lo;0;L;;;;;N;;;;; +18CAF;KHITAN SMALL SCRIPT CHARACTER-18CAF;Lo;0;L;;;;;N;;;;; +18CB0;KHITAN SMALL SCRIPT CHARACTER-18CB0;Lo;0;L;;;;;N;;;;; +18CB1;KHITAN SMALL SCRIPT CHARACTER-18CB1;Lo;0;L;;;;;N;;;;; +18CB2;KHITAN SMALL SCRIPT CHARACTER-18CB2;Lo;0;L;;;;;N;;;;; +18CB3;KHITAN SMALL SCRIPT CHARACTER-18CB3;Lo;0;L;;;;;N;;;;; +18CB4;KHITAN SMALL SCRIPT CHARACTER-18CB4;Lo;0;L;;;;;N;;;;; +18CB5;KHITAN SMALL SCRIPT CHARACTER-18CB5;Lo;0;L;;;;;N;;;;; +18CB6;KHITAN SMALL SCRIPT CHARACTER-18CB6;Lo;0;L;;;;;N;;;;; +18CB7;KHITAN SMALL SCRIPT CHARACTER-18CB7;Lo;0;L;;;;;N;;;;; +18CB8;KHITAN SMALL SCRIPT CHARACTER-18CB8;Lo;0;L;;;;;N;;;;; +18CB9;KHITAN SMALL SCRIPT CHARACTER-18CB9;Lo;0;L;;;;;N;;;;; +18CBA;KHITAN SMALL SCRIPT CHARACTER-18CBA;Lo;0;L;;;;;N;;;;; +18CBB;KHITAN SMALL SCRIPT CHARACTER-18CBB;Lo;0;L;;;;;N;;;;; +18CBC;KHITAN SMALL SCRIPT CHARACTER-18CBC;Lo;0;L;;;;;N;;;;; +18CBD;KHITAN SMALL SCRIPT CHARACTER-18CBD;Lo;0;L;;;;;N;;;;; +18CBE;KHITAN SMALL SCRIPT CHARACTER-18CBE;Lo;0;L;;;;;N;;;;; +18CBF;KHITAN SMALL SCRIPT CHARACTER-18CBF;Lo;0;L;;;;;N;;;;; +18CC0;KHITAN SMALL SCRIPT CHARACTER-18CC0;Lo;0;L;;;;;N;;;;; +18CC1;KHITAN SMALL SCRIPT CHARACTER-18CC1;Lo;0;L;;;;;N;;;;; +18CC2;KHITAN SMALL SCRIPT CHARACTER-18CC2;Lo;0;L;;;;;N;;;;; +18CC3;KHITAN SMALL SCRIPT CHARACTER-18CC3;Lo;0;L;;;;;N;;;;; +18CC4;KHITAN SMALL SCRIPT CHARACTER-18CC4;Lo;0;L;;;;;N;;;;; +18CC5;KHITAN SMALL SCRIPT CHARACTER-18CC5;Lo;0;L;;;;;N;;;;; +18CC6;KHITAN SMALL SCRIPT CHARACTER-18CC6;Lo;0;L;;;;;N;;;;; +18CC7;KHITAN SMALL SCRIPT CHARACTER-18CC7;Lo;0;L;;;;;N;;;;; +18CC8;KHITAN SMALL SCRIPT CHARACTER-18CC8;Lo;0;L;;;;;N;;;;; +18CC9;KHITAN SMALL SCRIPT CHARACTER-18CC9;Lo;0;L;;;;;N;;;;; +18CCA;KHITAN SMALL SCRIPT CHARACTER-18CCA;Lo;0;L;;;;;N;;;;; +18CCB;KHITAN SMALL SCRIPT CHARACTER-18CCB;Lo;0;L;;;;;N;;;;; +18CCC;KHITAN SMALL SCRIPT CHARACTER-18CCC;Lo;0;L;;;;;N;;;;; +18CCD;KHITAN SMALL SCRIPT CHARACTER-18CCD;Lo;0;L;;;;;N;;;;; +18CCE;KHITAN SMALL SCRIPT CHARACTER-18CCE;Lo;0;L;;;;;N;;;;; +18CCF;KHITAN SMALL SCRIPT CHARACTER-18CCF;Lo;0;L;;;;;N;;;;; +18CD0;KHITAN SMALL SCRIPT CHARACTER-18CD0;Lo;0;L;;;;;N;;;;; +18CD1;KHITAN SMALL SCRIPT CHARACTER-18CD1;Lo;0;L;;;;;N;;;;; +18CD2;KHITAN SMALL SCRIPT CHARACTER-18CD2;Lo;0;L;;;;;N;;;;; +18CD3;KHITAN SMALL SCRIPT CHARACTER-18CD3;Lo;0;L;;;;;N;;;;; +18CD4;KHITAN SMALL SCRIPT CHARACTER-18CD4;Lo;0;L;;;;;N;;;;; +18CD5;KHITAN SMALL SCRIPT CHARACTER-18CD5;Lo;0;L;;;;;N;;;;; +18D00;;Lo;0;L;;;;;N;;;;; +18D08;;Lo;0;L;;;;;N;;;;; 1B000;KATAKANA LETTER ARCHAIC E;Lo;0;L;;;;;N;;;;; 1B001;HIRAGANA LETTER ARCHAIC YE;Lo;0;L;;;;;N;;;;; +1B002;HENTAIGANA LETTER A-1;Lo;0;L;;;;;N;;;;; +1B003;HENTAIGANA LETTER A-2;Lo;0;L;;;;;N;;;;; +1B004;HENTAIGANA LETTER A-3;Lo;0;L;;;;;N;;;;; +1B005;HENTAIGANA LETTER A-WO;Lo;0;L;;;;;N;;;;; +1B006;HENTAIGANA LETTER I-1;Lo;0;L;;;;;N;;;;; +1B007;HENTAIGANA LETTER I-2;Lo;0;L;;;;;N;;;;; +1B008;HENTAIGANA LETTER I-3;Lo;0;L;;;;;N;;;;; +1B009;HENTAIGANA LETTER I-4;Lo;0;L;;;;;N;;;;; +1B00A;HENTAIGANA LETTER U-1;Lo;0;L;;;;;N;;;;; +1B00B;HENTAIGANA LETTER U-2;Lo;0;L;;;;;N;;;;; +1B00C;HENTAIGANA LETTER U-3;Lo;0;L;;;;;N;;;;; +1B00D;HENTAIGANA LETTER U-4;Lo;0;L;;;;;N;;;;; +1B00E;HENTAIGANA LETTER U-5;Lo;0;L;;;;;N;;;;; +1B00F;HENTAIGANA LETTER E-2;Lo;0;L;;;;;N;;;;; +1B010;HENTAIGANA LETTER E-3;Lo;0;L;;;;;N;;;;; +1B011;HENTAIGANA LETTER E-4;Lo;0;L;;;;;N;;;;; +1B012;HENTAIGANA LETTER E-5;Lo;0;L;;;;;N;;;;; +1B013;HENTAIGANA LETTER E-6;Lo;0;L;;;;;N;;;;; +1B014;HENTAIGANA LETTER O-1;Lo;0;L;;;;;N;;;;; +1B015;HENTAIGANA LETTER O-2;Lo;0;L;;;;;N;;;;; +1B016;HENTAIGANA LETTER O-3;Lo;0;L;;;;;N;;;;; +1B017;HENTAIGANA LETTER KA-1;Lo;0;L;;;;;N;;;;; +1B018;HENTAIGANA LETTER KA-2;Lo;0;L;;;;;N;;;;; +1B019;HENTAIGANA LETTER KA-3;Lo;0;L;;;;;N;;;;; +1B01A;HENTAIGANA LETTER KA-4;Lo;0;L;;;;;N;;;;; +1B01B;HENTAIGANA LETTER KA-5;Lo;0;L;;;;;N;;;;; +1B01C;HENTAIGANA LETTER KA-6;Lo;0;L;;;;;N;;;;; +1B01D;HENTAIGANA LETTER KA-7;Lo;0;L;;;;;N;;;;; +1B01E;HENTAIGANA LETTER KA-8;Lo;0;L;;;;;N;;;;; +1B01F;HENTAIGANA LETTER KA-9;Lo;0;L;;;;;N;;;;; +1B020;HENTAIGANA LETTER KA-10;Lo;0;L;;;;;N;;;;; +1B021;HENTAIGANA LETTER KA-11;Lo;0;L;;;;;N;;;;; +1B022;HENTAIGANA LETTER KA-KE;Lo;0;L;;;;;N;;;;; +1B023;HENTAIGANA LETTER KI-1;Lo;0;L;;;;;N;;;;; +1B024;HENTAIGANA LETTER KI-2;Lo;0;L;;;;;N;;;;; +1B025;HENTAIGANA LETTER KI-3;Lo;0;L;;;;;N;;;;; +1B026;HENTAIGANA LETTER KI-4;Lo;0;L;;;;;N;;;;; +1B027;HENTAIGANA LETTER KI-5;Lo;0;L;;;;;N;;;;; +1B028;HENTAIGANA LETTER KI-6;Lo;0;L;;;;;N;;;;; +1B029;HENTAIGANA LETTER KI-7;Lo;0;L;;;;;N;;;;; +1B02A;HENTAIGANA LETTER KI-8;Lo;0;L;;;;;N;;;;; +1B02B;HENTAIGANA LETTER KU-1;Lo;0;L;;;;;N;;;;; +1B02C;HENTAIGANA LETTER KU-2;Lo;0;L;;;;;N;;;;; +1B02D;HENTAIGANA LETTER KU-3;Lo;0;L;;;;;N;;;;; +1B02E;HENTAIGANA LETTER KU-4;Lo;0;L;;;;;N;;;;; +1B02F;HENTAIGANA LETTER KU-5;Lo;0;L;;;;;N;;;;; +1B030;HENTAIGANA LETTER KU-6;Lo;0;L;;;;;N;;;;; +1B031;HENTAIGANA LETTER KU-7;Lo;0;L;;;;;N;;;;; +1B032;HENTAIGANA LETTER KE-1;Lo;0;L;;;;;N;;;;; +1B033;HENTAIGANA LETTER KE-2;Lo;0;L;;;;;N;;;;; +1B034;HENTAIGANA LETTER KE-3;Lo;0;L;;;;;N;;;;; +1B035;HENTAIGANA LETTER KE-4;Lo;0;L;;;;;N;;;;; +1B036;HENTAIGANA LETTER KE-5;Lo;0;L;;;;;N;;;;; +1B037;HENTAIGANA LETTER KE-6;Lo;0;L;;;;;N;;;;; +1B038;HENTAIGANA LETTER KO-1;Lo;0;L;;;;;N;;;;; +1B039;HENTAIGANA LETTER KO-2;Lo;0;L;;;;;N;;;;; +1B03A;HENTAIGANA LETTER KO-3;Lo;0;L;;;;;N;;;;; +1B03B;HENTAIGANA LETTER KO-KI;Lo;0;L;;;;;N;;;;; +1B03C;HENTAIGANA LETTER SA-1;Lo;0;L;;;;;N;;;;; +1B03D;HENTAIGANA LETTER SA-2;Lo;0;L;;;;;N;;;;; +1B03E;HENTAIGANA LETTER SA-3;Lo;0;L;;;;;N;;;;; +1B03F;HENTAIGANA LETTER SA-4;Lo;0;L;;;;;N;;;;; +1B040;HENTAIGANA LETTER SA-5;Lo;0;L;;;;;N;;;;; +1B041;HENTAIGANA LETTER SA-6;Lo;0;L;;;;;N;;;;; +1B042;HENTAIGANA LETTER SA-7;Lo;0;L;;;;;N;;;;; +1B043;HENTAIGANA LETTER SA-8;Lo;0;L;;;;;N;;;;; +1B044;HENTAIGANA LETTER SI-1;Lo;0;L;;;;;N;;;;; +1B045;HENTAIGANA LETTER SI-2;Lo;0;L;;;;;N;;;;; +1B046;HENTAIGANA LETTER SI-3;Lo;0;L;;;;;N;;;;; +1B047;HENTAIGANA LETTER SI-4;Lo;0;L;;;;;N;;;;; +1B048;HENTAIGANA LETTER SI-5;Lo;0;L;;;;;N;;;;; +1B049;HENTAIGANA LETTER SI-6;Lo;0;L;;;;;N;;;;; +1B04A;HENTAIGANA LETTER SU-1;Lo;0;L;;;;;N;;;;; +1B04B;HENTAIGANA LETTER SU-2;Lo;0;L;;;;;N;;;;; +1B04C;HENTAIGANA LETTER SU-3;Lo;0;L;;;;;N;;;;; +1B04D;HENTAIGANA LETTER SU-4;Lo;0;L;;;;;N;;;;; +1B04E;HENTAIGANA LETTER SU-5;Lo;0;L;;;;;N;;;;; +1B04F;HENTAIGANA LETTER SU-6;Lo;0;L;;;;;N;;;;; +1B050;HENTAIGANA LETTER SU-7;Lo;0;L;;;;;N;;;;; +1B051;HENTAIGANA LETTER SU-8;Lo;0;L;;;;;N;;;;; +1B052;HENTAIGANA LETTER SE-1;Lo;0;L;;;;;N;;;;; +1B053;HENTAIGANA LETTER SE-2;Lo;0;L;;;;;N;;;;; +1B054;HENTAIGANA LETTER SE-3;Lo;0;L;;;;;N;;;;; +1B055;HENTAIGANA LETTER SE-4;Lo;0;L;;;;;N;;;;; +1B056;HENTAIGANA LETTER SE-5;Lo;0;L;;;;;N;;;;; +1B057;HENTAIGANA LETTER SO-1;Lo;0;L;;;;;N;;;;; +1B058;HENTAIGANA LETTER SO-2;Lo;0;L;;;;;N;;;;; +1B059;HENTAIGANA LETTER SO-3;Lo;0;L;;;;;N;;;;; +1B05A;HENTAIGANA LETTER SO-4;Lo;0;L;;;;;N;;;;; +1B05B;HENTAIGANA LETTER SO-5;Lo;0;L;;;;;N;;;;; +1B05C;HENTAIGANA LETTER SO-6;Lo;0;L;;;;;N;;;;; +1B05D;HENTAIGANA LETTER SO-7;Lo;0;L;;;;;N;;;;; +1B05E;HENTAIGANA LETTER TA-1;Lo;0;L;;;;;N;;;;; +1B05F;HENTAIGANA LETTER TA-2;Lo;0;L;;;;;N;;;;; +1B060;HENTAIGANA LETTER TA-3;Lo;0;L;;;;;N;;;;; +1B061;HENTAIGANA LETTER TA-4;Lo;0;L;;;;;N;;;;; +1B062;HENTAIGANA LETTER TI-1;Lo;0;L;;;;;N;;;;; +1B063;HENTAIGANA LETTER TI-2;Lo;0;L;;;;;N;;;;; +1B064;HENTAIGANA LETTER TI-3;Lo;0;L;;;;;N;;;;; +1B065;HENTAIGANA LETTER TI-4;Lo;0;L;;;;;N;;;;; +1B066;HENTAIGANA LETTER TI-5;Lo;0;L;;;;;N;;;;; +1B067;HENTAIGANA LETTER TI-6;Lo;0;L;;;;;N;;;;; +1B068;HENTAIGANA LETTER TI-7;Lo;0;L;;;;;N;;;;; +1B069;HENTAIGANA LETTER TU-1;Lo;0;L;;;;;N;;;;; +1B06A;HENTAIGANA LETTER TU-2;Lo;0;L;;;;;N;;;;; +1B06B;HENTAIGANA LETTER TU-3;Lo;0;L;;;;;N;;;;; +1B06C;HENTAIGANA LETTER TU-4;Lo;0;L;;;;;N;;;;; +1B06D;HENTAIGANA LETTER TU-TO;Lo;0;L;;;;;N;;;;; +1B06E;HENTAIGANA LETTER TE-1;Lo;0;L;;;;;N;;;;; +1B06F;HENTAIGANA LETTER TE-2;Lo;0;L;;;;;N;;;;; +1B070;HENTAIGANA LETTER TE-3;Lo;0;L;;;;;N;;;;; +1B071;HENTAIGANA LETTER TE-4;Lo;0;L;;;;;N;;;;; +1B072;HENTAIGANA LETTER TE-5;Lo;0;L;;;;;N;;;;; +1B073;HENTAIGANA LETTER TE-6;Lo;0;L;;;;;N;;;;; +1B074;HENTAIGANA LETTER TE-7;Lo;0;L;;;;;N;;;;; +1B075;HENTAIGANA LETTER TE-8;Lo;0;L;;;;;N;;;;; +1B076;HENTAIGANA LETTER TE-9;Lo;0;L;;;;;N;;;;; +1B077;HENTAIGANA LETTER TO-1;Lo;0;L;;;;;N;;;;; +1B078;HENTAIGANA LETTER TO-2;Lo;0;L;;;;;N;;;;; +1B079;HENTAIGANA LETTER TO-3;Lo;0;L;;;;;N;;;;; +1B07A;HENTAIGANA LETTER TO-4;Lo;0;L;;;;;N;;;;; +1B07B;HENTAIGANA LETTER TO-5;Lo;0;L;;;;;N;;;;; +1B07C;HENTAIGANA LETTER TO-6;Lo;0;L;;;;;N;;;;; +1B07D;HENTAIGANA LETTER TO-RA;Lo;0;L;;;;;N;;;;; +1B07E;HENTAIGANA LETTER NA-1;Lo;0;L;;;;;N;;;;; +1B07F;HENTAIGANA LETTER NA-2;Lo;0;L;;;;;N;;;;; +1B080;HENTAIGANA LETTER NA-3;Lo;0;L;;;;;N;;;;; +1B081;HENTAIGANA LETTER NA-4;Lo;0;L;;;;;N;;;;; +1B082;HENTAIGANA LETTER NA-5;Lo;0;L;;;;;N;;;;; +1B083;HENTAIGANA LETTER NA-6;Lo;0;L;;;;;N;;;;; +1B084;HENTAIGANA LETTER NA-7;Lo;0;L;;;;;N;;;;; +1B085;HENTAIGANA LETTER NA-8;Lo;0;L;;;;;N;;;;; +1B086;HENTAIGANA LETTER NA-9;Lo;0;L;;;;;N;;;;; +1B087;HENTAIGANA LETTER NI-1;Lo;0;L;;;;;N;;;;; +1B088;HENTAIGANA LETTER NI-2;Lo;0;L;;;;;N;;;;; +1B089;HENTAIGANA LETTER NI-3;Lo;0;L;;;;;N;;;;; +1B08A;HENTAIGANA LETTER NI-4;Lo;0;L;;;;;N;;;;; +1B08B;HENTAIGANA LETTER NI-5;Lo;0;L;;;;;N;;;;; +1B08C;HENTAIGANA LETTER NI-6;Lo;0;L;;;;;N;;;;; +1B08D;HENTAIGANA LETTER NI-7;Lo;0;L;;;;;N;;;;; +1B08E;HENTAIGANA LETTER NI-TE;Lo;0;L;;;;;N;;;;; +1B08F;HENTAIGANA LETTER NU-1;Lo;0;L;;;;;N;;;;; +1B090;HENTAIGANA LETTER NU-2;Lo;0;L;;;;;N;;;;; +1B091;HENTAIGANA LETTER NU-3;Lo;0;L;;;;;N;;;;; +1B092;HENTAIGANA LETTER NE-1;Lo;0;L;;;;;N;;;;; +1B093;HENTAIGANA LETTER NE-2;Lo;0;L;;;;;N;;;;; +1B094;HENTAIGANA LETTER NE-3;Lo;0;L;;;;;N;;;;; +1B095;HENTAIGANA LETTER NE-4;Lo;0;L;;;;;N;;;;; +1B096;HENTAIGANA LETTER NE-5;Lo;0;L;;;;;N;;;;; +1B097;HENTAIGANA LETTER NE-6;Lo;0;L;;;;;N;;;;; +1B098;HENTAIGANA LETTER NE-KO;Lo;0;L;;;;;N;;;;; +1B099;HENTAIGANA LETTER NO-1;Lo;0;L;;;;;N;;;;; +1B09A;HENTAIGANA LETTER NO-2;Lo;0;L;;;;;N;;;;; +1B09B;HENTAIGANA LETTER NO-3;Lo;0;L;;;;;N;;;;; +1B09C;HENTAIGANA LETTER NO-4;Lo;0;L;;;;;N;;;;; +1B09D;HENTAIGANA LETTER NO-5;Lo;0;L;;;;;N;;;;; +1B09E;HENTAIGANA LETTER HA-1;Lo;0;L;;;;;N;;;;; +1B09F;HENTAIGANA LETTER HA-2;Lo;0;L;;;;;N;;;;; +1B0A0;HENTAIGANA LETTER HA-3;Lo;0;L;;;;;N;;;;; +1B0A1;HENTAIGANA LETTER HA-4;Lo;0;L;;;;;N;;;;; +1B0A2;HENTAIGANA LETTER HA-5;Lo;0;L;;;;;N;;;;; +1B0A3;HENTAIGANA LETTER HA-6;Lo;0;L;;;;;N;;;;; +1B0A4;HENTAIGANA LETTER HA-7;Lo;0;L;;;;;N;;;;; +1B0A5;HENTAIGANA LETTER HA-8;Lo;0;L;;;;;N;;;;; +1B0A6;HENTAIGANA LETTER HA-9;Lo;0;L;;;;;N;;;;; +1B0A7;HENTAIGANA LETTER HA-10;Lo;0;L;;;;;N;;;;; +1B0A8;HENTAIGANA LETTER HA-11;Lo;0;L;;;;;N;;;;; +1B0A9;HENTAIGANA LETTER HI-1;Lo;0;L;;;;;N;;;;; +1B0AA;HENTAIGANA LETTER HI-2;Lo;0;L;;;;;N;;;;; +1B0AB;HENTAIGANA LETTER HI-3;Lo;0;L;;;;;N;;;;; +1B0AC;HENTAIGANA LETTER HI-4;Lo;0;L;;;;;N;;;;; +1B0AD;HENTAIGANA LETTER HI-5;Lo;0;L;;;;;N;;;;; +1B0AE;HENTAIGANA LETTER HI-6;Lo;0;L;;;;;N;;;;; +1B0AF;HENTAIGANA LETTER HI-7;Lo;0;L;;;;;N;;;;; +1B0B0;HENTAIGANA LETTER HU-1;Lo;0;L;;;;;N;;;;; +1B0B1;HENTAIGANA LETTER HU-2;Lo;0;L;;;;;N;;;;; +1B0B2;HENTAIGANA LETTER HU-3;Lo;0;L;;;;;N;;;;; +1B0B3;HENTAIGANA LETTER HE-1;Lo;0;L;;;;;N;;;;; +1B0B4;HENTAIGANA LETTER HE-2;Lo;0;L;;;;;N;;;;; +1B0B5;HENTAIGANA LETTER HE-3;Lo;0;L;;;;;N;;;;; +1B0B6;HENTAIGANA LETTER HE-4;Lo;0;L;;;;;N;;;;; +1B0B7;HENTAIGANA LETTER HE-5;Lo;0;L;;;;;N;;;;; +1B0B8;HENTAIGANA LETTER HE-6;Lo;0;L;;;;;N;;;;; +1B0B9;HENTAIGANA LETTER HE-7;Lo;0;L;;;;;N;;;;; +1B0BA;HENTAIGANA LETTER HO-1;Lo;0;L;;;;;N;;;;; +1B0BB;HENTAIGANA LETTER HO-2;Lo;0;L;;;;;N;;;;; +1B0BC;HENTAIGANA LETTER HO-3;Lo;0;L;;;;;N;;;;; +1B0BD;HENTAIGANA LETTER HO-4;Lo;0;L;;;;;N;;;;; +1B0BE;HENTAIGANA LETTER HO-5;Lo;0;L;;;;;N;;;;; +1B0BF;HENTAIGANA LETTER HO-6;Lo;0;L;;;;;N;;;;; +1B0C0;HENTAIGANA LETTER HO-7;Lo;0;L;;;;;N;;;;; +1B0C1;HENTAIGANA LETTER HO-8;Lo;0;L;;;;;N;;;;; +1B0C2;HENTAIGANA LETTER MA-1;Lo;0;L;;;;;N;;;;; +1B0C3;HENTAIGANA LETTER MA-2;Lo;0;L;;;;;N;;;;; +1B0C4;HENTAIGANA LETTER MA-3;Lo;0;L;;;;;N;;;;; +1B0C5;HENTAIGANA LETTER MA-4;Lo;0;L;;;;;N;;;;; +1B0C6;HENTAIGANA LETTER MA-5;Lo;0;L;;;;;N;;;;; +1B0C7;HENTAIGANA LETTER MA-6;Lo;0;L;;;;;N;;;;; +1B0C8;HENTAIGANA LETTER MA-7;Lo;0;L;;;;;N;;;;; +1B0C9;HENTAIGANA LETTER MI-1;Lo;0;L;;;;;N;;;;; +1B0CA;HENTAIGANA LETTER MI-2;Lo;0;L;;;;;N;;;;; +1B0CB;HENTAIGANA LETTER MI-3;Lo;0;L;;;;;N;;;;; +1B0CC;HENTAIGANA LETTER MI-4;Lo;0;L;;;;;N;;;;; +1B0CD;HENTAIGANA LETTER MI-5;Lo;0;L;;;;;N;;;;; +1B0CE;HENTAIGANA LETTER MI-6;Lo;0;L;;;;;N;;;;; +1B0CF;HENTAIGANA LETTER MI-7;Lo;0;L;;;;;N;;;;; +1B0D0;HENTAIGANA LETTER MU-1;Lo;0;L;;;;;N;;;;; +1B0D1;HENTAIGANA LETTER MU-2;Lo;0;L;;;;;N;;;;; +1B0D2;HENTAIGANA LETTER MU-3;Lo;0;L;;;;;N;;;;; +1B0D3;HENTAIGANA LETTER MU-4;Lo;0;L;;;;;N;;;;; +1B0D4;HENTAIGANA LETTER ME-1;Lo;0;L;;;;;N;;;;; +1B0D5;HENTAIGANA LETTER ME-2;Lo;0;L;;;;;N;;;;; +1B0D6;HENTAIGANA LETTER ME-MA;Lo;0;L;;;;;N;;;;; +1B0D7;HENTAIGANA LETTER MO-1;Lo;0;L;;;;;N;;;;; +1B0D8;HENTAIGANA LETTER MO-2;Lo;0;L;;;;;N;;;;; +1B0D9;HENTAIGANA LETTER MO-3;Lo;0;L;;;;;N;;;;; +1B0DA;HENTAIGANA LETTER MO-4;Lo;0;L;;;;;N;;;;; +1B0DB;HENTAIGANA LETTER MO-5;Lo;0;L;;;;;N;;;;; +1B0DC;HENTAIGANA LETTER MO-6;Lo;0;L;;;;;N;;;;; +1B0DD;HENTAIGANA LETTER YA-1;Lo;0;L;;;;;N;;;;; +1B0DE;HENTAIGANA LETTER YA-2;Lo;0;L;;;;;N;;;;; +1B0DF;HENTAIGANA LETTER YA-3;Lo;0;L;;;;;N;;;;; +1B0E0;HENTAIGANA LETTER YA-4;Lo;0;L;;;;;N;;;;; +1B0E1;HENTAIGANA LETTER YA-5;Lo;0;L;;;;;N;;;;; +1B0E2;HENTAIGANA LETTER YA-YO;Lo;0;L;;;;;N;;;;; +1B0E3;HENTAIGANA LETTER YU-1;Lo;0;L;;;;;N;;;;; +1B0E4;HENTAIGANA LETTER YU-2;Lo;0;L;;;;;N;;;;; +1B0E5;HENTAIGANA LETTER YU-3;Lo;0;L;;;;;N;;;;; +1B0E6;HENTAIGANA LETTER YU-4;Lo;0;L;;;;;N;;;;; +1B0E7;HENTAIGANA LETTER YO-1;Lo;0;L;;;;;N;;;;; +1B0E8;HENTAIGANA LETTER YO-2;Lo;0;L;;;;;N;;;;; +1B0E9;HENTAIGANA LETTER YO-3;Lo;0;L;;;;;N;;;;; +1B0EA;HENTAIGANA LETTER YO-4;Lo;0;L;;;;;N;;;;; +1B0EB;HENTAIGANA LETTER YO-5;Lo;0;L;;;;;N;;;;; +1B0EC;HENTAIGANA LETTER YO-6;Lo;0;L;;;;;N;;;;; +1B0ED;HENTAIGANA LETTER RA-1;Lo;0;L;;;;;N;;;;; +1B0EE;HENTAIGANA LETTER RA-2;Lo;0;L;;;;;N;;;;; +1B0EF;HENTAIGANA LETTER RA-3;Lo;0;L;;;;;N;;;;; +1B0F0;HENTAIGANA LETTER RA-4;Lo;0;L;;;;;N;;;;; +1B0F1;HENTAIGANA LETTER RI-1;Lo;0;L;;;;;N;;;;; +1B0F2;HENTAIGANA LETTER RI-2;Lo;0;L;;;;;N;;;;; +1B0F3;HENTAIGANA LETTER RI-3;Lo;0;L;;;;;N;;;;; +1B0F4;HENTAIGANA LETTER RI-4;Lo;0;L;;;;;N;;;;; +1B0F5;HENTAIGANA LETTER RI-5;Lo;0;L;;;;;N;;;;; +1B0F6;HENTAIGANA LETTER RI-6;Lo;0;L;;;;;N;;;;; +1B0F7;HENTAIGANA LETTER RI-7;Lo;0;L;;;;;N;;;;; +1B0F8;HENTAIGANA LETTER RU-1;Lo;0;L;;;;;N;;;;; +1B0F9;HENTAIGANA LETTER RU-2;Lo;0;L;;;;;N;;;;; +1B0FA;HENTAIGANA LETTER RU-3;Lo;0;L;;;;;N;;;;; +1B0FB;HENTAIGANA LETTER RU-4;Lo;0;L;;;;;N;;;;; +1B0FC;HENTAIGANA LETTER RU-5;Lo;0;L;;;;;N;;;;; +1B0FD;HENTAIGANA LETTER RU-6;Lo;0;L;;;;;N;;;;; +1B0FE;HENTAIGANA LETTER RE-1;Lo;0;L;;;;;N;;;;; +1B0FF;HENTAIGANA LETTER RE-2;Lo;0;L;;;;;N;;;;; +1B100;HENTAIGANA LETTER RE-3;Lo;0;L;;;;;N;;;;; +1B101;HENTAIGANA LETTER RE-4;Lo;0;L;;;;;N;;;;; +1B102;HENTAIGANA LETTER RO-1;Lo;0;L;;;;;N;;;;; +1B103;HENTAIGANA LETTER RO-2;Lo;0;L;;;;;N;;;;; +1B104;HENTAIGANA LETTER RO-3;Lo;0;L;;;;;N;;;;; +1B105;HENTAIGANA LETTER RO-4;Lo;0;L;;;;;N;;;;; +1B106;HENTAIGANA LETTER RO-5;Lo;0;L;;;;;N;;;;; +1B107;HENTAIGANA LETTER RO-6;Lo;0;L;;;;;N;;;;; +1B108;HENTAIGANA LETTER WA-1;Lo;0;L;;;;;N;;;;; +1B109;HENTAIGANA LETTER WA-2;Lo;0;L;;;;;N;;;;; +1B10A;HENTAIGANA LETTER WA-3;Lo;0;L;;;;;N;;;;; +1B10B;HENTAIGANA LETTER WA-4;Lo;0;L;;;;;N;;;;; +1B10C;HENTAIGANA LETTER WA-5;Lo;0;L;;;;;N;;;;; +1B10D;HENTAIGANA LETTER WI-1;Lo;0;L;;;;;N;;;;; +1B10E;HENTAIGANA LETTER WI-2;Lo;0;L;;;;;N;;;;; +1B10F;HENTAIGANA LETTER WI-3;Lo;0;L;;;;;N;;;;; +1B110;HENTAIGANA LETTER WI-4;Lo;0;L;;;;;N;;;;; +1B111;HENTAIGANA LETTER WI-5;Lo;0;L;;;;;N;;;;; +1B112;HENTAIGANA LETTER WE-1;Lo;0;L;;;;;N;;;;; +1B113;HENTAIGANA LETTER WE-2;Lo;0;L;;;;;N;;;;; +1B114;HENTAIGANA LETTER WE-3;Lo;0;L;;;;;N;;;;; +1B115;HENTAIGANA LETTER WE-4;Lo;0;L;;;;;N;;;;; +1B116;HENTAIGANA LETTER WO-1;Lo;0;L;;;;;N;;;;; +1B117;HENTAIGANA LETTER WO-2;Lo;0;L;;;;;N;;;;; +1B118;HENTAIGANA LETTER WO-3;Lo;0;L;;;;;N;;;;; +1B119;HENTAIGANA LETTER WO-4;Lo;0;L;;;;;N;;;;; +1B11A;HENTAIGANA LETTER WO-5;Lo;0;L;;;;;N;;;;; +1B11B;HENTAIGANA LETTER WO-6;Lo;0;L;;;;;N;;;;; +1B11C;HENTAIGANA LETTER WO-7;Lo;0;L;;;;;N;;;;; +1B11D;HENTAIGANA LETTER N-MU-MO-1;Lo;0;L;;;;;N;;;;; +1B11E;HENTAIGANA LETTER N-MU-MO-2;Lo;0;L;;;;;N;;;;; +1B150;HIRAGANA LETTER SMALL WI;Lo;0;L;;;;;N;;;;; +1B151;HIRAGANA LETTER SMALL WE;Lo;0;L;;;;;N;;;;; +1B152;HIRAGANA LETTER SMALL WO;Lo;0;L;;;;;N;;;;; +1B164;KATAKANA LETTER SMALL WI;Lo;0;L;;;;;N;;;;; +1B165;KATAKANA LETTER SMALL WE;Lo;0;L;;;;;N;;;;; +1B166;KATAKANA LETTER SMALL WO;Lo;0;L;;;;;N;;;;; +1B167;KATAKANA LETTER SMALL N;Lo;0;L;;;;;N;;;;; +1B170;NUSHU CHARACTER-1B170;Lo;0;L;;;;;N;;;;; +1B171;NUSHU CHARACTER-1B171;Lo;0;L;;;;;N;;;;; +1B172;NUSHU CHARACTER-1B172;Lo;0;L;;;;;N;;;;; +1B173;NUSHU CHARACTER-1B173;Lo;0;L;;;;;N;;;;; +1B174;NUSHU CHARACTER-1B174;Lo;0;L;;;;;N;;;;; +1B175;NUSHU CHARACTER-1B175;Lo;0;L;;;;;N;;;;; +1B176;NUSHU CHARACTER-1B176;Lo;0;L;;;;;N;;;;; +1B177;NUSHU CHARACTER-1B177;Lo;0;L;;;;;N;;;;; +1B178;NUSHU CHARACTER-1B178;Lo;0;L;;;;;N;;;;; +1B179;NUSHU CHARACTER-1B179;Lo;0;L;;;;;N;;;;; +1B17A;NUSHU CHARACTER-1B17A;Lo;0;L;;;;;N;;;;; +1B17B;NUSHU CHARACTER-1B17B;Lo;0;L;;;;;N;;;;; +1B17C;NUSHU CHARACTER-1B17C;Lo;0;L;;;;;N;;;;; +1B17D;NUSHU CHARACTER-1B17D;Lo;0;L;;;;;N;;;;; +1B17E;NUSHU CHARACTER-1B17E;Lo;0;L;;;;;N;;;;; +1B17F;NUSHU CHARACTER-1B17F;Lo;0;L;;;;;N;;;;; +1B180;NUSHU CHARACTER-1B180;Lo;0;L;;;;;N;;;;; +1B181;NUSHU CHARACTER-1B181;Lo;0;L;;;;;N;;;;; +1B182;NUSHU CHARACTER-1B182;Lo;0;L;;;;;N;;;;; +1B183;NUSHU CHARACTER-1B183;Lo;0;L;;;;;N;;;;; +1B184;NUSHU CHARACTER-1B184;Lo;0;L;;;;;N;;;;; +1B185;NUSHU CHARACTER-1B185;Lo;0;L;;;;;N;;;;; +1B186;NUSHU CHARACTER-1B186;Lo;0;L;;;;;N;;;;; +1B187;NUSHU CHARACTER-1B187;Lo;0;L;;;;;N;;;;; +1B188;NUSHU CHARACTER-1B188;Lo;0;L;;;;;N;;;;; +1B189;NUSHU CHARACTER-1B189;Lo;0;L;;;;;N;;;;; +1B18A;NUSHU CHARACTER-1B18A;Lo;0;L;;;;;N;;;;; +1B18B;NUSHU CHARACTER-1B18B;Lo;0;L;;;;;N;;;;; +1B18C;NUSHU CHARACTER-1B18C;Lo;0;L;;;;;N;;;;; +1B18D;NUSHU CHARACTER-1B18D;Lo;0;L;;;;;N;;;;; +1B18E;NUSHU CHARACTER-1B18E;Lo;0;L;;;;;N;;;;; +1B18F;NUSHU CHARACTER-1B18F;Lo;0;L;;;;;N;;;;; +1B190;NUSHU CHARACTER-1B190;Lo;0;L;;;;;N;;;;; +1B191;NUSHU CHARACTER-1B191;Lo;0;L;;;;;N;;;;; +1B192;NUSHU CHARACTER-1B192;Lo;0;L;;;;;N;;;;; +1B193;NUSHU CHARACTER-1B193;Lo;0;L;;;;;N;;;;; +1B194;NUSHU CHARACTER-1B194;Lo;0;L;;;;;N;;;;; +1B195;NUSHU CHARACTER-1B195;Lo;0;L;;;;;N;;;;; +1B196;NUSHU CHARACTER-1B196;Lo;0;L;;;;;N;;;;; +1B197;NUSHU CHARACTER-1B197;Lo;0;L;;;;;N;;;;; +1B198;NUSHU CHARACTER-1B198;Lo;0;L;;;;;N;;;;; +1B199;NUSHU CHARACTER-1B199;Lo;0;L;;;;;N;;;;; +1B19A;NUSHU CHARACTER-1B19A;Lo;0;L;;;;;N;;;;; +1B19B;NUSHU CHARACTER-1B19B;Lo;0;L;;;;;N;;;;; +1B19C;NUSHU CHARACTER-1B19C;Lo;0;L;;;;;N;;;;; +1B19D;NUSHU CHARACTER-1B19D;Lo;0;L;;;;;N;;;;; +1B19E;NUSHU CHARACTER-1B19E;Lo;0;L;;;;;N;;;;; +1B19F;NUSHU CHARACTER-1B19F;Lo;0;L;;;;;N;;;;; +1B1A0;NUSHU CHARACTER-1B1A0;Lo;0;L;;;;;N;;;;; +1B1A1;NUSHU CHARACTER-1B1A1;Lo;0;L;;;;;N;;;;; +1B1A2;NUSHU CHARACTER-1B1A2;Lo;0;L;;;;;N;;;;; +1B1A3;NUSHU CHARACTER-1B1A3;Lo;0;L;;;;;N;;;;; +1B1A4;NUSHU CHARACTER-1B1A4;Lo;0;L;;;;;N;;;;; +1B1A5;NUSHU CHARACTER-1B1A5;Lo;0;L;;;;;N;;;;; +1B1A6;NUSHU CHARACTER-1B1A6;Lo;0;L;;;;;N;;;;; +1B1A7;NUSHU CHARACTER-1B1A7;Lo;0;L;;;;;N;;;;; +1B1A8;NUSHU CHARACTER-1B1A8;Lo;0;L;;;;;N;;;;; +1B1A9;NUSHU CHARACTER-1B1A9;Lo;0;L;;;;;N;;;;; +1B1AA;NUSHU CHARACTER-1B1AA;Lo;0;L;;;;;N;;;;; +1B1AB;NUSHU CHARACTER-1B1AB;Lo;0;L;;;;;N;;;;; +1B1AC;NUSHU CHARACTER-1B1AC;Lo;0;L;;;;;N;;;;; +1B1AD;NUSHU CHARACTER-1B1AD;Lo;0;L;;;;;N;;;;; +1B1AE;NUSHU CHARACTER-1B1AE;Lo;0;L;;;;;N;;;;; +1B1AF;NUSHU CHARACTER-1B1AF;Lo;0;L;;;;;N;;;;; +1B1B0;NUSHU CHARACTER-1B1B0;Lo;0;L;;;;;N;;;;; +1B1B1;NUSHU CHARACTER-1B1B1;Lo;0;L;;;;;N;;;;; +1B1B2;NUSHU CHARACTER-1B1B2;Lo;0;L;;;;;N;;;;; +1B1B3;NUSHU CHARACTER-1B1B3;Lo;0;L;;;;;N;;;;; +1B1B4;NUSHU CHARACTER-1B1B4;Lo;0;L;;;;;N;;;;; +1B1B5;NUSHU CHARACTER-1B1B5;Lo;0;L;;;;;N;;;;; +1B1B6;NUSHU CHARACTER-1B1B6;Lo;0;L;;;;;N;;;;; +1B1B7;NUSHU CHARACTER-1B1B7;Lo;0;L;;;;;N;;;;; +1B1B8;NUSHU CHARACTER-1B1B8;Lo;0;L;;;;;N;;;;; +1B1B9;NUSHU CHARACTER-1B1B9;Lo;0;L;;;;;N;;;;; +1B1BA;NUSHU CHARACTER-1B1BA;Lo;0;L;;;;;N;;;;; +1B1BB;NUSHU CHARACTER-1B1BB;Lo;0;L;;;;;N;;;;; +1B1BC;NUSHU CHARACTER-1B1BC;Lo;0;L;;;;;N;;;;; +1B1BD;NUSHU CHARACTER-1B1BD;Lo;0;L;;;;;N;;;;; +1B1BE;NUSHU CHARACTER-1B1BE;Lo;0;L;;;;;N;;;;; +1B1BF;NUSHU CHARACTER-1B1BF;Lo;0;L;;;;;N;;;;; +1B1C0;NUSHU CHARACTER-1B1C0;Lo;0;L;;;;;N;;;;; +1B1C1;NUSHU CHARACTER-1B1C1;Lo;0;L;;;;;N;;;;; +1B1C2;NUSHU CHARACTER-1B1C2;Lo;0;L;;;;;N;;;;; +1B1C3;NUSHU CHARACTER-1B1C3;Lo;0;L;;;;;N;;;;; +1B1C4;NUSHU CHARACTER-1B1C4;Lo;0;L;;;;;N;;;;; +1B1C5;NUSHU CHARACTER-1B1C5;Lo;0;L;;;;;N;;;;; +1B1C6;NUSHU CHARACTER-1B1C6;Lo;0;L;;;;;N;;;;; +1B1C7;NUSHU CHARACTER-1B1C7;Lo;0;L;;;;;N;;;;; +1B1C8;NUSHU CHARACTER-1B1C8;Lo;0;L;;;;;N;;;;; +1B1C9;NUSHU CHARACTER-1B1C9;Lo;0;L;;;;;N;;;;; +1B1CA;NUSHU CHARACTER-1B1CA;Lo;0;L;;;;;N;;;;; +1B1CB;NUSHU CHARACTER-1B1CB;Lo;0;L;;;;;N;;;;; +1B1CC;NUSHU CHARACTER-1B1CC;Lo;0;L;;;;;N;;;;; +1B1CD;NUSHU CHARACTER-1B1CD;Lo;0;L;;;;;N;;;;; +1B1CE;NUSHU CHARACTER-1B1CE;Lo;0;L;;;;;N;;;;; +1B1CF;NUSHU CHARACTER-1B1CF;Lo;0;L;;;;;N;;;;; +1B1D0;NUSHU CHARACTER-1B1D0;Lo;0;L;;;;;N;;;;; +1B1D1;NUSHU CHARACTER-1B1D1;Lo;0;L;;;;;N;;;;; +1B1D2;NUSHU CHARACTER-1B1D2;Lo;0;L;;;;;N;;;;; +1B1D3;NUSHU CHARACTER-1B1D3;Lo;0;L;;;;;N;;;;; +1B1D4;NUSHU CHARACTER-1B1D4;Lo;0;L;;;;;N;;;;; +1B1D5;NUSHU CHARACTER-1B1D5;Lo;0;L;;;;;N;;;;; +1B1D6;NUSHU CHARACTER-1B1D6;Lo;0;L;;;;;N;;;;; +1B1D7;NUSHU CHARACTER-1B1D7;Lo;0;L;;;;;N;;;;; +1B1D8;NUSHU CHARACTER-1B1D8;Lo;0;L;;;;;N;;;;; +1B1D9;NUSHU CHARACTER-1B1D9;Lo;0;L;;;;;N;;;;; +1B1DA;NUSHU CHARACTER-1B1DA;Lo;0;L;;;;;N;;;;; +1B1DB;NUSHU CHARACTER-1B1DB;Lo;0;L;;;;;N;;;;; +1B1DC;NUSHU CHARACTER-1B1DC;Lo;0;L;;;;;N;;;;; +1B1DD;NUSHU CHARACTER-1B1DD;Lo;0;L;;;;;N;;;;; +1B1DE;NUSHU CHARACTER-1B1DE;Lo;0;L;;;;;N;;;;; +1B1DF;NUSHU CHARACTER-1B1DF;Lo;0;L;;;;;N;;;;; +1B1E0;NUSHU CHARACTER-1B1E0;Lo;0;L;;;;;N;;;;; +1B1E1;NUSHU CHARACTER-1B1E1;Lo;0;L;;;;;N;;;;; +1B1E2;NUSHU CHARACTER-1B1E2;Lo;0;L;;;;;N;;;;; +1B1E3;NUSHU CHARACTER-1B1E3;Lo;0;L;;;;;N;;;;; +1B1E4;NUSHU CHARACTER-1B1E4;Lo;0;L;;;;;N;;;;; +1B1E5;NUSHU CHARACTER-1B1E5;Lo;0;L;;;;;N;;;;; +1B1E6;NUSHU CHARACTER-1B1E6;Lo;0;L;;;;;N;;;;; +1B1E7;NUSHU CHARACTER-1B1E7;Lo;0;L;;;;;N;;;;; +1B1E8;NUSHU CHARACTER-1B1E8;Lo;0;L;;;;;N;;;;; +1B1E9;NUSHU CHARACTER-1B1E9;Lo;0;L;;;;;N;;;;; +1B1EA;NUSHU CHARACTER-1B1EA;Lo;0;L;;;;;N;;;;; +1B1EB;NUSHU CHARACTER-1B1EB;Lo;0;L;;;;;N;;;;; +1B1EC;NUSHU CHARACTER-1B1EC;Lo;0;L;;;;;N;;;;; +1B1ED;NUSHU CHARACTER-1B1ED;Lo;0;L;;;;;N;;;;; +1B1EE;NUSHU CHARACTER-1B1EE;Lo;0;L;;;;;N;;;;; +1B1EF;NUSHU CHARACTER-1B1EF;Lo;0;L;;;;;N;;;;; +1B1F0;NUSHU CHARACTER-1B1F0;Lo;0;L;;;;;N;;;;; +1B1F1;NUSHU CHARACTER-1B1F1;Lo;0;L;;;;;N;;;;; +1B1F2;NUSHU CHARACTER-1B1F2;Lo;0;L;;;;;N;;;;; +1B1F3;NUSHU CHARACTER-1B1F3;Lo;0;L;;;;;N;;;;; +1B1F4;NUSHU CHARACTER-1B1F4;Lo;0;L;;;;;N;;;;; +1B1F5;NUSHU CHARACTER-1B1F5;Lo;0;L;;;;;N;;;;; +1B1F6;NUSHU CHARACTER-1B1F6;Lo;0;L;;;;;N;;;;; +1B1F7;NUSHU CHARACTER-1B1F7;Lo;0;L;;;;;N;;;;; +1B1F8;NUSHU CHARACTER-1B1F8;Lo;0;L;;;;;N;;;;; +1B1F9;NUSHU CHARACTER-1B1F9;Lo;0;L;;;;;N;;;;; +1B1FA;NUSHU CHARACTER-1B1FA;Lo;0;L;;;;;N;;;;; +1B1FB;NUSHU CHARACTER-1B1FB;Lo;0;L;;;;;N;;;;; +1B1FC;NUSHU CHARACTER-1B1FC;Lo;0;L;;;;;N;;;;; +1B1FD;NUSHU CHARACTER-1B1FD;Lo;0;L;;;;;N;;;;; +1B1FE;NUSHU CHARACTER-1B1FE;Lo;0;L;;;;;N;;;;; +1B1FF;NUSHU CHARACTER-1B1FF;Lo;0;L;;;;;N;;;;; +1B200;NUSHU CHARACTER-1B200;Lo;0;L;;;;;N;;;;; +1B201;NUSHU CHARACTER-1B201;Lo;0;L;;;;;N;;;;; +1B202;NUSHU CHARACTER-1B202;Lo;0;L;;;;;N;;;;; +1B203;NUSHU CHARACTER-1B203;Lo;0;L;;;;;N;;;;; +1B204;NUSHU CHARACTER-1B204;Lo;0;L;;;;;N;;;;; +1B205;NUSHU CHARACTER-1B205;Lo;0;L;;;;;N;;;;; +1B206;NUSHU CHARACTER-1B206;Lo;0;L;;;;;N;;;;; +1B207;NUSHU CHARACTER-1B207;Lo;0;L;;;;;N;;;;; +1B208;NUSHU CHARACTER-1B208;Lo;0;L;;;;;N;;;;; +1B209;NUSHU CHARACTER-1B209;Lo;0;L;;;;;N;;;;; +1B20A;NUSHU CHARACTER-1B20A;Lo;0;L;;;;;N;;;;; +1B20B;NUSHU CHARACTER-1B20B;Lo;0;L;;;;;N;;;;; +1B20C;NUSHU CHARACTER-1B20C;Lo;0;L;;;;;N;;;;; +1B20D;NUSHU CHARACTER-1B20D;Lo;0;L;;;;;N;;;;; +1B20E;NUSHU CHARACTER-1B20E;Lo;0;L;;;;;N;;;;; +1B20F;NUSHU CHARACTER-1B20F;Lo;0;L;;;;;N;;;;; +1B210;NUSHU CHARACTER-1B210;Lo;0;L;;;;;N;;;;; +1B211;NUSHU CHARACTER-1B211;Lo;0;L;;;;;N;;;;; +1B212;NUSHU CHARACTER-1B212;Lo;0;L;;;;;N;;;;; +1B213;NUSHU CHARACTER-1B213;Lo;0;L;;;;;N;;;;; +1B214;NUSHU CHARACTER-1B214;Lo;0;L;;;;;N;;;;; +1B215;NUSHU CHARACTER-1B215;Lo;0;L;;;;;N;;;;; +1B216;NUSHU CHARACTER-1B216;Lo;0;L;;;;;N;;;;; +1B217;NUSHU CHARACTER-1B217;Lo;0;L;;;;;N;;;;; +1B218;NUSHU CHARACTER-1B218;Lo;0;L;;;;;N;;;;; +1B219;NUSHU CHARACTER-1B219;Lo;0;L;;;;;N;;;;; +1B21A;NUSHU CHARACTER-1B21A;Lo;0;L;;;;;N;;;;; +1B21B;NUSHU CHARACTER-1B21B;Lo;0;L;;;;;N;;;;; +1B21C;NUSHU CHARACTER-1B21C;Lo;0;L;;;;;N;;;;; +1B21D;NUSHU CHARACTER-1B21D;Lo;0;L;;;;;N;;;;; +1B21E;NUSHU CHARACTER-1B21E;Lo;0;L;;;;;N;;;;; +1B21F;NUSHU CHARACTER-1B21F;Lo;0;L;;;;;N;;;;; +1B220;NUSHU CHARACTER-1B220;Lo;0;L;;;;;N;;;;; +1B221;NUSHU CHARACTER-1B221;Lo;0;L;;;;;N;;;;; +1B222;NUSHU CHARACTER-1B222;Lo;0;L;;;;;N;;;;; +1B223;NUSHU CHARACTER-1B223;Lo;0;L;;;;;N;;;;; +1B224;NUSHU CHARACTER-1B224;Lo;0;L;;;;;N;;;;; +1B225;NUSHU CHARACTER-1B225;Lo;0;L;;;;;N;;;;; +1B226;NUSHU CHARACTER-1B226;Lo;0;L;;;;;N;;;;; +1B227;NUSHU CHARACTER-1B227;Lo;0;L;;;;;N;;;;; +1B228;NUSHU CHARACTER-1B228;Lo;0;L;;;;;N;;;;; +1B229;NUSHU CHARACTER-1B229;Lo;0;L;;;;;N;;;;; +1B22A;NUSHU CHARACTER-1B22A;Lo;0;L;;;;;N;;;;; +1B22B;NUSHU CHARACTER-1B22B;Lo;0;L;;;;;N;;;;; +1B22C;NUSHU CHARACTER-1B22C;Lo;0;L;;;;;N;;;;; +1B22D;NUSHU CHARACTER-1B22D;Lo;0;L;;;;;N;;;;; +1B22E;NUSHU CHARACTER-1B22E;Lo;0;L;;;;;N;;;;; +1B22F;NUSHU CHARACTER-1B22F;Lo;0;L;;;;;N;;;;; +1B230;NUSHU CHARACTER-1B230;Lo;0;L;;;;;N;;;;; +1B231;NUSHU CHARACTER-1B231;Lo;0;L;;;;;N;;;;; +1B232;NUSHU CHARACTER-1B232;Lo;0;L;;;;;N;;;;; +1B233;NUSHU CHARACTER-1B233;Lo;0;L;;;;;N;;;;; +1B234;NUSHU CHARACTER-1B234;Lo;0;L;;;;;N;;;;; +1B235;NUSHU CHARACTER-1B235;Lo;0;L;;;;;N;;;;; +1B236;NUSHU CHARACTER-1B236;Lo;0;L;;;;;N;;;;; +1B237;NUSHU CHARACTER-1B237;Lo;0;L;;;;;N;;;;; +1B238;NUSHU CHARACTER-1B238;Lo;0;L;;;;;N;;;;; +1B239;NUSHU CHARACTER-1B239;Lo;0;L;;;;;N;;;;; +1B23A;NUSHU CHARACTER-1B23A;Lo;0;L;;;;;N;;;;; +1B23B;NUSHU CHARACTER-1B23B;Lo;0;L;;;;;N;;;;; +1B23C;NUSHU CHARACTER-1B23C;Lo;0;L;;;;;N;;;;; +1B23D;NUSHU CHARACTER-1B23D;Lo;0;L;;;;;N;;;;; +1B23E;NUSHU CHARACTER-1B23E;Lo;0;L;;;;;N;;;;; +1B23F;NUSHU CHARACTER-1B23F;Lo;0;L;;;;;N;;;;; +1B240;NUSHU CHARACTER-1B240;Lo;0;L;;;;;N;;;;; +1B241;NUSHU CHARACTER-1B241;Lo;0;L;;;;;N;;;;; +1B242;NUSHU CHARACTER-1B242;Lo;0;L;;;;;N;;;;; +1B243;NUSHU CHARACTER-1B243;Lo;0;L;;;;;N;;;;; +1B244;NUSHU CHARACTER-1B244;Lo;0;L;;;;;N;;;;; +1B245;NUSHU CHARACTER-1B245;Lo;0;L;;;;;N;;;;; +1B246;NUSHU CHARACTER-1B246;Lo;0;L;;;;;N;;;;; +1B247;NUSHU CHARACTER-1B247;Lo;0;L;;;;;N;;;;; +1B248;NUSHU CHARACTER-1B248;Lo;0;L;;;;;N;;;;; +1B249;NUSHU CHARACTER-1B249;Lo;0;L;;;;;N;;;;; +1B24A;NUSHU CHARACTER-1B24A;Lo;0;L;;;;;N;;;;; +1B24B;NUSHU CHARACTER-1B24B;Lo;0;L;;;;;N;;;;; +1B24C;NUSHU CHARACTER-1B24C;Lo;0;L;;;;;N;;;;; +1B24D;NUSHU CHARACTER-1B24D;Lo;0;L;;;;;N;;;;; +1B24E;NUSHU CHARACTER-1B24E;Lo;0;L;;;;;N;;;;; +1B24F;NUSHU CHARACTER-1B24F;Lo;0;L;;;;;N;;;;; +1B250;NUSHU CHARACTER-1B250;Lo;0;L;;;;;N;;;;; +1B251;NUSHU CHARACTER-1B251;Lo;0;L;;;;;N;;;;; +1B252;NUSHU CHARACTER-1B252;Lo;0;L;;;;;N;;;;; +1B253;NUSHU CHARACTER-1B253;Lo;0;L;;;;;N;;;;; +1B254;NUSHU CHARACTER-1B254;Lo;0;L;;;;;N;;;;; +1B255;NUSHU CHARACTER-1B255;Lo;0;L;;;;;N;;;;; +1B256;NUSHU CHARACTER-1B256;Lo;0;L;;;;;N;;;;; +1B257;NUSHU CHARACTER-1B257;Lo;0;L;;;;;N;;;;; +1B258;NUSHU CHARACTER-1B258;Lo;0;L;;;;;N;;;;; +1B259;NUSHU CHARACTER-1B259;Lo;0;L;;;;;N;;;;; +1B25A;NUSHU CHARACTER-1B25A;Lo;0;L;;;;;N;;;;; +1B25B;NUSHU CHARACTER-1B25B;Lo;0;L;;;;;N;;;;; +1B25C;NUSHU CHARACTER-1B25C;Lo;0;L;;;;;N;;;;; +1B25D;NUSHU CHARACTER-1B25D;Lo;0;L;;;;;N;;;;; +1B25E;NUSHU CHARACTER-1B25E;Lo;0;L;;;;;N;;;;; +1B25F;NUSHU CHARACTER-1B25F;Lo;0;L;;;;;N;;;;; +1B260;NUSHU CHARACTER-1B260;Lo;0;L;;;;;N;;;;; +1B261;NUSHU CHARACTER-1B261;Lo;0;L;;;;;N;;;;; +1B262;NUSHU CHARACTER-1B262;Lo;0;L;;;;;N;;;;; +1B263;NUSHU CHARACTER-1B263;Lo;0;L;;;;;N;;;;; +1B264;NUSHU CHARACTER-1B264;Lo;0;L;;;;;N;;;;; +1B265;NUSHU CHARACTER-1B265;Lo;0;L;;;;;N;;;;; +1B266;NUSHU CHARACTER-1B266;Lo;0;L;;;;;N;;;;; +1B267;NUSHU CHARACTER-1B267;Lo;0;L;;;;;N;;;;; +1B268;NUSHU CHARACTER-1B268;Lo;0;L;;;;;N;;;;; +1B269;NUSHU CHARACTER-1B269;Lo;0;L;;;;;N;;;;; +1B26A;NUSHU CHARACTER-1B26A;Lo;0;L;;;;;N;;;;; +1B26B;NUSHU CHARACTER-1B26B;Lo;0;L;;;;;N;;;;; +1B26C;NUSHU CHARACTER-1B26C;Lo;0;L;;;;;N;;;;; +1B26D;NUSHU CHARACTER-1B26D;Lo;0;L;;;;;N;;;;; +1B26E;NUSHU CHARACTER-1B26E;Lo;0;L;;;;;N;;;;; +1B26F;NUSHU CHARACTER-1B26F;Lo;0;L;;;;;N;;;;; +1B270;NUSHU CHARACTER-1B270;Lo;0;L;;;;;N;;;;; +1B271;NUSHU CHARACTER-1B271;Lo;0;L;;;;;N;;;;; +1B272;NUSHU CHARACTER-1B272;Lo;0;L;;;;;N;;;;; +1B273;NUSHU CHARACTER-1B273;Lo;0;L;;;;;N;;;;; +1B274;NUSHU CHARACTER-1B274;Lo;0;L;;;;;N;;;;; +1B275;NUSHU CHARACTER-1B275;Lo;0;L;;;;;N;;;;; +1B276;NUSHU CHARACTER-1B276;Lo;0;L;;;;;N;;;;; +1B277;NUSHU CHARACTER-1B277;Lo;0;L;;;;;N;;;;; +1B278;NUSHU CHARACTER-1B278;Lo;0;L;;;;;N;;;;; +1B279;NUSHU CHARACTER-1B279;Lo;0;L;;;;;N;;;;; +1B27A;NUSHU CHARACTER-1B27A;Lo;0;L;;;;;N;;;;; +1B27B;NUSHU CHARACTER-1B27B;Lo;0;L;;;;;N;;;;; +1B27C;NUSHU CHARACTER-1B27C;Lo;0;L;;;;;N;;;;; +1B27D;NUSHU CHARACTER-1B27D;Lo;0;L;;;;;N;;;;; +1B27E;NUSHU CHARACTER-1B27E;Lo;0;L;;;;;N;;;;; +1B27F;NUSHU CHARACTER-1B27F;Lo;0;L;;;;;N;;;;; +1B280;NUSHU CHARACTER-1B280;Lo;0;L;;;;;N;;;;; +1B281;NUSHU CHARACTER-1B281;Lo;0;L;;;;;N;;;;; +1B282;NUSHU CHARACTER-1B282;Lo;0;L;;;;;N;;;;; +1B283;NUSHU CHARACTER-1B283;Lo;0;L;;;;;N;;;;; +1B284;NUSHU CHARACTER-1B284;Lo;0;L;;;;;N;;;;; +1B285;NUSHU CHARACTER-1B285;Lo;0;L;;;;;N;;;;; +1B286;NUSHU CHARACTER-1B286;Lo;0;L;;;;;N;;;;; +1B287;NUSHU CHARACTER-1B287;Lo;0;L;;;;;N;;;;; +1B288;NUSHU CHARACTER-1B288;Lo;0;L;;;;;N;;;;; +1B289;NUSHU CHARACTER-1B289;Lo;0;L;;;;;N;;;;; +1B28A;NUSHU CHARACTER-1B28A;Lo;0;L;;;;;N;;;;; +1B28B;NUSHU CHARACTER-1B28B;Lo;0;L;;;;;N;;;;; +1B28C;NUSHU CHARACTER-1B28C;Lo;0;L;;;;;N;;;;; +1B28D;NUSHU CHARACTER-1B28D;Lo;0;L;;;;;N;;;;; +1B28E;NUSHU CHARACTER-1B28E;Lo;0;L;;;;;N;;;;; +1B28F;NUSHU CHARACTER-1B28F;Lo;0;L;;;;;N;;;;; +1B290;NUSHU CHARACTER-1B290;Lo;0;L;;;;;N;;;;; +1B291;NUSHU CHARACTER-1B291;Lo;0;L;;;;;N;;;;; +1B292;NUSHU CHARACTER-1B292;Lo;0;L;;;;;N;;;;; +1B293;NUSHU CHARACTER-1B293;Lo;0;L;;;;;N;;;;; +1B294;NUSHU CHARACTER-1B294;Lo;0;L;;;;;N;;;;; +1B295;NUSHU CHARACTER-1B295;Lo;0;L;;;;;N;;;;; +1B296;NUSHU CHARACTER-1B296;Lo;0;L;;;;;N;;;;; +1B297;NUSHU CHARACTER-1B297;Lo;0;L;;;;;N;;;;; +1B298;NUSHU CHARACTER-1B298;Lo;0;L;;;;;N;;;;; +1B299;NUSHU CHARACTER-1B299;Lo;0;L;;;;;N;;;;; +1B29A;NUSHU CHARACTER-1B29A;Lo;0;L;;;;;N;;;;; +1B29B;NUSHU CHARACTER-1B29B;Lo;0;L;;;;;N;;;;; +1B29C;NUSHU CHARACTER-1B29C;Lo;0;L;;;;;N;;;;; +1B29D;NUSHU CHARACTER-1B29D;Lo;0;L;;;;;N;;;;; +1B29E;NUSHU CHARACTER-1B29E;Lo;0;L;;;;;N;;;;; +1B29F;NUSHU CHARACTER-1B29F;Lo;0;L;;;;;N;;;;; +1B2A0;NUSHU CHARACTER-1B2A0;Lo;0;L;;;;;N;;;;; +1B2A1;NUSHU CHARACTER-1B2A1;Lo;0;L;;;;;N;;;;; +1B2A2;NUSHU CHARACTER-1B2A2;Lo;0;L;;;;;N;;;;; +1B2A3;NUSHU CHARACTER-1B2A3;Lo;0;L;;;;;N;;;;; +1B2A4;NUSHU CHARACTER-1B2A4;Lo;0;L;;;;;N;;;;; +1B2A5;NUSHU CHARACTER-1B2A5;Lo;0;L;;;;;N;;;;; +1B2A6;NUSHU CHARACTER-1B2A6;Lo;0;L;;;;;N;;;;; +1B2A7;NUSHU CHARACTER-1B2A7;Lo;0;L;;;;;N;;;;; +1B2A8;NUSHU CHARACTER-1B2A8;Lo;0;L;;;;;N;;;;; +1B2A9;NUSHU CHARACTER-1B2A9;Lo;0;L;;;;;N;;;;; +1B2AA;NUSHU CHARACTER-1B2AA;Lo;0;L;;;;;N;;;;; +1B2AB;NUSHU CHARACTER-1B2AB;Lo;0;L;;;;;N;;;;; +1B2AC;NUSHU CHARACTER-1B2AC;Lo;0;L;;;;;N;;;;; +1B2AD;NUSHU CHARACTER-1B2AD;Lo;0;L;;;;;N;;;;; +1B2AE;NUSHU CHARACTER-1B2AE;Lo;0;L;;;;;N;;;;; +1B2AF;NUSHU CHARACTER-1B2AF;Lo;0;L;;;;;N;;;;; +1B2B0;NUSHU CHARACTER-1B2B0;Lo;0;L;;;;;N;;;;; +1B2B1;NUSHU CHARACTER-1B2B1;Lo;0;L;;;;;N;;;;; +1B2B2;NUSHU CHARACTER-1B2B2;Lo;0;L;;;;;N;;;;; +1B2B3;NUSHU CHARACTER-1B2B3;Lo;0;L;;;;;N;;;;; +1B2B4;NUSHU CHARACTER-1B2B4;Lo;0;L;;;;;N;;;;; +1B2B5;NUSHU CHARACTER-1B2B5;Lo;0;L;;;;;N;;;;; +1B2B6;NUSHU CHARACTER-1B2B6;Lo;0;L;;;;;N;;;;; +1B2B7;NUSHU CHARACTER-1B2B7;Lo;0;L;;;;;N;;;;; +1B2B8;NUSHU CHARACTER-1B2B8;Lo;0;L;;;;;N;;;;; +1B2B9;NUSHU CHARACTER-1B2B9;Lo;0;L;;;;;N;;;;; +1B2BA;NUSHU CHARACTER-1B2BA;Lo;0;L;;;;;N;;;;; +1B2BB;NUSHU CHARACTER-1B2BB;Lo;0;L;;;;;N;;;;; +1B2BC;NUSHU CHARACTER-1B2BC;Lo;0;L;;;;;N;;;;; +1B2BD;NUSHU CHARACTER-1B2BD;Lo;0;L;;;;;N;;;;; +1B2BE;NUSHU CHARACTER-1B2BE;Lo;0;L;;;;;N;;;;; +1B2BF;NUSHU CHARACTER-1B2BF;Lo;0;L;;;;;N;;;;; +1B2C0;NUSHU CHARACTER-1B2C0;Lo;0;L;;;;;N;;;;; +1B2C1;NUSHU CHARACTER-1B2C1;Lo;0;L;;;;;N;;;;; +1B2C2;NUSHU CHARACTER-1B2C2;Lo;0;L;;;;;N;;;;; +1B2C3;NUSHU CHARACTER-1B2C3;Lo;0;L;;;;;N;;;;; +1B2C4;NUSHU CHARACTER-1B2C4;Lo;0;L;;;;;N;;;;; +1B2C5;NUSHU CHARACTER-1B2C5;Lo;0;L;;;;;N;;;;; +1B2C6;NUSHU CHARACTER-1B2C6;Lo;0;L;;;;;N;;;;; +1B2C7;NUSHU CHARACTER-1B2C7;Lo;0;L;;;;;N;;;;; +1B2C8;NUSHU CHARACTER-1B2C8;Lo;0;L;;;;;N;;;;; +1B2C9;NUSHU CHARACTER-1B2C9;Lo;0;L;;;;;N;;;;; +1B2CA;NUSHU CHARACTER-1B2CA;Lo;0;L;;;;;N;;;;; +1B2CB;NUSHU CHARACTER-1B2CB;Lo;0;L;;;;;N;;;;; +1B2CC;NUSHU CHARACTER-1B2CC;Lo;0;L;;;;;N;;;;; +1B2CD;NUSHU CHARACTER-1B2CD;Lo;0;L;;;;;N;;;;; +1B2CE;NUSHU CHARACTER-1B2CE;Lo;0;L;;;;;N;;;;; +1B2CF;NUSHU CHARACTER-1B2CF;Lo;0;L;;;;;N;;;;; +1B2D0;NUSHU CHARACTER-1B2D0;Lo;0;L;;;;;N;;;;; +1B2D1;NUSHU CHARACTER-1B2D1;Lo;0;L;;;;;N;;;;; +1B2D2;NUSHU CHARACTER-1B2D2;Lo;0;L;;;;;N;;;;; +1B2D3;NUSHU CHARACTER-1B2D3;Lo;0;L;;;;;N;;;;; +1B2D4;NUSHU CHARACTER-1B2D4;Lo;0;L;;;;;N;;;;; +1B2D5;NUSHU CHARACTER-1B2D5;Lo;0;L;;;;;N;;;;; +1B2D6;NUSHU CHARACTER-1B2D6;Lo;0;L;;;;;N;;;;; +1B2D7;NUSHU CHARACTER-1B2D7;Lo;0;L;;;;;N;;;;; +1B2D8;NUSHU CHARACTER-1B2D8;Lo;0;L;;;;;N;;;;; +1B2D9;NUSHU CHARACTER-1B2D9;Lo;0;L;;;;;N;;;;; +1B2DA;NUSHU CHARACTER-1B2DA;Lo;0;L;;;;;N;;;;; +1B2DB;NUSHU CHARACTER-1B2DB;Lo;0;L;;;;;N;;;;; +1B2DC;NUSHU CHARACTER-1B2DC;Lo;0;L;;;;;N;;;;; +1B2DD;NUSHU CHARACTER-1B2DD;Lo;0;L;;;;;N;;;;; +1B2DE;NUSHU CHARACTER-1B2DE;Lo;0;L;;;;;N;;;;; +1B2DF;NUSHU CHARACTER-1B2DF;Lo;0;L;;;;;N;;;;; +1B2E0;NUSHU CHARACTER-1B2E0;Lo;0;L;;;;;N;;;;; +1B2E1;NUSHU CHARACTER-1B2E1;Lo;0;L;;;;;N;;;;; +1B2E2;NUSHU CHARACTER-1B2E2;Lo;0;L;;;;;N;;;;; +1B2E3;NUSHU CHARACTER-1B2E3;Lo;0;L;;;;;N;;;;; +1B2E4;NUSHU CHARACTER-1B2E4;Lo;0;L;;;;;N;;;;; +1B2E5;NUSHU CHARACTER-1B2E5;Lo;0;L;;;;;N;;;;; +1B2E6;NUSHU CHARACTER-1B2E6;Lo;0;L;;;;;N;;;;; +1B2E7;NUSHU CHARACTER-1B2E7;Lo;0;L;;;;;N;;;;; +1B2E8;NUSHU CHARACTER-1B2E8;Lo;0;L;;;;;N;;;;; +1B2E9;NUSHU CHARACTER-1B2E9;Lo;0;L;;;;;N;;;;; +1B2EA;NUSHU CHARACTER-1B2EA;Lo;0;L;;;;;N;;;;; +1B2EB;NUSHU CHARACTER-1B2EB;Lo;0;L;;;;;N;;;;; +1B2EC;NUSHU CHARACTER-1B2EC;Lo;0;L;;;;;N;;;;; +1B2ED;NUSHU CHARACTER-1B2ED;Lo;0;L;;;;;N;;;;; +1B2EE;NUSHU CHARACTER-1B2EE;Lo;0;L;;;;;N;;;;; +1B2EF;NUSHU CHARACTER-1B2EF;Lo;0;L;;;;;N;;;;; +1B2F0;NUSHU CHARACTER-1B2F0;Lo;0;L;;;;;N;;;;; +1B2F1;NUSHU CHARACTER-1B2F1;Lo;0;L;;;;;N;;;;; +1B2F2;NUSHU CHARACTER-1B2F2;Lo;0;L;;;;;N;;;;; +1B2F3;NUSHU CHARACTER-1B2F3;Lo;0;L;;;;;N;;;;; +1B2F4;NUSHU CHARACTER-1B2F4;Lo;0;L;;;;;N;;;;; +1B2F5;NUSHU CHARACTER-1B2F5;Lo;0;L;;;;;N;;;;; +1B2F6;NUSHU CHARACTER-1B2F6;Lo;0;L;;;;;N;;;;; +1B2F7;NUSHU CHARACTER-1B2F7;Lo;0;L;;;;;N;;;;; +1B2F8;NUSHU CHARACTER-1B2F8;Lo;0;L;;;;;N;;;;; +1B2F9;NUSHU CHARACTER-1B2F9;Lo;0;L;;;;;N;;;;; +1B2FA;NUSHU CHARACTER-1B2FA;Lo;0;L;;;;;N;;;;; +1B2FB;NUSHU CHARACTER-1B2FB;Lo;0;L;;;;;N;;;;; 1BC00;DUPLOYAN LETTER H;Lo;0;L;;;;;N;;;;; 1BC01;DUPLOYAN LETTER X;Lo;0;L;;;;;N;;;;; 1BC02;DUPLOYAN LETTER P;Lo;0;L;;;;;N;;;;; @@ -25540,6 +27871,26 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1D243;COMBINING GREEK MUSICAL TETRASEME;Mn;230;NSM;;;;;N;;;;; 1D244;COMBINING GREEK MUSICAL PENTASEME;Mn;230;NSM;;;;;N;;;;; 1D245;GREEK MUSICAL LEIMMA;So;0;ON;;;;;N;;;;; +1D2E0;MAYAN NUMERAL ZERO;No;0;L;;;;0;N;;;;; +1D2E1;MAYAN NUMERAL ONE;No;0;L;;;;1;N;;;;; +1D2E2;MAYAN NUMERAL TWO;No;0;L;;;;2;N;;;;; +1D2E3;MAYAN NUMERAL THREE;No;0;L;;;;3;N;;;;; +1D2E4;MAYAN NUMERAL FOUR;No;0;L;;;;4;N;;;;; +1D2E5;MAYAN NUMERAL FIVE;No;0;L;;;;5;N;;;;; +1D2E6;MAYAN NUMERAL SIX;No;0;L;;;;6;N;;;;; +1D2E7;MAYAN NUMERAL SEVEN;No;0;L;;;;7;N;;;;; +1D2E8;MAYAN NUMERAL EIGHT;No;0;L;;;;8;N;;;;; +1D2E9;MAYAN NUMERAL NINE;No;0;L;;;;9;N;;;;; +1D2EA;MAYAN NUMERAL TEN;No;0;L;;;;10;N;;;;; +1D2EB;MAYAN NUMERAL ELEVEN;No;0;L;;;;11;N;;;;; +1D2EC;MAYAN NUMERAL TWELVE;No;0;L;;;;12;N;;;;; +1D2ED;MAYAN NUMERAL THIRTEEN;No;0;L;;;;13;N;;;;; +1D2EE;MAYAN NUMERAL FOURTEEN;No;0;L;;;;14;N;;;;; +1D2EF;MAYAN NUMERAL FIFTEEN;No;0;L;;;;15;N;;;;; +1D2F0;MAYAN NUMERAL SIXTEEN;No;0;L;;;;16;N;;;;; +1D2F1;MAYAN NUMERAL SEVENTEEN;No;0;L;;;;17;N;;;;; +1D2F2;MAYAN NUMERAL EIGHTEEN;No;0;L;;;;18;N;;;;; +1D2F3;MAYAN NUMERAL NINETEEN;No;0;L;;;;19;N;;;;; 1D300;MONOGRAM FOR EARTH;So;0;ON;;;;;N;;;;; 1D301;DIGRAM FOR HEAVENLY EARTH;So;0;ON;;;;;N;;;;; 1D302;DIGRAM FOR HUMAN EARTH;So;0;ON;;;;;N;;;;; @@ -25645,6 +27996,13 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1D36F;COUNTING ROD TENS DIGIT SEVEN;No;0;L;;;;70;N;;;;; 1D370;COUNTING ROD TENS DIGIT EIGHT;No;0;L;;;;80;N;;;;; 1D371;COUNTING ROD TENS DIGIT NINE;No;0;L;;;;90;N;;;;; +1D372;IDEOGRAPHIC TALLY MARK ONE;No;0;L;;;;1;N;;;;; +1D373;IDEOGRAPHIC TALLY MARK TWO;No;0;L;;;;2;N;;;;; +1D374;IDEOGRAPHIC TALLY MARK THREE;No;0;L;;;;3;N;;;;; +1D375;IDEOGRAPHIC TALLY MARK FOUR;No;0;L;;;;4;N;;;;; +1D376;IDEOGRAPHIC TALLY MARK FIVE;No;0;L;;;;5;N;;;;; +1D377;TALLY MARK ONE;No;0;L;;;;1;N;;;;; +1D378;TALLY MARK FIVE;No;0;L;;;;5;N;;;;; 1D400;MATHEMATICAL BOLD CAPITAL A;Lu;0;L; 0041;;;;N;;;;; 1D401;MATHEMATICAL BOLD CAPITAL B;Lu;0;L; 0042;;;;N;;;;; 1D402;MATHEMATICAL BOLD CAPITAL C;Lu;0;L; 0043;;;;N;;;;; @@ -27351,6 +29709,136 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1E028;COMBINING GLAGOLITIC LETTER BIG YUS;Mn;230;NSM;;;;;N;;;;; 1E029;COMBINING GLAGOLITIC LETTER IOTATED BIG YUS;Mn;230;NSM;;;;;N;;;;; 1E02A;COMBINING GLAGOLITIC LETTER FITA;Mn;230;NSM;;;;;N;;;;; +1E100;NYIAKENG PUACHUE HMONG LETTER MA;Lo;0;L;;;;;N;;;;; +1E101;NYIAKENG PUACHUE HMONG LETTER TSA;Lo;0;L;;;;;N;;;;; +1E102;NYIAKENG PUACHUE HMONG LETTER NTA;Lo;0;L;;;;;N;;;;; +1E103;NYIAKENG PUACHUE HMONG LETTER TA;Lo;0;L;;;;;N;;;;; +1E104;NYIAKENG PUACHUE HMONG LETTER HA;Lo;0;L;;;;;N;;;;; +1E105;NYIAKENG PUACHUE HMONG LETTER NA;Lo;0;L;;;;;N;;;;; +1E106;NYIAKENG PUACHUE HMONG LETTER XA;Lo;0;L;;;;;N;;;;; +1E107;NYIAKENG PUACHUE HMONG LETTER NKA;Lo;0;L;;;;;N;;;;; +1E108;NYIAKENG PUACHUE HMONG LETTER CA;Lo;0;L;;;;;N;;;;; +1E109;NYIAKENG PUACHUE HMONG LETTER LA;Lo;0;L;;;;;N;;;;; +1E10A;NYIAKENG PUACHUE HMONG LETTER SA;Lo;0;L;;;;;N;;;;; +1E10B;NYIAKENG PUACHUE HMONG LETTER ZA;Lo;0;L;;;;;N;;;;; +1E10C;NYIAKENG PUACHUE HMONG LETTER NCA;Lo;0;L;;;;;N;;;;; +1E10D;NYIAKENG PUACHUE HMONG LETTER NTSA;Lo;0;L;;;;;N;;;;; +1E10E;NYIAKENG PUACHUE HMONG LETTER KA;Lo;0;L;;;;;N;;;;; +1E10F;NYIAKENG PUACHUE HMONG LETTER DA;Lo;0;L;;;;;N;;;;; +1E110;NYIAKENG PUACHUE HMONG LETTER NYA;Lo;0;L;;;;;N;;;;; +1E111;NYIAKENG PUACHUE HMONG LETTER NRA;Lo;0;L;;;;;N;;;;; +1E112;NYIAKENG PUACHUE HMONG LETTER VA;Lo;0;L;;;;;N;;;;; +1E113;NYIAKENG PUACHUE HMONG LETTER NTXA;Lo;0;L;;;;;N;;;;; +1E114;NYIAKENG PUACHUE HMONG LETTER TXA;Lo;0;L;;;;;N;;;;; +1E115;NYIAKENG PUACHUE HMONG LETTER FA;Lo;0;L;;;;;N;;;;; +1E116;NYIAKENG PUACHUE HMONG LETTER RA;Lo;0;L;;;;;N;;;;; +1E117;NYIAKENG PUACHUE HMONG LETTER QA;Lo;0;L;;;;;N;;;;; +1E118;NYIAKENG PUACHUE HMONG LETTER YA;Lo;0;L;;;;;N;;;;; +1E119;NYIAKENG PUACHUE HMONG LETTER NQA;Lo;0;L;;;;;N;;;;; +1E11A;NYIAKENG PUACHUE HMONG LETTER PA;Lo;0;L;;;;;N;;;;; +1E11B;NYIAKENG PUACHUE HMONG LETTER XYA;Lo;0;L;;;;;N;;;;; +1E11C;NYIAKENG PUACHUE HMONG LETTER NPA;Lo;0;L;;;;;N;;;;; +1E11D;NYIAKENG PUACHUE HMONG LETTER DLA;Lo;0;L;;;;;N;;;;; +1E11E;NYIAKENG PUACHUE HMONG LETTER NPLA;Lo;0;L;;;;;N;;;;; +1E11F;NYIAKENG PUACHUE HMONG LETTER HAH;Lo;0;L;;;;;N;;;;; +1E120;NYIAKENG PUACHUE HMONG LETTER MLA;Lo;0;L;;;;;N;;;;; +1E121;NYIAKENG PUACHUE HMONG LETTER PLA;Lo;0;L;;;;;N;;;;; +1E122;NYIAKENG PUACHUE HMONG LETTER GA;Lo;0;L;;;;;N;;;;; +1E123;NYIAKENG PUACHUE HMONG LETTER RRA;Lo;0;L;;;;;N;;;;; +1E124;NYIAKENG PUACHUE HMONG LETTER A;Lo;0;L;;;;;N;;;;; +1E125;NYIAKENG PUACHUE HMONG LETTER AA;Lo;0;L;;;;;N;;;;; +1E126;NYIAKENG PUACHUE HMONG LETTER I;Lo;0;L;;;;;N;;;;; +1E127;NYIAKENG PUACHUE HMONG LETTER U;Lo;0;L;;;;;N;;;;; +1E128;NYIAKENG PUACHUE HMONG LETTER O;Lo;0;L;;;;;N;;;;; +1E129;NYIAKENG PUACHUE HMONG LETTER OO;Lo;0;L;;;;;N;;;;; +1E12A;NYIAKENG PUACHUE HMONG LETTER E;Lo;0;L;;;;;N;;;;; +1E12B;NYIAKENG PUACHUE HMONG LETTER EE;Lo;0;L;;;;;N;;;;; +1E12C;NYIAKENG PUACHUE HMONG LETTER W;Lo;0;L;;;;;N;;;;; +1E130;NYIAKENG PUACHUE HMONG TONE-B;Mn;230;NSM;;;;;N;;;;; +1E131;NYIAKENG PUACHUE HMONG TONE-M;Mn;230;NSM;;;;;N;;;;; +1E132;NYIAKENG PUACHUE HMONG TONE-J;Mn;230;NSM;;;;;N;;;;; +1E133;NYIAKENG PUACHUE HMONG TONE-V;Mn;230;NSM;;;;;N;;;;; +1E134;NYIAKENG PUACHUE HMONG TONE-S;Mn;230;NSM;;;;;N;;;;; +1E135;NYIAKENG PUACHUE HMONG TONE-G;Mn;230;NSM;;;;;N;;;;; +1E136;NYIAKENG PUACHUE HMONG TONE-D;Mn;230;NSM;;;;;N;;;;; +1E137;NYIAKENG PUACHUE HMONG SIGN FOR PERSON;Lm;0;L;;;;;N;;;;; +1E138;NYIAKENG PUACHUE HMONG SIGN FOR THING;Lm;0;L;;;;;N;;;;; +1E139;NYIAKENG PUACHUE HMONG SIGN FOR LOCATION;Lm;0;L;;;;;N;;;;; +1E13A;NYIAKENG PUACHUE HMONG SIGN FOR ANIMAL;Lm;0;L;;;;;N;;;;; +1E13B;NYIAKENG PUACHUE HMONG SIGN FOR INVERTEBRATE;Lm;0;L;;;;;N;;;;; +1E13C;NYIAKENG PUACHUE HMONG SIGN XW XW;Lm;0;L;;;;;N;;;;; +1E13D;NYIAKENG PUACHUE HMONG SYLLABLE LENGTHENER;Lm;0;L;;;;;N;;;;; +1E140;NYIAKENG PUACHUE HMONG DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +1E141;NYIAKENG PUACHUE HMONG DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +1E142;NYIAKENG PUACHUE HMONG DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +1E143;NYIAKENG PUACHUE HMONG DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +1E144;NYIAKENG PUACHUE HMONG DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +1E145;NYIAKENG PUACHUE HMONG DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +1E146;NYIAKENG PUACHUE HMONG DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +1E147;NYIAKENG PUACHUE HMONG DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +1E148;NYIAKENG PUACHUE HMONG DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +1E149;NYIAKENG PUACHUE HMONG DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +1E14E;NYIAKENG PUACHUE HMONG LOGOGRAM NYAJ;Lo;0;L;;;;;N;;;;; +1E14F;NYIAKENG PUACHUE HMONG CIRCLED CA;So;0;L;;;;;N;;;;; +1E2C0;WANCHO LETTER AA;Lo;0;L;;;;;N;;;;; +1E2C1;WANCHO LETTER A;Lo;0;L;;;;;N;;;;; +1E2C2;WANCHO LETTER BA;Lo;0;L;;;;;N;;;;; +1E2C3;WANCHO LETTER CA;Lo;0;L;;;;;N;;;;; +1E2C4;WANCHO LETTER DA;Lo;0;L;;;;;N;;;;; +1E2C5;WANCHO LETTER GA;Lo;0;L;;;;;N;;;;; +1E2C6;WANCHO LETTER YA;Lo;0;L;;;;;N;;;;; +1E2C7;WANCHO LETTER PHA;Lo;0;L;;;;;N;;;;; +1E2C8;WANCHO LETTER LA;Lo;0;L;;;;;N;;;;; +1E2C9;WANCHO LETTER NA;Lo;0;L;;;;;N;;;;; +1E2CA;WANCHO LETTER PA;Lo;0;L;;;;;N;;;;; +1E2CB;WANCHO LETTER TA;Lo;0;L;;;;;N;;;;; +1E2CC;WANCHO LETTER THA;Lo;0;L;;;;;N;;;;; +1E2CD;WANCHO LETTER FA;Lo;0;L;;;;;N;;;;; +1E2CE;WANCHO LETTER SA;Lo;0;L;;;;;N;;;;; +1E2CF;WANCHO LETTER SHA;Lo;0;L;;;;;N;;;;; +1E2D0;WANCHO LETTER JA;Lo;0;L;;;;;N;;;;; +1E2D1;WANCHO LETTER ZA;Lo;0;L;;;;;N;;;;; +1E2D2;WANCHO LETTER WA;Lo;0;L;;;;;N;;;;; +1E2D3;WANCHO LETTER VA;Lo;0;L;;;;;N;;;;; +1E2D4;WANCHO LETTER KA;Lo;0;L;;;;;N;;;;; +1E2D5;WANCHO LETTER O;Lo;0;L;;;;;N;;;;; +1E2D6;WANCHO LETTER AU;Lo;0;L;;;;;N;;;;; +1E2D7;WANCHO LETTER RA;Lo;0;L;;;;;N;;;;; +1E2D8;WANCHO LETTER MA;Lo;0;L;;;;;N;;;;; +1E2D9;WANCHO LETTER KHA;Lo;0;L;;;;;N;;;;; +1E2DA;WANCHO LETTER HA;Lo;0;L;;;;;N;;;;; +1E2DB;WANCHO LETTER E;Lo;0;L;;;;;N;;;;; +1E2DC;WANCHO LETTER I;Lo;0;L;;;;;N;;;;; +1E2DD;WANCHO LETTER NGA;Lo;0;L;;;;;N;;;;; +1E2DE;WANCHO LETTER U;Lo;0;L;;;;;N;;;;; +1E2DF;WANCHO LETTER LLHA;Lo;0;L;;;;;N;;;;; +1E2E0;WANCHO LETTER TSA;Lo;0;L;;;;;N;;;;; +1E2E1;WANCHO LETTER TRA;Lo;0;L;;;;;N;;;;; +1E2E2;WANCHO LETTER ONG;Lo;0;L;;;;;N;;;;; +1E2E3;WANCHO LETTER AANG;Lo;0;L;;;;;N;;;;; +1E2E4;WANCHO LETTER ANG;Lo;0;L;;;;;N;;;;; +1E2E5;WANCHO LETTER ING;Lo;0;L;;;;;N;;;;; +1E2E6;WANCHO LETTER ON;Lo;0;L;;;;;N;;;;; +1E2E7;WANCHO LETTER EN;Lo;0;L;;;;;N;;;;; +1E2E8;WANCHO LETTER AAN;Lo;0;L;;;;;N;;;;; +1E2E9;WANCHO LETTER NYA;Lo;0;L;;;;;N;;;;; +1E2EA;WANCHO LETTER UEN;Lo;0;L;;;;;N;;;;; +1E2EB;WANCHO LETTER YIH;Lo;0;L;;;;;N;;;;; +1E2EC;WANCHO TONE TUP;Mn;230;NSM;;;;;N;;;;; +1E2ED;WANCHO TONE TUPNI;Mn;230;NSM;;;;;N;;;;; +1E2EE;WANCHO TONE KOI;Mn;230;NSM;;;;;N;;;;; +1E2EF;WANCHO TONE KOINI;Mn;230;NSM;;;;;N;;;;; +1E2F0;WANCHO DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +1E2F1;WANCHO DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +1E2F2;WANCHO DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +1E2F3;WANCHO DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +1E2F4;WANCHO DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +1E2F5;WANCHO DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +1E2F6;WANCHO DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +1E2F7;WANCHO DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +1E2F8;WANCHO DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +1E2F9;WANCHO DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +1E2FF;WANCHO NGUN SIGN;Sc;0;ET;;;;;N;;;;; 1E800;MENDE KIKAKUI SYLLABLE M001 KI;Lo;0;R;;;;;N;;;;; 1E801;MENDE KIKAKUI SYLLABLE M002 KA;Lo;0;R;;;;;N;;;;; 1E802;MENDE KIKAKUI SYLLABLE M003 KU;Lo;0;R;;;;;N;;;;; @@ -27639,6 +30127,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1E948;ADLAM CONSONANT MODIFIER;Mn;230;NSM;;;;;N;;;;; 1E949;ADLAM GEMINATE CONSONANT MODIFIER;Mn;230;NSM;;;;;N;;;;; 1E94A;ADLAM NUKTA;Mn;7;NSM;;;;;N;;;;; +1E94B;ADLAM NASALIZATION MARK;Lm;0;R;;;;;N;;;;; 1E950;ADLAM DIGIT ZERO;Nd;0;R;;0;0;0;N;;;;; 1E951;ADLAM DIGIT ONE;Nd;0;R;;1;1;1;N;;;;; 1E952;ADLAM DIGIT TWO;Nd;0;R;;2;2;2;N;;;;; @@ -27651,6 +30140,135 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1E959;ADLAM DIGIT NINE;Nd;0;R;;9;9;9;N;;;;; 1E95E;ADLAM INITIAL EXCLAMATION MARK;Po;0;R;;;;;N;;;;; 1E95F;ADLAM INITIAL QUESTION MARK;Po;0;R;;;;;N;;;;; +1EC71;INDIC SIYAQ NUMBER ONE;No;0;AL;;;;1;N;;;;; +1EC72;INDIC SIYAQ NUMBER TWO;No;0;AL;;;;2;N;;;;; +1EC73;INDIC SIYAQ NUMBER THREE;No;0;AL;;;;3;N;;;;; +1EC74;INDIC SIYAQ NUMBER FOUR;No;0;AL;;;;4;N;;;;; +1EC75;INDIC SIYAQ NUMBER FIVE;No;0;AL;;;;5;N;;;;; +1EC76;INDIC SIYAQ NUMBER SIX;No;0;AL;;;;6;N;;;;; +1EC77;INDIC SIYAQ NUMBER SEVEN;No;0;AL;;;;7;N;;;;; +1EC78;INDIC SIYAQ NUMBER EIGHT;No;0;AL;;;;8;N;;;;; +1EC79;INDIC SIYAQ NUMBER NINE;No;0;AL;;;;9;N;;;;; +1EC7A;INDIC SIYAQ NUMBER TEN;No;0;AL;;;;10;N;;;;; +1EC7B;INDIC SIYAQ NUMBER TWENTY;No;0;AL;;;;20;N;;;;; +1EC7C;INDIC SIYAQ NUMBER THIRTY;No;0;AL;;;;30;N;;;;; +1EC7D;INDIC SIYAQ NUMBER FORTY;No;0;AL;;;;40;N;;;;; +1EC7E;INDIC SIYAQ NUMBER FIFTY;No;0;AL;;;;50;N;;;;; +1EC7F;INDIC SIYAQ NUMBER SIXTY;No;0;AL;;;;60;N;;;;; +1EC80;INDIC SIYAQ NUMBER SEVENTY;No;0;AL;;;;70;N;;;;; +1EC81;INDIC SIYAQ NUMBER EIGHTY;No;0;AL;;;;80;N;;;;; +1EC82;INDIC SIYAQ NUMBER NINETY;No;0;AL;;;;90;N;;;;; +1EC83;INDIC SIYAQ NUMBER ONE HUNDRED;No;0;AL;;;;100;N;;;;; +1EC84;INDIC SIYAQ NUMBER TWO HUNDRED;No;0;AL;;;;200;N;;;;; +1EC85;INDIC SIYAQ NUMBER THREE HUNDRED;No;0;AL;;;;300;N;;;;; +1EC86;INDIC SIYAQ NUMBER FOUR HUNDRED;No;0;AL;;;;400;N;;;;; +1EC87;INDIC SIYAQ NUMBER FIVE HUNDRED;No;0;AL;;;;500;N;;;;; +1EC88;INDIC SIYAQ NUMBER SIX HUNDRED;No;0;AL;;;;600;N;;;;; +1EC89;INDIC SIYAQ NUMBER SEVEN HUNDRED;No;0;AL;;;;700;N;;;;; +1EC8A;INDIC SIYAQ NUMBER EIGHT HUNDRED;No;0;AL;;;;800;N;;;;; +1EC8B;INDIC SIYAQ NUMBER NINE HUNDRED;No;0;AL;;;;900;N;;;;; +1EC8C;INDIC SIYAQ NUMBER ONE THOUSAND;No;0;AL;;;;1000;N;;;;; +1EC8D;INDIC SIYAQ NUMBER TWO THOUSAND;No;0;AL;;;;2000;N;;;;; +1EC8E;INDIC SIYAQ NUMBER THREE THOUSAND;No;0;AL;;;;3000;N;;;;; +1EC8F;INDIC SIYAQ NUMBER FOUR THOUSAND;No;0;AL;;;;4000;N;;;;; +1EC90;INDIC SIYAQ NUMBER FIVE THOUSAND;No;0;AL;;;;5000;N;;;;; +1EC91;INDIC SIYAQ NUMBER SIX THOUSAND;No;0;AL;;;;6000;N;;;;; +1EC92;INDIC SIYAQ NUMBER SEVEN THOUSAND;No;0;AL;;;;7000;N;;;;; +1EC93;INDIC SIYAQ NUMBER EIGHT THOUSAND;No;0;AL;;;;8000;N;;;;; +1EC94;INDIC SIYAQ NUMBER NINE THOUSAND;No;0;AL;;;;9000;N;;;;; +1EC95;INDIC SIYAQ NUMBER TEN THOUSAND;No;0;AL;;;;10000;N;;;;; +1EC96;INDIC SIYAQ NUMBER TWENTY THOUSAND;No;0;AL;;;;20000;N;;;;; +1EC97;INDIC SIYAQ NUMBER THIRTY THOUSAND;No;0;AL;;;;30000;N;;;;; +1EC98;INDIC SIYAQ NUMBER FORTY THOUSAND;No;0;AL;;;;40000;N;;;;; +1EC99;INDIC SIYAQ NUMBER FIFTY THOUSAND;No;0;AL;;;;50000;N;;;;; +1EC9A;INDIC SIYAQ NUMBER SIXTY THOUSAND;No;0;AL;;;;60000;N;;;;; +1EC9B;INDIC SIYAQ NUMBER SEVENTY THOUSAND;No;0;AL;;;;70000;N;;;;; +1EC9C;INDIC SIYAQ NUMBER EIGHTY THOUSAND;No;0;AL;;;;80000;N;;;;; +1EC9D;INDIC SIYAQ NUMBER NINETY THOUSAND;No;0;AL;;;;90000;N;;;;; +1EC9E;INDIC SIYAQ NUMBER LAKH;No;0;AL;;;;100000;N;;;;; +1EC9F;INDIC SIYAQ NUMBER LAKHAN;No;0;AL;;;;200000;N;;;;; +1ECA0;INDIC SIYAQ LAKH MARK;No;0;AL;;;;100000;N;;;;; +1ECA1;INDIC SIYAQ NUMBER KAROR;No;0;AL;;;;10000000;N;;;;; +1ECA2;INDIC SIYAQ NUMBER KARORAN;No;0;AL;;;;20000000;N;;;;; +1ECA3;INDIC SIYAQ NUMBER PREFIXED ONE;No;0;AL;;;;1;N;;;;; +1ECA4;INDIC SIYAQ NUMBER PREFIXED TWO;No;0;AL;;;;2;N;;;;; +1ECA5;INDIC SIYAQ NUMBER PREFIXED THREE;No;0;AL;;;;3;N;;;;; +1ECA6;INDIC SIYAQ NUMBER PREFIXED FOUR;No;0;AL;;;;4;N;;;;; +1ECA7;INDIC SIYAQ NUMBER PREFIXED FIVE;No;0;AL;;;;5;N;;;;; +1ECA8;INDIC SIYAQ NUMBER PREFIXED SIX;No;0;AL;;;;6;N;;;;; +1ECA9;INDIC SIYAQ NUMBER PREFIXED SEVEN;No;0;AL;;;;7;N;;;;; +1ECAA;INDIC SIYAQ NUMBER PREFIXED EIGHT;No;0;AL;;;;8;N;;;;; +1ECAB;INDIC SIYAQ NUMBER PREFIXED NINE;No;0;AL;;;;9;N;;;;; +1ECAC;INDIC SIYAQ PLACEHOLDER;So;0;AL;;;;;N;;;;; +1ECAD;INDIC SIYAQ FRACTION ONE QUARTER;No;0;AL;;;;1/4;N;;;;; +1ECAE;INDIC SIYAQ FRACTION ONE HALF;No;0;AL;;;;1/2;N;;;;; +1ECAF;INDIC SIYAQ FRACTION THREE QUARTERS;No;0;AL;;;;3/4;N;;;;; +1ECB0;INDIC SIYAQ RUPEE MARK;Sc;0;AL;;;;;N;;;;; +1ECB1;INDIC SIYAQ NUMBER ALTERNATE ONE;No;0;AL;;;;1;N;;;;; +1ECB2;INDIC SIYAQ NUMBER ALTERNATE TWO;No;0;AL;;;;2;N;;;;; +1ECB3;INDIC SIYAQ NUMBER ALTERNATE TEN THOUSAND;No;0;AL;;;;10000;N;;;;; +1ECB4;INDIC SIYAQ ALTERNATE LAKH MARK;No;0;AL;;;;100000;N;;;;; +1ED01;OTTOMAN SIYAQ NUMBER ONE;No;0;AL;;;;1;N;;;;; +1ED02;OTTOMAN SIYAQ NUMBER TWO;No;0;AL;;;;2;N;;;;; +1ED03;OTTOMAN SIYAQ NUMBER THREE;No;0;AL;;;;3;N;;;;; +1ED04;OTTOMAN SIYAQ NUMBER FOUR;No;0;AL;;;;4;N;;;;; +1ED05;OTTOMAN SIYAQ NUMBER FIVE;No;0;AL;;;;5;N;;;;; +1ED06;OTTOMAN SIYAQ NUMBER SIX;No;0;AL;;;;6;N;;;;; +1ED07;OTTOMAN SIYAQ NUMBER SEVEN;No;0;AL;;;;7;N;;;;; +1ED08;OTTOMAN SIYAQ NUMBER EIGHT;No;0;AL;;;;8;N;;;;; +1ED09;OTTOMAN SIYAQ NUMBER NINE;No;0;AL;;;;9;N;;;;; +1ED0A;OTTOMAN SIYAQ NUMBER TEN;No;0;AL;;;;10;N;;;;; +1ED0B;OTTOMAN SIYAQ NUMBER TWENTY;No;0;AL;;;;20;N;;;;; +1ED0C;OTTOMAN SIYAQ NUMBER THIRTY;No;0;AL;;;;30;N;;;;; +1ED0D;OTTOMAN SIYAQ NUMBER FORTY;No;0;AL;;;;40;N;;;;; +1ED0E;OTTOMAN SIYAQ NUMBER FIFTY;No;0;AL;;;;50;N;;;;; +1ED0F;OTTOMAN SIYAQ NUMBER SIXTY;No;0;AL;;;;60;N;;;;; +1ED10;OTTOMAN SIYAQ NUMBER SEVENTY;No;0;AL;;;;70;N;;;;; +1ED11;OTTOMAN SIYAQ NUMBER EIGHTY;No;0;AL;;;;80;N;;;;; +1ED12;OTTOMAN SIYAQ NUMBER NINETY;No;0;AL;;;;90;N;;;;; +1ED13;OTTOMAN SIYAQ NUMBER ONE HUNDRED;No;0;AL;;;;100;N;;;;; +1ED14;OTTOMAN SIYAQ NUMBER TWO HUNDRED;No;0;AL;;;;200;N;;;;; +1ED15;OTTOMAN SIYAQ NUMBER THREE HUNDRED;No;0;AL;;;;300;N;;;;; +1ED16;OTTOMAN SIYAQ NUMBER FOUR HUNDRED;No;0;AL;;;;400;N;;;;; +1ED17;OTTOMAN SIYAQ NUMBER FIVE HUNDRED;No;0;AL;;;;500;N;;;;; +1ED18;OTTOMAN SIYAQ NUMBER SIX HUNDRED;No;0;AL;;;;600;N;;;;; +1ED19;OTTOMAN SIYAQ NUMBER SEVEN HUNDRED;No;0;AL;;;;700;N;;;;; +1ED1A;OTTOMAN SIYAQ NUMBER EIGHT HUNDRED;No;0;AL;;;;800;N;;;;; +1ED1B;OTTOMAN SIYAQ NUMBER NINE HUNDRED;No;0;AL;;;;900;N;;;;; +1ED1C;OTTOMAN SIYAQ NUMBER ONE THOUSAND;No;0;AL;;;;1000;N;;;;; +1ED1D;OTTOMAN SIYAQ NUMBER TWO THOUSAND;No;0;AL;;;;2000;N;;;;; +1ED1E;OTTOMAN SIYAQ NUMBER THREE THOUSAND;No;0;AL;;;;3000;N;;;;; +1ED1F;OTTOMAN SIYAQ NUMBER FOUR THOUSAND;No;0;AL;;;;4000;N;;;;; +1ED20;OTTOMAN SIYAQ NUMBER FIVE THOUSAND;No;0;AL;;;;5000;N;;;;; +1ED21;OTTOMAN SIYAQ NUMBER SIX THOUSAND;No;0;AL;;;;6000;N;;;;; +1ED22;OTTOMAN SIYAQ NUMBER SEVEN THOUSAND;No;0;AL;;;;7000;N;;;;; +1ED23;OTTOMAN SIYAQ NUMBER EIGHT THOUSAND;No;0;AL;;;;8000;N;;;;; +1ED24;OTTOMAN SIYAQ NUMBER NINE THOUSAND;No;0;AL;;;;9000;N;;;;; +1ED25;OTTOMAN SIYAQ NUMBER TEN THOUSAND;No;0;AL;;;;10000;N;;;;; +1ED26;OTTOMAN SIYAQ NUMBER TWENTY THOUSAND;No;0;AL;;;;20000;N;;;;; +1ED27;OTTOMAN SIYAQ NUMBER THIRTY THOUSAND;No;0;AL;;;;30000;N;;;;; +1ED28;OTTOMAN SIYAQ NUMBER FORTY THOUSAND;No;0;AL;;;;40000;N;;;;; +1ED29;OTTOMAN SIYAQ NUMBER FIFTY THOUSAND;No;0;AL;;;;50000;N;;;;; +1ED2A;OTTOMAN SIYAQ NUMBER SIXTY THOUSAND;No;0;AL;;;;60000;N;;;;; +1ED2B;OTTOMAN SIYAQ NUMBER SEVENTY THOUSAND;No;0;AL;;;;70000;N;;;;; +1ED2C;OTTOMAN SIYAQ NUMBER EIGHTY THOUSAND;No;0;AL;;;;80000;N;;;;; +1ED2D;OTTOMAN SIYAQ NUMBER NINETY THOUSAND;No;0;AL;;;;90000;N;;;;; +1ED2E;OTTOMAN SIYAQ MARRATAN;So;0;AL;;;;;N;;;;; +1ED2F;OTTOMAN SIYAQ ALTERNATE NUMBER TWO;No;0;AL;;;;2;N;;;;; +1ED30;OTTOMAN SIYAQ ALTERNATE NUMBER THREE;No;0;AL;;;;3;N;;;;; +1ED31;OTTOMAN SIYAQ ALTERNATE NUMBER FOUR;No;0;AL;;;;4;N;;;;; +1ED32;OTTOMAN SIYAQ ALTERNATE NUMBER FIVE;No;0;AL;;;;5;N;;;;; +1ED33;OTTOMAN SIYAQ ALTERNATE NUMBER SIX;No;0;AL;;;;6;N;;;;; +1ED34;OTTOMAN SIYAQ ALTERNATE NUMBER SEVEN;No;0;AL;;;;7;N;;;;; +1ED35;OTTOMAN SIYAQ ALTERNATE NUMBER EIGHT;No;0;AL;;;;8;N;;;;; +1ED36;OTTOMAN SIYAQ ALTERNATE NUMBER NINE;No;0;AL;;;;9;N;;;;; +1ED37;OTTOMAN SIYAQ ALTERNATE NUMBER TEN;No;0;AL;;;;10;N;;;;; +1ED38;OTTOMAN SIYAQ ALTERNATE NUMBER FOUR HUNDRED;No;0;AL;;;;400;N;;;;; +1ED39;OTTOMAN SIYAQ ALTERNATE NUMBER SIX HUNDRED;No;0;AL;;;;600;N;;;;; +1ED3A;OTTOMAN SIYAQ ALTERNATE NUMBER TWO THOUSAND;No;0;AL;;;;2000;N;;;;; +1ED3B;OTTOMAN SIYAQ ALTERNATE NUMBER TEN THOUSAND;No;0;AL;;;;10000;N;;;;; +1ED3C;OTTOMAN SIYAQ FRACTION ONE HALF;No;0;AL;;;;1/2;N;;;;; +1ED3D;OTTOMAN SIYAQ FRACTION ONE SIXTH;No;0;AL;;;;1/6;N;;;;; 1EE00;ARABIC MATHEMATICAL ALEF;Lo;0;AL; 0627;;;;N;;;;; 1EE01;ARABIC MATHEMATICAL BEH;Lo;0;AL; 0628;;;;N;;;;; 1EE02;ARABIC MATHEMATICAL JEEM;Lo;0;AL; 062C;;;;N;;;;; @@ -28033,6 +30651,9 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1F10A;DIGIT NINE COMMA;No;0;EN; 0039 002C;;9;9;N;;;;; 1F10B;DINGBAT CIRCLED SANS-SERIF DIGIT ZERO;No;0;ON;;;;0;N;;;;; 1F10C;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ZERO;No;0;ON;;;;0;N;;;;; +1F10D;CIRCLED ZERO WITH SLASH;So;0;ON;;;;;N;;;;; +1F10E;CIRCLED ANTICLOCKWISE ARROW;So;0;ON;;;;;N;;;;; +1F10F;CIRCLED DOLLAR SIGN WITH OVERLAID BACKSLASH;So;0;ON;;;;;N;;;;; 1F110;PARENTHESIZED LATIN CAPITAL LETTER A;So;0;L; 0028 0041 0029;;;;N;;;;; 1F111;PARENTHESIZED LATIN CAPITAL LETTER B;So;0;L; 0028 0042 0029;;;;N;;;;; 1F112;PARENTHESIZED LATIN CAPITAL LETTER C;So;0;L; 0028 0043 0029;;;;N;;;;; @@ -28064,6 +30685,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1F12C;CIRCLED ITALIC LATIN CAPITAL LETTER R;So;0;L; 0052;;;;N;;;;; 1F12D;CIRCLED CD;So;0;L; 0043 0044;;;;N;;;;; 1F12E;CIRCLED WZ;So;0;L; 0057 005A;;;;N;;;;; +1F12F;COPYLEFT SYMBOL;So;0;ON;;;;;N;;;;; 1F130;SQUARED LATIN CAPITAL LETTER A;So;0;L; 0041;;;;N;;;;; 1F131;SQUARED LATIN CAPITAL LETTER B;So;0;L; 0042;;;;N;;;;; 1F132;SQUARED LATIN CAPITAL LETTER C;So;0;L; 0043;;;;N;;;;; @@ -28124,6 +30746,10 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1F169;NEGATIVE CIRCLED LATIN CAPITAL LETTER Z;So;0;L;;;;;N;;;;; 1F16A;RAISED MC SIGN;So;0;ON; 004D 0043;;;;N;;;;; 1F16B;RAISED MD SIGN;So;0;ON; 004D 0044;;;;N;;;;; +1F16C;RAISED MR SIGN;So;0;ON; 004D 0052;;;;N;;;;; +1F16D;CIRCLED CC;So;0;ON;;;;;N;;;;; +1F16E;CIRCLED C WITH OVERLAID BACKSLASH;So;0;ON;;;;;N;;;;; +1F16F;CIRCLED HUMAN FIGURE;So;0;ON;;;;;N;;;;; 1F170;NEGATIVE SQUARED LATIN CAPITAL LETTER A;So;0;L;;;;;N;;;;; 1F171;NEGATIVE SQUARED LATIN CAPITAL LETTER B;So;0;L;;;;;N;;;;; 1F172;NEGATIVE SQUARED LATIN CAPITAL LETTER C;So;0;L;;;;;N;;;;; @@ -28185,6 +30811,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1F1AA;SQUARED SHV;So;0;L;;;;;N;;;;; 1F1AB;SQUARED UHD;So;0;L;;;;;N;;;;; 1F1AC;SQUARED VOD;So;0;L;;;;;N;;;;; +1F1AD;MASK WORK SYMBOL;So;0;ON;;;;;N;;;;; 1F1E6;REGIONAL INDICATOR SYMBOL LETTER A;So;0;L;;;;;N;;;;; 1F1E7;REGIONAL INDICATOR SYMBOL LETTER B;So;0;L;;;;;N;;;;; 1F1E8;REGIONAL INDICATOR SYMBOL LETTER C;So;0;L;;;;;N;;;;; @@ -28269,6 +30896,12 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1F248;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-6557;So;0;L; 3014 6557 3015;;;;N;;;;; 1F250;CIRCLED IDEOGRAPH ADVANTAGE;So;0;L; 5F97;;;;N;;;;; 1F251;CIRCLED IDEOGRAPH ACCEPT;So;0;L; 53EF;;;;N;;;;; +1F260;ROUNDED SYMBOL FOR FU;So;0;ON;;;;;N;;;;; +1F261;ROUNDED SYMBOL FOR LU;So;0;ON;;;;;N;;;;; +1F262;ROUNDED SYMBOL FOR SHOU;So;0;ON;;;;;N;;;;; +1F263;ROUNDED SYMBOL FOR XI;So;0;ON;;;;;N;;;;; +1F264;ROUNDED SYMBOL FOR SHUANGXI;So;0;ON;;;;;N;;;;; +1F265;ROUNDED SYMBOL FOR CAI;So;0;ON;;;;;N;;;;; 1F300;CYCLONE;So;0;ON;;;;;N;;;;; 1F301;FOGGY;So;0;ON;;;;;N;;;;; 1F302;CLOSED UMBRELLA;So;0;ON;;;;;N;;;;; @@ -29248,6 +31881,11 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1F6D0;PLACE OF WORSHIP;So;0;ON;;;;;N;;;;; 1F6D1;OCTAGONAL SIGN;So;0;ON;;;;;N;;;;; 1F6D2;SHOPPING TROLLEY;So;0;ON;;;;;N;;;;; +1F6D3;STUPA;So;0;ON;;;;;N;;;;; +1F6D4;PAGODA;So;0;ON;;;;;N;;;;; +1F6D5;HINDU TEMPLE;So;0;ON;;;;;N;;;;; +1F6D6;HUT;So;0;ON;;;;;N;;;;; +1F6D7;ELEVATOR;So;0;ON;;;;;N;;;;; 1F6E0;HAMMER AND WRENCH;So;0;ON;;;;;N;;;;; 1F6E1;SHIELD;So;0;ON;;;;;N;;;;; 1F6E2;OIL DRUM;So;0;ON;;;;;N;;;;; @@ -29268,6 +31906,12 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1F6F4;SCOOTER;So;0;ON;;;;;N;;;;; 1F6F5;MOTOR SCOOTER;So;0;ON;;;;;N;;;;; 1F6F6;CANOE;So;0;ON;;;;;N;;;;; +1F6F7;SLED;So;0;ON;;;;;N;;;;; +1F6F8;FLYING SAUCER;So;0;ON;;;;;N;;;;; +1F6F9;SKATEBOARD;So;0;ON;;;;;N;;;;; +1F6FA;AUTO RICKSHAW;So;0;ON;;;;;N;;;;; +1F6FB;PICKUP TRUCK;So;0;ON;;;;;N;;;;; +1F6FC;ROLLER SKATE;So;0;ON;;;;;N;;;;; 1F700;ALCHEMICAL SYMBOL FOR QUINTESSENCE;So;0;ON;;;;;N;;;;; 1F701;ALCHEMICAL SYMBOL FOR AIR;So;0;ON;;;;;N;;;;; 1F702;ALCHEMICAL SYMBOL FOR FIRE;So;0;ON;;;;;N;;;;; @@ -29469,6 +32113,22 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1F7D2;LIGHT TWELVE POINTED BLACK STAR;So;0;ON;;;;;N;;;;; 1F7D3;HEAVY TWELVE POINTED BLACK STAR;So;0;ON;;;;;N;;;;; 1F7D4;HEAVY TWELVE POINTED PINWHEEL STAR;So;0;ON;;;;;N;;;;; +1F7D5;CIRCLED TRIANGLE;So;0;ON;;;;;N;;;;; +1F7D6;NEGATIVE CIRCLED TRIANGLE;So;0;ON;;;;;N;;;;; +1F7D7;CIRCLED SQUARE;So;0;ON;;;;;N;;;;; +1F7D8;NEGATIVE CIRCLED SQUARE;So;0;ON;;;;;N;;;;; +1F7E0;LARGE ORANGE CIRCLE;So;0;ON;;;;;N;;;;; +1F7E1;LARGE YELLOW CIRCLE;So;0;ON;;;;;N;;;;; +1F7E2;LARGE GREEN CIRCLE;So;0;ON;;;;;N;;;;; +1F7E3;LARGE PURPLE CIRCLE;So;0;ON;;;;;N;;;;; +1F7E4;LARGE BROWN CIRCLE;So;0;ON;;;;;N;;;;; +1F7E5;LARGE RED SQUARE;So;0;ON;;;;;N;;;;; +1F7E6;LARGE BLUE SQUARE;So;0;ON;;;;;N;;;;; +1F7E7;LARGE ORANGE SQUARE;So;0;ON;;;;;N;;;;; +1F7E8;LARGE YELLOW SQUARE;So;0;ON;;;;;N;;;;; +1F7E9;LARGE GREEN SQUARE;So;0;ON;;;;;N;;;;; +1F7EA;LARGE PURPLE SQUARE;So;0;ON;;;;;N;;;;; +1F7EB;LARGE BROWN SQUARE;So;0;ON;;;;;N;;;;; 1F800;LEFTWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;; 1F801;UPWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;; 1F802;RIGHTWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;; @@ -29617,6 +32277,24 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1F8AB;RIGHTWARDS FRONT-TILTED SHADOWED WHITE ARROW;So;0;ON;;;;;N;;;;; 1F8AC;WHITE ARROW SHAFT WIDTH ONE;So;0;ON;;;;;N;;;;; 1F8AD;WHITE ARROW SHAFT WIDTH TWO THIRDS;So;0;ON;;;;;N;;;;; +1F8B0;ARROW POINTING UPWARDS THEN NORTH WEST;So;0;ON;;;;;N;;;;; +1F8B1;ARROW POINTING RIGHTWARDS THEN CURVING SOUTH WEST;So;0;ON;;;;;N;;;;; +1F900;CIRCLED CROSS FORMEE WITH FOUR DOTS;So;0;ON;;;;;N;;;;; +1F901;CIRCLED CROSS FORMEE WITH TWO DOTS;So;0;ON;;;;;N;;;;; +1F902;CIRCLED CROSS FORMEE;So;0;ON;;;;;N;;;;; +1F903;LEFT HALF CIRCLE WITH FOUR DOTS;So;0;ON;;;;;N;;;;; +1F904;LEFT HALF CIRCLE WITH THREE DOTS;So;0;ON;;;;;N;;;;; +1F905;LEFT HALF CIRCLE WITH TWO DOTS;So;0;ON;;;;;N;;;;; +1F906;LEFT HALF CIRCLE WITH DOT;So;0;ON;;;;;N;;;;; +1F907;LEFT HALF CIRCLE;So;0;ON;;;;;N;;;;; +1F908;DOWNWARD FACING HOOK;So;0;ON;;;;;N;;;;; +1F909;DOWNWARD FACING NOTCHED HOOK;So;0;ON;;;;;N;;;;; +1F90A;DOWNWARD FACING HOOK WITH DOT;So;0;ON;;;;;N;;;;; +1F90B;DOWNWARD FACING NOTCHED HOOK WITH DOT;So;0;ON;;;;;N;;;;; +1F90C;PINCHED FINGERS;So;0;ON;;;;;N;;;;; +1F90D;WHITE HEART;So;0;ON;;;;;N;;;;; +1F90E;BROWN HEART;So;0;ON;;;;;N;;;;; +1F90F;PINCHING HAND;So;0;ON;;;;;N;;;;; 1F910;ZIPPER-MOUTH FACE;So;0;ON;;;;;N;;;;; 1F911;MONEY-MOUTH FACE;So;0;ON;;;;;N;;;;; 1F912;FACE WITH THERMOMETER;So;0;ON;;;;;N;;;;; @@ -29632,6 +32310,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1F91C;RIGHT-FACING FIST;So;0;ON;;;;;N;;;;; 1F91D;HANDSHAKE;So;0;ON;;;;;N;;;;; 1F91E;HAND WITH INDEX AND MIDDLE FINGERS CROSSED;So;0;ON;;;;;N;;;;; +1F91F;I LOVE YOU HAND SIGN;So;0;ON;;;;;N;;;;; 1F920;FACE WITH COWBOY HAT;So;0;ON;;;;;N;;;;; 1F921;CLOWN FACE;So;0;ON;;;;;N;;;;; 1F922;NAUSEATED FACE;So;0;ON;;;;;N;;;;; @@ -29640,7 +32319,17 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1F925;LYING FACE;So;0;ON;;;;;N;;;;; 1F926;FACE PALM;So;0;ON;;;;;N;;;;; 1F927;SNEEZING FACE;So;0;ON;;;;;N;;;;; +1F928;FACE WITH ONE EYEBROW RAISED;So;0;ON;;;;;N;;;;; +1F929;GRINNING FACE WITH STAR EYES;So;0;ON;;;;;N;;;;; +1F92A;GRINNING FACE WITH ONE LARGE AND ONE SMALL EYE;So;0;ON;;;;;N;;;;; +1F92B;FACE WITH FINGER COVERING CLOSED LIPS;So;0;ON;;;;;N;;;;; +1F92C;SERIOUS FACE WITH SYMBOLS COVERING MOUTH;So;0;ON;;;;;N;;;;; +1F92D;SMILING FACE WITH SMILING EYES AND HAND COVERING MOUTH;So;0;ON;;;;;N;;;;; +1F92E;FACE WITH OPEN MOUTH VOMITING;So;0;ON;;;;;N;;;;; +1F92F;SHOCKED FACE WITH EXPLODING HEAD;So;0;ON;;;;;N;;;;; 1F930;PREGNANT WOMAN;So;0;ON;;;;;N;;;;; +1F931;BREAST-FEEDING;So;0;ON;;;;;N;;;;; +1F932;PALMS UP TOGETHER;So;0;ON;;;;;N;;;;; 1F933;SELFIE;So;0;ON;;;;;N;;;;; 1F934;PRINCE;So;0;ON;;;;;N;;;;; 1F935;MAN IN TUXEDO;So;0;ON;;;;;N;;;;; @@ -29653,6 +32342,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1F93C;WRESTLERS;So;0;ON;;;;;N;;;;; 1F93D;WATER POLO;So;0;ON;;;;;N;;;;; 1F93E;HANDBALL;So;0;ON;;;;;N;;;;; +1F93F;DIVING MASK;So;0;ON;;;;;N;;;;; 1F940;WILTED FLOWER;So;0;ON;;;;;N;;;;; 1F941;DRUM WITH DRUMSTICKS;So;0;ON;;;;;N;;;;; 1F942;CLINKING GLASSES;So;0;ON;;;;;N;;;;; @@ -29665,6 +32355,10 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1F949;THIRD PLACE MEDAL;So;0;ON;;;;;N;;;;; 1F94A;BOXING GLOVE;So;0;ON;;;;;N;;;;; 1F94B;MARTIAL ARTS UNIFORM;So;0;ON;;;;;N;;;;; +1F94C;CURLING STONE;So;0;ON;;;;;N;;;;; +1F94D;LACROSSE STICK AND BALL;So;0;ON;;;;;N;;;;; +1F94E;SOFTBALL;So;0;ON;;;;;N;;;;; +1F94F;FLYING DISC;So;0;ON;;;;;N;;;;; 1F950;CROISSANT;So;0;ON;;;;;N;;;;; 1F951;AVOCADO;So;0;ON;;;;;N;;;;; 1F952;CUCUMBER;So;0;ON;;;;;N;;;;; @@ -29680,6 +32374,38 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1F95C;PEANUTS;So;0;ON;;;;;N;;;;; 1F95D;KIWIFRUIT;So;0;ON;;;;;N;;;;; 1F95E;PANCAKES;So;0;ON;;;;;N;;;;; +1F95F;DUMPLING;So;0;ON;;;;;N;;;;; +1F960;FORTUNE COOKIE;So;0;ON;;;;;N;;;;; +1F961;TAKEOUT BOX;So;0;ON;;;;;N;;;;; +1F962;CHOPSTICKS;So;0;ON;;;;;N;;;;; +1F963;BOWL WITH SPOON;So;0;ON;;;;;N;;;;; +1F964;CUP WITH STRAW;So;0;ON;;;;;N;;;;; +1F965;COCONUT;So;0;ON;;;;;N;;;;; +1F966;BROCCOLI;So;0;ON;;;;;N;;;;; +1F967;PIE;So;0;ON;;;;;N;;;;; +1F968;PRETZEL;So;0;ON;;;;;N;;;;; +1F969;CUT OF MEAT;So;0;ON;;;;;N;;;;; +1F96A;SANDWICH;So;0;ON;;;;;N;;;;; +1F96B;CANNED FOOD;So;0;ON;;;;;N;;;;; +1F96C;LEAFY GREEN;So;0;ON;;;;;N;;;;; +1F96D;MANGO;So;0;ON;;;;;N;;;;; +1F96E;MOON CAKE;So;0;ON;;;;;N;;;;; +1F96F;BAGEL;So;0;ON;;;;;N;;;;; +1F970;SMILING FACE WITH SMILING EYES AND THREE HEARTS;So;0;ON;;;;;N;;;;; +1F971;YAWNING FACE;So;0;ON;;;;;N;;;;; +1F972;SMILING FACE WITH TEAR;So;0;ON;;;;;N;;;;; +1F973;FACE WITH PARTY HORN AND PARTY HAT;So;0;ON;;;;;N;;;;; +1F974;FACE WITH UNEVEN EYES AND WAVY MOUTH;So;0;ON;;;;;N;;;;; +1F975;OVERHEATED FACE;So;0;ON;;;;;N;;;;; +1F976;FREEZING FACE;So;0;ON;;;;;N;;;;; +1F977;NINJA;So;0;ON;;;;;N;;;;; +1F978;DISGUISED FACE;So;0;ON;;;;;N;;;;; +1F97A;FACE WITH PLEADING EYES;So;0;ON;;;;;N;;;;; +1F97B;SARI;So;0;ON;;;;;N;;;;; +1F97C;LAB COAT;So;0;ON;;;;;N;;;;; +1F97D;GOGGLES;So;0;ON;;;;;N;;;;; +1F97E;HIKING BOOT;So;0;ON;;;;;N;;;;; +1F97F;FLAT SHOE;So;0;ON;;;;;N;;;;; 1F980;CRAB;So;0;ON;;;;;N;;;;; 1F981;LION FACE;So;0;ON;;;;;N;;;;; 1F982;SCORPION;So;0;ON;;;;;N;;;;; @@ -29698,15 +32424,492 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1F98F;RHINOCEROS;So;0;ON;;;;;N;;;;; 1F990;SHRIMP;So;0;ON;;;;;N;;;;; 1F991;SQUID;So;0;ON;;;;;N;;;;; +1F992;GIRAFFE FACE;So;0;ON;;;;;N;;;;; +1F993;ZEBRA FACE;So;0;ON;;;;;N;;;;; +1F994;HEDGEHOG;So;0;ON;;;;;N;;;;; +1F995;SAUROPOD;So;0;ON;;;;;N;;;;; +1F996;T-REX;So;0;ON;;;;;N;;;;; +1F997;CRICKET;So;0;ON;;;;;N;;;;; +1F998;KANGAROO;So;0;ON;;;;;N;;;;; +1F999;LLAMA;So;0;ON;;;;;N;;;;; +1F99A;PEACOCK;So;0;ON;;;;;N;;;;; +1F99B;HIPPOPOTAMUS;So;0;ON;;;;;N;;;;; +1F99C;PARROT;So;0;ON;;;;;N;;;;; +1F99D;RACCOON;So;0;ON;;;;;N;;;;; +1F99E;LOBSTER;So;0;ON;;;;;N;;;;; +1F99F;MOSQUITO;So;0;ON;;;;;N;;;;; +1F9A0;MICROBE;So;0;ON;;;;;N;;;;; +1F9A1;BADGER;So;0;ON;;;;;N;;;;; +1F9A2;SWAN;So;0;ON;;;;;N;;;;; +1F9A3;MAMMOTH;So;0;ON;;;;;N;;;;; +1F9A4;DODO;So;0;ON;;;;;N;;;;; +1F9A5;SLOTH;So;0;ON;;;;;N;;;;; +1F9A6;OTTER;So;0;ON;;;;;N;;;;; +1F9A7;ORANGUTAN;So;0;ON;;;;;N;;;;; +1F9A8;SKUNK;So;0;ON;;;;;N;;;;; +1F9A9;FLAMINGO;So;0;ON;;;;;N;;;;; +1F9AA;OYSTER;So;0;ON;;;;;N;;;;; +1F9AB;BEAVER;So;0;ON;;;;;N;;;;; +1F9AC;BISON;So;0;ON;;;;;N;;;;; +1F9AD;SEAL;So;0;ON;;;;;N;;;;; +1F9AE;GUIDE DOG;So;0;ON;;;;;N;;;;; +1F9AF;PROBING CANE;So;0;ON;;;;;N;;;;; +1F9B0;EMOJI COMPONENT RED HAIR;So;0;ON;;;;;N;;;;; +1F9B1;EMOJI COMPONENT CURLY HAIR;So;0;ON;;;;;N;;;;; +1F9B2;EMOJI COMPONENT BALD;So;0;ON;;;;;N;;;;; +1F9B3;EMOJI COMPONENT WHITE HAIR;So;0;ON;;;;;N;;;;; +1F9B4;BONE;So;0;ON;;;;;N;;;;; +1F9B5;LEG;So;0;ON;;;;;N;;;;; +1F9B6;FOOT;So;0;ON;;;;;N;;;;; +1F9B7;TOOTH;So;0;ON;;;;;N;;;;; +1F9B8;SUPERHERO;So;0;ON;;;;;N;;;;; +1F9B9;SUPERVILLAIN;So;0;ON;;;;;N;;;;; +1F9BA;SAFETY VEST;So;0;ON;;;;;N;;;;; +1F9BB;EAR WITH HEARING AID;So;0;ON;;;;;N;;;;; +1F9BC;MOTORIZED WHEELCHAIR;So;0;ON;;;;;N;;;;; +1F9BD;MANUAL WHEELCHAIR;So;0;ON;;;;;N;;;;; +1F9BE;MECHANICAL ARM;So;0;ON;;;;;N;;;;; +1F9BF;MECHANICAL LEG;So;0;ON;;;;;N;;;;; 1F9C0;CHEESE WEDGE;So;0;ON;;;;;N;;;;; +1F9C1;CUPCAKE;So;0;ON;;;;;N;;;;; +1F9C2;SALT SHAKER;So;0;ON;;;;;N;;;;; +1F9C3;BEVERAGE BOX;So;0;ON;;;;;N;;;;; +1F9C4;GARLIC;So;0;ON;;;;;N;;;;; +1F9C5;ONION;So;0;ON;;;;;N;;;;; +1F9C6;FALAFEL;So;0;ON;;;;;N;;;;; +1F9C7;WAFFLE;So;0;ON;;;;;N;;;;; +1F9C8;BUTTER;So;0;ON;;;;;N;;;;; +1F9C9;MATE DRINK;So;0;ON;;;;;N;;;;; +1F9CA;ICE CUBE;So;0;ON;;;;;N;;;;; +1F9CB;BUBBLE TEA;So;0;ON;;;;;N;;;;; +1F9CD;STANDING PERSON;So;0;ON;;;;;N;;;;; +1F9CE;KNEELING PERSON;So;0;ON;;;;;N;;;;; +1F9CF;DEAF PERSON;So;0;ON;;;;;N;;;;; +1F9D0;FACE WITH MONOCLE;So;0;ON;;;;;N;;;;; +1F9D1;ADULT;So;0;ON;;;;;N;;;;; +1F9D2;CHILD;So;0;ON;;;;;N;;;;; +1F9D3;OLDER ADULT;So;0;ON;;;;;N;;;;; +1F9D4;BEARDED PERSON;So;0;ON;;;;;N;;;;; +1F9D5;PERSON WITH HEADSCARF;So;0;ON;;;;;N;;;;; +1F9D6;PERSON IN STEAMY ROOM;So;0;ON;;;;;N;;;;; +1F9D7;PERSON CLIMBING;So;0;ON;;;;;N;;;;; +1F9D8;PERSON IN LOTUS POSITION;So;0;ON;;;;;N;;;;; +1F9D9;MAGE;So;0;ON;;;;;N;;;;; +1F9DA;FAIRY;So;0;ON;;;;;N;;;;; +1F9DB;VAMPIRE;So;0;ON;;;;;N;;;;; +1F9DC;MERPERSON;So;0;ON;;;;;N;;;;; +1F9DD;ELF;So;0;ON;;;;;N;;;;; +1F9DE;GENIE;So;0;ON;;;;;N;;;;; +1F9DF;ZOMBIE;So;0;ON;;;;;N;;;;; +1F9E0;BRAIN;So;0;ON;;;;;N;;;;; +1F9E1;ORANGE HEART;So;0;ON;;;;;N;;;;; +1F9E2;BILLED CAP;So;0;ON;;;;;N;;;;; +1F9E3;SCARF;So;0;ON;;;;;N;;;;; +1F9E4;GLOVES;So;0;ON;;;;;N;;;;; +1F9E5;COAT;So;0;ON;;;;;N;;;;; +1F9E6;SOCKS;So;0;ON;;;;;N;;;;; +1F9E7;RED GIFT ENVELOPE;So;0;ON;;;;;N;;;;; +1F9E8;FIRECRACKER;So;0;ON;;;;;N;;;;; +1F9E9;JIGSAW PUZZLE PIECE;So;0;ON;;;;;N;;;;; +1F9EA;TEST TUBE;So;0;ON;;;;;N;;;;; +1F9EB;PETRI DISH;So;0;ON;;;;;N;;;;; +1F9EC;DNA DOUBLE HELIX;So;0;ON;;;;;N;;;;; +1F9ED;COMPASS;So;0;ON;;;;;N;;;;; +1F9EE;ABACUS;So;0;ON;;;;;N;;;;; +1F9EF;FIRE EXTINGUISHER;So;0;ON;;;;;N;;;;; +1F9F0;TOOLBOX;So;0;ON;;;;;N;;;;; +1F9F1;BRICK;So;0;ON;;;;;N;;;;; +1F9F2;MAGNET;So;0;ON;;;;;N;;;;; +1F9F3;LUGGAGE;So;0;ON;;;;;N;;;;; +1F9F4;LOTION BOTTLE;So;0;ON;;;;;N;;;;; +1F9F5;SPOOL OF THREAD;So;0;ON;;;;;N;;;;; +1F9F6;BALL OF YARN;So;0;ON;;;;;N;;;;; +1F9F7;SAFETY PIN;So;0;ON;;;;;N;;;;; +1F9F8;TEDDY BEAR;So;0;ON;;;;;N;;;;; +1F9F9;BROOM;So;0;ON;;;;;N;;;;; +1F9FA;BASKET;So;0;ON;;;;;N;;;;; +1F9FB;ROLL OF PAPER;So;0;ON;;;;;N;;;;; +1F9FC;BAR OF SOAP;So;0;ON;;;;;N;;;;; +1F9FD;SPONGE;So;0;ON;;;;;N;;;;; +1F9FE;RECEIPT;So;0;ON;;;;;N;;;;; +1F9FF;NAZAR AMULET;So;0;ON;;;;;N;;;;; +1FA00;NEUTRAL CHESS KING;So;0;ON;;;;;N;;;;; +1FA01;NEUTRAL CHESS QUEEN;So;0;ON;;;;;N;;;;; +1FA02;NEUTRAL CHESS ROOK;So;0;ON;;;;;N;;;;; +1FA03;NEUTRAL CHESS BISHOP;So;0;ON;;;;;N;;;;; +1FA04;NEUTRAL CHESS KNIGHT;So;0;ON;;;;;N;;;;; +1FA05;NEUTRAL CHESS PAWN;So;0;ON;;;;;N;;;;; +1FA06;WHITE CHESS KNIGHT ROTATED FORTY-FIVE DEGREES;So;0;ON;;;;;N;;;;; +1FA07;BLACK CHESS KNIGHT ROTATED FORTY-FIVE DEGREES;So;0;ON;;;;;N;;;;; +1FA08;NEUTRAL CHESS KNIGHT ROTATED FORTY-FIVE DEGREES;So;0;ON;;;;;N;;;;; +1FA09;WHITE CHESS KING ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA0A;WHITE CHESS QUEEN ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA0B;WHITE CHESS ROOK ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA0C;WHITE CHESS BISHOP ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA0D;WHITE CHESS KNIGHT ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA0E;WHITE CHESS PAWN ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA0F;BLACK CHESS KING ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA10;BLACK CHESS QUEEN ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA11;BLACK CHESS ROOK ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA12;BLACK CHESS BISHOP ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA13;BLACK CHESS KNIGHT ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA14;BLACK CHESS PAWN ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA15;NEUTRAL CHESS KING ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA16;NEUTRAL CHESS QUEEN ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA17;NEUTRAL CHESS ROOK ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA18;NEUTRAL CHESS BISHOP ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA19;NEUTRAL CHESS KNIGHT ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA1A;NEUTRAL CHESS PAWN ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA1B;WHITE CHESS KNIGHT ROTATED ONE HUNDRED THIRTY-FIVE DEGREES;So;0;ON;;;;;N;;;;; +1FA1C;BLACK CHESS KNIGHT ROTATED ONE HUNDRED THIRTY-FIVE DEGREES;So;0;ON;;;;;N;;;;; +1FA1D;NEUTRAL CHESS KNIGHT ROTATED ONE HUNDRED THIRTY-FIVE DEGREES;So;0;ON;;;;;N;;;;; +1FA1E;WHITE CHESS TURNED KING;So;0;ON;;;;;N;;;;; +1FA1F;WHITE CHESS TURNED QUEEN;So;0;ON;;;;;N;;;;; +1FA20;WHITE CHESS TURNED ROOK;So;0;ON;;;;;N;;;;; +1FA21;WHITE CHESS TURNED BISHOP;So;0;ON;;;;;N;;;;; +1FA22;WHITE CHESS TURNED KNIGHT;So;0;ON;;;;;N;;;;; +1FA23;WHITE CHESS TURNED PAWN;So;0;ON;;;;;N;;;;; +1FA24;BLACK CHESS TURNED KING;So;0;ON;;;;;N;;;;; +1FA25;BLACK CHESS TURNED QUEEN;So;0;ON;;;;;N;;;;; +1FA26;BLACK CHESS TURNED ROOK;So;0;ON;;;;;N;;;;; +1FA27;BLACK CHESS TURNED BISHOP;So;0;ON;;;;;N;;;;; +1FA28;BLACK CHESS TURNED KNIGHT;So;0;ON;;;;;N;;;;; +1FA29;BLACK CHESS TURNED PAWN;So;0;ON;;;;;N;;;;; +1FA2A;NEUTRAL CHESS TURNED KING;So;0;ON;;;;;N;;;;; +1FA2B;NEUTRAL CHESS TURNED QUEEN;So;0;ON;;;;;N;;;;; +1FA2C;NEUTRAL CHESS TURNED ROOK;So;0;ON;;;;;N;;;;; +1FA2D;NEUTRAL CHESS TURNED BISHOP;So;0;ON;;;;;N;;;;; +1FA2E;NEUTRAL CHESS TURNED KNIGHT;So;0;ON;;;;;N;;;;; +1FA2F;NEUTRAL CHESS TURNED PAWN;So;0;ON;;;;;N;;;;; +1FA30;WHITE CHESS KNIGHT ROTATED TWO HUNDRED TWENTY-FIVE DEGREES;So;0;ON;;;;;N;;;;; +1FA31;BLACK CHESS KNIGHT ROTATED TWO HUNDRED TWENTY-FIVE DEGREES;So;0;ON;;;;;N;;;;; +1FA32;NEUTRAL CHESS KNIGHT ROTATED TWO HUNDRED TWENTY-FIVE DEGREES;So;0;ON;;;;;N;;;;; +1FA33;WHITE CHESS KING ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA34;WHITE CHESS QUEEN ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA35;WHITE CHESS ROOK ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA36;WHITE CHESS BISHOP ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA37;WHITE CHESS KNIGHT ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA38;WHITE CHESS PAWN ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA39;BLACK CHESS KING ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA3A;BLACK CHESS QUEEN ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA3B;BLACK CHESS ROOK ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA3C;BLACK CHESS BISHOP ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA3D;BLACK CHESS KNIGHT ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA3E;BLACK CHESS PAWN ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA3F;NEUTRAL CHESS KING ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA40;NEUTRAL CHESS QUEEN ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA41;NEUTRAL CHESS ROOK ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA42;NEUTRAL CHESS BISHOP ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA43;NEUTRAL CHESS KNIGHT ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA44;NEUTRAL CHESS PAWN ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;; +1FA45;WHITE CHESS KNIGHT ROTATED THREE HUNDRED FIFTEEN DEGREES;So;0;ON;;;;;N;;;;; +1FA46;BLACK CHESS KNIGHT ROTATED THREE HUNDRED FIFTEEN DEGREES;So;0;ON;;;;;N;;;;; +1FA47;NEUTRAL CHESS KNIGHT ROTATED THREE HUNDRED FIFTEEN DEGREES;So;0;ON;;;;;N;;;;; +1FA48;WHITE CHESS EQUIHOPPER;So;0;ON;;;;;N;;;;; +1FA49;BLACK CHESS EQUIHOPPER;So;0;ON;;;;;N;;;;; +1FA4A;NEUTRAL CHESS EQUIHOPPER;So;0;ON;;;;;N;;;;; +1FA4B;WHITE CHESS EQUIHOPPER ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA4C;BLACK CHESS EQUIHOPPER ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA4D;NEUTRAL CHESS EQUIHOPPER ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;; +1FA4E;WHITE CHESS KNIGHT-QUEEN;So;0;ON;;;;;N;;;;; +1FA4F;WHITE CHESS KNIGHT-ROOK;So;0;ON;;;;;N;;;;; +1FA50;WHITE CHESS KNIGHT-BISHOP;So;0;ON;;;;;N;;;;; +1FA51;BLACK CHESS KNIGHT-QUEEN;So;0;ON;;;;;N;;;;; +1FA52;BLACK CHESS KNIGHT-ROOK;So;0;ON;;;;;N;;;;; +1FA53;BLACK CHESS KNIGHT-BISHOP;So;0;ON;;;;;N;;;;; +1FA60;XIANGQI RED GENERAL;So;0;ON;;;;;N;;;;; +1FA61;XIANGQI RED MANDARIN;So;0;ON;;;;;N;;;;; +1FA62;XIANGQI RED ELEPHANT;So;0;ON;;;;;N;;;;; +1FA63;XIANGQI RED HORSE;So;0;ON;;;;;N;;;;; +1FA64;XIANGQI RED CHARIOT;So;0;ON;;;;;N;;;;; +1FA65;XIANGQI RED CANNON;So;0;ON;;;;;N;;;;; +1FA66;XIANGQI RED SOLDIER;So;0;ON;;;;;N;;;;; +1FA67;XIANGQI BLACK GENERAL;So;0;ON;;;;;N;;;;; +1FA68;XIANGQI BLACK MANDARIN;So;0;ON;;;;;N;;;;; +1FA69;XIANGQI BLACK ELEPHANT;So;0;ON;;;;;N;;;;; +1FA6A;XIANGQI BLACK HORSE;So;0;ON;;;;;N;;;;; +1FA6B;XIANGQI BLACK CHARIOT;So;0;ON;;;;;N;;;;; +1FA6C;XIANGQI BLACK CANNON;So;0;ON;;;;;N;;;;; +1FA6D;XIANGQI BLACK SOLDIER;So;0;ON;;;;;N;;;;; +1FA70;BALLET SHOES;So;0;ON;;;;;N;;;;; +1FA71;ONE-PIECE SWIMSUIT;So;0;ON;;;;;N;;;;; +1FA72;BRIEFS;So;0;ON;;;;;N;;;;; +1FA73;SHORTS;So;0;ON;;;;;N;;;;; +1FA74;THONG SANDAL;So;0;ON;;;;;N;;;;; +1FA78;DROP OF BLOOD;So;0;ON;;;;;N;;;;; +1FA79;ADHESIVE BANDAGE;So;0;ON;;;;;N;;;;; +1FA7A;STETHOSCOPE;So;0;ON;;;;;N;;;;; +1FA80;YO-YO;So;0;ON;;;;;N;;;;; +1FA81;KITE;So;0;ON;;;;;N;;;;; +1FA82;PARACHUTE;So;0;ON;;;;;N;;;;; +1FA83;BOOMERANG;So;0;ON;;;;;N;;;;; +1FA84;MAGIC WAND;So;0;ON;;;;;N;;;;; +1FA85;PINATA;So;0;ON;;;;;N;;;;; +1FA86;NESTING DOLLS;So;0;ON;;;;;N;;;;; +1FA90;RINGED PLANET;So;0;ON;;;;;N;;;;; +1FA91;CHAIR;So;0;ON;;;;;N;;;;; +1FA92;RAZOR;So;0;ON;;;;;N;;;;; +1FA93;AXE;So;0;ON;;;;;N;;;;; +1FA94;DIYA LAMP;So;0;ON;;;;;N;;;;; +1FA95;BANJO;So;0;ON;;;;;N;;;;; +1FA96;MILITARY HELMET;So;0;ON;;;;;N;;;;; +1FA97;ACCORDION;So;0;ON;;;;;N;;;;; +1FA98;LONG DRUM;So;0;ON;;;;;N;;;;; +1FA99;COIN;So;0;ON;;;;;N;;;;; +1FA9A;CARPENTRY SAW;So;0;ON;;;;;N;;;;; +1FA9B;SCREWDRIVER;So;0;ON;;;;;N;;;;; +1FA9C;LADDER;So;0;ON;;;;;N;;;;; +1FA9D;HOOK;So;0;ON;;;;;N;;;;; +1FA9E;MIRROR;So;0;ON;;;;;N;;;;; +1FA9F;WINDOW;So;0;ON;;;;;N;;;;; +1FAA0;PLUNGER;So;0;ON;;;;;N;;;;; +1FAA1;SEWING NEEDLE;So;0;ON;;;;;N;;;;; +1FAA2;KNOT;So;0;ON;;;;;N;;;;; +1FAA3;BUCKET;So;0;ON;;;;;N;;;;; +1FAA4;MOUSE TRAP;So;0;ON;;;;;N;;;;; +1FAA5;TOOTHBRUSH;So;0;ON;;;;;N;;;;; +1FAA6;HEADSTONE;So;0;ON;;;;;N;;;;; +1FAA7;PLACARD;So;0;ON;;;;;N;;;;; +1FAA8;ROCK;So;0;ON;;;;;N;;;;; +1FAB0;FLY;So;0;ON;;;;;N;;;;; +1FAB1;WORM;So;0;ON;;;;;N;;;;; +1FAB2;BEETLE;So;0;ON;;;;;N;;;;; +1FAB3;COCKROACH;So;0;ON;;;;;N;;;;; +1FAB4;POTTED PLANT;So;0;ON;;;;;N;;;;; +1FAB5;WOOD;So;0;ON;;;;;N;;;;; +1FAB6;FEATHER;So;0;ON;;;;;N;;;;; +1FAC0;ANATOMICAL HEART;So;0;ON;;;;;N;;;;; +1FAC1;LUNGS;So;0;ON;;;;;N;;;;; +1FAC2;PEOPLE HUGGING;So;0;ON;;;;;N;;;;; +1FAD0;BLUEBERRIES;So;0;ON;;;;;N;;;;; +1FAD1;BELL PEPPER;So;0;ON;;;;;N;;;;; +1FAD2;OLIVE;So;0;ON;;;;;N;;;;; +1FAD3;FLATBREAD;So;0;ON;;;;;N;;;;; +1FAD4;TAMALE;So;0;ON;;;;;N;;;;; +1FAD5;FONDUE;So;0;ON;;;;;N;;;;; +1FAD6;TEAPOT;So;0;ON;;;;;N;;;;; +1FB00;BLOCK SEXTANT-1;So;0;ON;;;;;N;;;;; +1FB01;BLOCK SEXTANT-2;So;0;ON;;;;;N;;;;; +1FB02;BLOCK SEXTANT-12;So;0;ON;;;;;N;;;;; +1FB03;BLOCK SEXTANT-3;So;0;ON;;;;;N;;;;; +1FB04;BLOCK SEXTANT-13;So;0;ON;;;;;N;;;;; +1FB05;BLOCK SEXTANT-23;So;0;ON;;;;;N;;;;; +1FB06;BLOCK SEXTANT-123;So;0;ON;;;;;N;;;;; +1FB07;BLOCK SEXTANT-4;So;0;ON;;;;;N;;;;; +1FB08;BLOCK SEXTANT-14;So;0;ON;;;;;N;;;;; +1FB09;BLOCK SEXTANT-24;So;0;ON;;;;;N;;;;; +1FB0A;BLOCK SEXTANT-124;So;0;ON;;;;;N;;;;; +1FB0B;BLOCK SEXTANT-34;So;0;ON;;;;;N;;;;; +1FB0C;BLOCK SEXTANT-134;So;0;ON;;;;;N;;;;; +1FB0D;BLOCK SEXTANT-234;So;0;ON;;;;;N;;;;; +1FB0E;BLOCK SEXTANT-1234;So;0;ON;;;;;N;;;;; +1FB0F;BLOCK SEXTANT-5;So;0;ON;;;;;N;;;;; +1FB10;BLOCK SEXTANT-15;So;0;ON;;;;;N;;;;; +1FB11;BLOCK SEXTANT-25;So;0;ON;;;;;N;;;;; +1FB12;BLOCK SEXTANT-125;So;0;ON;;;;;N;;;;; +1FB13;BLOCK SEXTANT-35;So;0;ON;;;;;N;;;;; +1FB14;BLOCK SEXTANT-235;So;0;ON;;;;;N;;;;; +1FB15;BLOCK SEXTANT-1235;So;0;ON;;;;;N;;;;; +1FB16;BLOCK SEXTANT-45;So;0;ON;;;;;N;;;;; +1FB17;BLOCK SEXTANT-145;So;0;ON;;;;;N;;;;; +1FB18;BLOCK SEXTANT-245;So;0;ON;;;;;N;;;;; +1FB19;BLOCK SEXTANT-1245;So;0;ON;;;;;N;;;;; +1FB1A;BLOCK SEXTANT-345;So;0;ON;;;;;N;;;;; +1FB1B;BLOCK SEXTANT-1345;So;0;ON;;;;;N;;;;; +1FB1C;BLOCK SEXTANT-2345;So;0;ON;;;;;N;;;;; +1FB1D;BLOCK SEXTANT-12345;So;0;ON;;;;;N;;;;; +1FB1E;BLOCK SEXTANT-6;So;0;ON;;;;;N;;;;; +1FB1F;BLOCK SEXTANT-16;So;0;ON;;;;;N;;;;; +1FB20;BLOCK SEXTANT-26;So;0;ON;;;;;N;;;;; +1FB21;BLOCK SEXTANT-126;So;0;ON;;;;;N;;;;; +1FB22;BLOCK SEXTANT-36;So;0;ON;;;;;N;;;;; +1FB23;BLOCK SEXTANT-136;So;0;ON;;;;;N;;;;; +1FB24;BLOCK SEXTANT-236;So;0;ON;;;;;N;;;;; +1FB25;BLOCK SEXTANT-1236;So;0;ON;;;;;N;;;;; +1FB26;BLOCK SEXTANT-46;So;0;ON;;;;;N;;;;; +1FB27;BLOCK SEXTANT-146;So;0;ON;;;;;N;;;;; +1FB28;BLOCK SEXTANT-1246;So;0;ON;;;;;N;;;;; +1FB29;BLOCK SEXTANT-346;So;0;ON;;;;;N;;;;; +1FB2A;BLOCK SEXTANT-1346;So;0;ON;;;;;N;;;;; +1FB2B;BLOCK SEXTANT-2346;So;0;ON;;;;;N;;;;; +1FB2C;BLOCK SEXTANT-12346;So;0;ON;;;;;N;;;;; +1FB2D;BLOCK SEXTANT-56;So;0;ON;;;;;N;;;;; +1FB2E;BLOCK SEXTANT-156;So;0;ON;;;;;N;;;;; +1FB2F;BLOCK SEXTANT-256;So;0;ON;;;;;N;;;;; +1FB30;BLOCK SEXTANT-1256;So;0;ON;;;;;N;;;;; +1FB31;BLOCK SEXTANT-356;So;0;ON;;;;;N;;;;; +1FB32;BLOCK SEXTANT-1356;So;0;ON;;;;;N;;;;; +1FB33;BLOCK SEXTANT-2356;So;0;ON;;;;;N;;;;; +1FB34;BLOCK SEXTANT-12356;So;0;ON;;;;;N;;;;; +1FB35;BLOCK SEXTANT-456;So;0;ON;;;;;N;;;;; +1FB36;BLOCK SEXTANT-1456;So;0;ON;;;;;N;;;;; +1FB37;BLOCK SEXTANT-2456;So;0;ON;;;;;N;;;;; +1FB38;BLOCK SEXTANT-12456;So;0;ON;;;;;N;;;;; +1FB39;BLOCK SEXTANT-3456;So;0;ON;;;;;N;;;;; +1FB3A;BLOCK SEXTANT-13456;So;0;ON;;;;;N;;;;; +1FB3B;BLOCK SEXTANT-23456;So;0;ON;;;;;N;;;;; +1FB3C;LOWER LEFT BLOCK DIAGONAL LOWER MIDDLE LEFT TO LOWER CENTRE;So;0;ON;;;;;N;;;;; +1FB3D;LOWER LEFT BLOCK DIAGONAL LOWER MIDDLE LEFT TO LOWER RIGHT;So;0;ON;;;;;N;;;;; +1FB3E;LOWER LEFT BLOCK DIAGONAL UPPER MIDDLE LEFT TO LOWER CENTRE;So;0;ON;;;;;N;;;;; +1FB3F;LOWER LEFT BLOCK DIAGONAL UPPER MIDDLE LEFT TO LOWER RIGHT;So;0;ON;;;;;N;;;;; +1FB40;LOWER LEFT BLOCK DIAGONAL UPPER LEFT TO LOWER CENTRE;So;0;ON;;;;;N;;;;; +1FB41;LOWER RIGHT BLOCK DIAGONAL UPPER MIDDLE LEFT TO UPPER CENTRE;So;0;ON;;;;;N;;;;; +1FB42;LOWER RIGHT BLOCK DIAGONAL UPPER MIDDLE LEFT TO UPPER RIGHT;So;0;ON;;;;;N;;;;; +1FB43;LOWER RIGHT BLOCK DIAGONAL LOWER MIDDLE LEFT TO UPPER CENTRE;So;0;ON;;;;;N;;;;; +1FB44;LOWER RIGHT BLOCK DIAGONAL LOWER MIDDLE LEFT TO UPPER RIGHT;So;0;ON;;;;;N;;;;; +1FB45;LOWER RIGHT BLOCK DIAGONAL LOWER LEFT TO UPPER CENTRE;So;0;ON;;;;;N;;;;; +1FB46;LOWER RIGHT BLOCK DIAGONAL LOWER MIDDLE LEFT TO UPPER MIDDLE RIGHT;So;0;ON;;;;;N;;;;; +1FB47;LOWER RIGHT BLOCK DIAGONAL LOWER CENTRE TO LOWER MIDDLE RIGHT;So;0;ON;;;;;N;;;;; +1FB48;LOWER RIGHT BLOCK DIAGONAL LOWER LEFT TO LOWER MIDDLE RIGHT;So;0;ON;;;;;N;;;;; +1FB49;LOWER RIGHT BLOCK DIAGONAL LOWER CENTRE TO UPPER MIDDLE RIGHT;So;0;ON;;;;;N;;;;; +1FB4A;LOWER RIGHT BLOCK DIAGONAL LOWER LEFT TO UPPER MIDDLE RIGHT;So;0;ON;;;;;N;;;;; +1FB4B;LOWER RIGHT BLOCK DIAGONAL LOWER CENTRE TO UPPER RIGHT;So;0;ON;;;;;N;;;;; +1FB4C;LOWER LEFT BLOCK DIAGONAL UPPER CENTRE TO UPPER MIDDLE RIGHT;So;0;ON;;;;;N;;;;; +1FB4D;LOWER LEFT BLOCK DIAGONAL UPPER LEFT TO UPPER MIDDLE RIGHT;So;0;ON;;;;;N;;;;; +1FB4E;LOWER LEFT BLOCK DIAGONAL UPPER CENTRE TO LOWER MIDDLE RIGHT;So;0;ON;;;;;N;;;;; +1FB4F;LOWER LEFT BLOCK DIAGONAL UPPER LEFT TO LOWER MIDDLE RIGHT;So;0;ON;;;;;N;;;;; +1FB50;LOWER LEFT BLOCK DIAGONAL UPPER CENTRE TO LOWER RIGHT;So;0;ON;;;;;N;;;;; +1FB51;LOWER LEFT BLOCK DIAGONAL UPPER MIDDLE LEFT TO LOWER MIDDLE RIGHT;So;0;ON;;;;;N;;;;; +1FB52;UPPER RIGHT BLOCK DIAGONAL LOWER MIDDLE LEFT TO LOWER CENTRE;So;0;ON;;;;;N;;;;; +1FB53;UPPER RIGHT BLOCK DIAGONAL LOWER MIDDLE LEFT TO LOWER RIGHT;So;0;ON;;;;;N;;;;; +1FB54;UPPER RIGHT BLOCK DIAGONAL UPPER MIDDLE LEFT TO LOWER CENTRE;So;0;ON;;;;;N;;;;; +1FB55;UPPER RIGHT BLOCK DIAGONAL UPPER MIDDLE LEFT TO LOWER RIGHT;So;0;ON;;;;;N;;;;; +1FB56;UPPER RIGHT BLOCK DIAGONAL UPPER LEFT TO LOWER CENTRE;So;0;ON;;;;;N;;;;; +1FB57;UPPER LEFT BLOCK DIAGONAL UPPER MIDDLE LEFT TO UPPER CENTRE;So;0;ON;;;;;N;;;;; +1FB58;UPPER LEFT BLOCK DIAGONAL UPPER MIDDLE LEFT TO UPPER RIGHT;So;0;ON;;;;;N;;;;; +1FB59;UPPER LEFT BLOCK DIAGONAL LOWER MIDDLE LEFT TO UPPER CENTRE;So;0;ON;;;;;N;;;;; +1FB5A;UPPER LEFT BLOCK DIAGONAL LOWER MIDDLE LEFT TO UPPER RIGHT;So;0;ON;;;;;N;;;;; +1FB5B;UPPER LEFT BLOCK DIAGONAL LOWER LEFT TO UPPER CENTRE;So;0;ON;;;;;N;;;;; +1FB5C;UPPER LEFT BLOCK DIAGONAL LOWER MIDDLE LEFT TO UPPER MIDDLE RIGHT;So;0;ON;;;;;N;;;;; +1FB5D;UPPER LEFT BLOCK DIAGONAL LOWER CENTRE TO LOWER MIDDLE RIGHT;So;0;ON;;;;;N;;;;; +1FB5E;UPPER LEFT BLOCK DIAGONAL LOWER LEFT TO LOWER MIDDLE RIGHT;So;0;ON;;;;;N;;;;; +1FB5F;UPPER LEFT BLOCK DIAGONAL LOWER CENTRE TO UPPER MIDDLE RIGHT;So;0;ON;;;;;N;;;;; +1FB60;UPPER LEFT BLOCK DIAGONAL LOWER LEFT TO UPPER MIDDLE RIGHT;So;0;ON;;;;;N;;;;; +1FB61;UPPER LEFT BLOCK DIAGONAL LOWER CENTRE TO UPPER RIGHT;So;0;ON;;;;;N;;;;; +1FB62;UPPER RIGHT BLOCK DIAGONAL UPPER CENTRE TO UPPER MIDDLE RIGHT;So;0;ON;;;;;N;;;;; +1FB63;UPPER RIGHT BLOCK DIAGONAL UPPER LEFT TO UPPER MIDDLE RIGHT;So;0;ON;;;;;N;;;;; +1FB64;UPPER RIGHT BLOCK DIAGONAL UPPER CENTRE TO LOWER MIDDLE RIGHT;So;0;ON;;;;;N;;;;; +1FB65;UPPER RIGHT BLOCK DIAGONAL UPPER LEFT TO LOWER MIDDLE RIGHT;So;0;ON;;;;;N;;;;; +1FB66;UPPER RIGHT BLOCK DIAGONAL UPPER CENTRE TO LOWER RIGHT;So;0;ON;;;;;N;;;;; +1FB67;UPPER RIGHT BLOCK DIAGONAL UPPER MIDDLE LEFT TO LOWER MIDDLE RIGHT;So;0;ON;;;;;N;;;;; +1FB68;UPPER AND RIGHT AND LOWER TRIANGULAR THREE QUARTERS BLOCK;So;0;ON;;;;;N;;;;; +1FB69;LEFT AND LOWER AND RIGHT TRIANGULAR THREE QUARTERS BLOCK;So;0;ON;;;;;N;;;;; +1FB6A;UPPER AND LEFT AND LOWER TRIANGULAR THREE QUARTERS BLOCK;So;0;ON;;;;;N;;;;; +1FB6B;LEFT AND UPPER AND RIGHT TRIANGULAR THREE QUARTERS BLOCK;So;0;ON;;;;;N;;;;; +1FB6C;LEFT TRIANGULAR ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;; +1FB6D;UPPER TRIANGULAR ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;; +1FB6E;RIGHT TRIANGULAR ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;; +1FB6F;LOWER TRIANGULAR ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;; +1FB70;VERTICAL ONE EIGHTH BLOCK-2;So;0;ON;;;;;N;;;;; +1FB71;VERTICAL ONE EIGHTH BLOCK-3;So;0;ON;;;;;N;;;;; +1FB72;VERTICAL ONE EIGHTH BLOCK-4;So;0;ON;;;;;N;;;;; +1FB73;VERTICAL ONE EIGHTH BLOCK-5;So;0;ON;;;;;N;;;;; +1FB74;VERTICAL ONE EIGHTH BLOCK-6;So;0;ON;;;;;N;;;;; +1FB75;VERTICAL ONE EIGHTH BLOCK-7;So;0;ON;;;;;N;;;;; +1FB76;HORIZONTAL ONE EIGHTH BLOCK-2;So;0;ON;;;;;N;;;;; +1FB77;HORIZONTAL ONE EIGHTH BLOCK-3;So;0;ON;;;;;N;;;;; +1FB78;HORIZONTAL ONE EIGHTH BLOCK-4;So;0;ON;;;;;N;;;;; +1FB79;HORIZONTAL ONE EIGHTH BLOCK-5;So;0;ON;;;;;N;;;;; +1FB7A;HORIZONTAL ONE EIGHTH BLOCK-6;So;0;ON;;;;;N;;;;; +1FB7B;HORIZONTAL ONE EIGHTH BLOCK-7;So;0;ON;;;;;N;;;;; +1FB7C;LEFT AND LOWER ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;; +1FB7D;LEFT AND UPPER ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;; +1FB7E;RIGHT AND UPPER ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;; +1FB7F;RIGHT AND LOWER ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;; +1FB80;UPPER AND LOWER ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;; +1FB81;HORIZONTAL ONE EIGHTH BLOCK-1358;So;0;ON;;;;;N;;;;; +1FB82;UPPER ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;; +1FB83;UPPER THREE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;; +1FB84;UPPER FIVE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;; +1FB85;UPPER THREE QUARTERS BLOCK;So;0;ON;;;;;N;;;;; +1FB86;UPPER SEVEN EIGHTHS BLOCK;So;0;ON;;;;;N;;;;; +1FB87;RIGHT ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;; +1FB88;RIGHT THREE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;; +1FB89;RIGHT FIVE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;; +1FB8A;RIGHT THREE QUARTERS BLOCK;So;0;ON;;;;;N;;;;; +1FB8B;RIGHT SEVEN EIGHTHS BLOCK;So;0;ON;;;;;N;;;;; +1FB8C;LEFT HALF MEDIUM SHADE;So;0;ON;;;;;N;;;;; +1FB8D;RIGHT HALF MEDIUM SHADE;So;0;ON;;;;;N;;;;; +1FB8E;UPPER HALF MEDIUM SHADE;So;0;ON;;;;;N;;;;; +1FB8F;LOWER HALF MEDIUM SHADE;So;0;ON;;;;;N;;;;; +1FB90;INVERSE MEDIUM SHADE;So;0;ON;;;;;N;;;;; +1FB91;UPPER HALF BLOCK AND LOWER HALF INVERSE MEDIUM SHADE;So;0;ON;;;;;N;;;;; +1FB92;UPPER HALF INVERSE MEDIUM SHADE AND LOWER HALF BLOCK;So;0;ON;;;;;N;;;;; +1FB94;LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK;So;0;ON;;;;;N;;;;; +1FB95;CHECKER BOARD FILL;So;0;ON;;;;;N;;;;; +1FB96;INVERSE CHECKER BOARD FILL;So;0;ON;;;;;N;;;;; +1FB97;HEAVY HORIZONTAL FILL;So;0;ON;;;;;N;;;;; +1FB98;UPPER LEFT TO LOWER RIGHT FILL;So;0;ON;;;;;N;;;;; +1FB99;UPPER RIGHT TO LOWER LEFT FILL;So;0;ON;;;;;N;;;;; +1FB9A;UPPER AND LOWER TRIANGULAR HALF BLOCK;So;0;ON;;;;;N;;;;; +1FB9B;LEFT AND RIGHT TRIANGULAR HALF BLOCK;So;0;ON;;;;;N;;;;; +1FB9C;UPPER LEFT TRIANGULAR MEDIUM SHADE;So;0;ON;;;;;N;;;;; +1FB9D;UPPER RIGHT TRIANGULAR MEDIUM SHADE;So;0;ON;;;;;N;;;;; +1FB9E;LOWER RIGHT TRIANGULAR MEDIUM SHADE;So;0;ON;;;;;N;;;;; +1FB9F;LOWER LEFT TRIANGULAR MEDIUM SHADE;So;0;ON;;;;;N;;;;; +1FBA0;BOX DRAWINGS LIGHT DIAGONAL UPPER CENTRE TO MIDDLE LEFT;So;0;ON;;;;;N;;;;; +1FBA1;BOX DRAWINGS LIGHT DIAGONAL UPPER CENTRE TO MIDDLE RIGHT;So;0;ON;;;;;N;;;;; +1FBA2;BOX DRAWINGS LIGHT DIAGONAL MIDDLE LEFT TO LOWER CENTRE;So;0;ON;;;;;N;;;;; +1FBA3;BOX DRAWINGS LIGHT DIAGONAL MIDDLE RIGHT TO LOWER CENTRE;So;0;ON;;;;;N;;;;; +1FBA4;BOX DRAWINGS LIGHT DIAGONAL UPPER CENTRE TO MIDDLE LEFT TO LOWER CENTRE;So;0;ON;;;;;N;;;;; +1FBA5;BOX DRAWINGS LIGHT DIAGONAL UPPER CENTRE TO MIDDLE RIGHT TO LOWER CENTRE;So;0;ON;;;;;N;;;;; +1FBA6;BOX DRAWINGS LIGHT DIAGONAL MIDDLE LEFT TO LOWER CENTRE TO MIDDLE RIGHT;So;0;ON;;;;;N;;;;; +1FBA7;BOX DRAWINGS LIGHT DIAGONAL MIDDLE LEFT TO UPPER CENTRE TO MIDDLE RIGHT;So;0;ON;;;;;N;;;;; +1FBA8;BOX DRAWINGS LIGHT DIAGONAL UPPER CENTRE TO MIDDLE LEFT AND MIDDLE RIGHT TO LOWER CENTRE;So;0;ON;;;;;N;;;;; +1FBA9;BOX DRAWINGS LIGHT DIAGONAL UPPER CENTRE TO MIDDLE RIGHT AND MIDDLE LEFT TO LOWER CENTRE;So;0;ON;;;;;N;;;;; +1FBAA;BOX DRAWINGS LIGHT DIAGONAL UPPER CENTRE TO MIDDLE RIGHT TO LOWER CENTRE TO MIDDLE LEFT;So;0;ON;;;;;N;;;;; +1FBAB;BOX DRAWINGS LIGHT DIAGONAL UPPER CENTRE TO MIDDLE LEFT TO LOWER CENTRE TO MIDDLE RIGHT;So;0;ON;;;;;N;;;;; +1FBAC;BOX DRAWINGS LIGHT DIAGONAL MIDDLE LEFT TO UPPER CENTRE TO MIDDLE RIGHT TO LOWER CENTRE;So;0;ON;;;;;N;;;;; +1FBAD;BOX DRAWINGS LIGHT DIAGONAL MIDDLE RIGHT TO UPPER CENTRE TO MIDDLE LEFT TO LOWER CENTRE;So;0;ON;;;;;N;;;;; +1FBAE;BOX DRAWINGS LIGHT DIAGONAL DIAMOND;So;0;ON;;;;;N;;;;; +1FBAF;BOX DRAWINGS LIGHT HORIZONTAL WITH VERTICAL STROKE;So;0;ON;;;;;N;;;;; +1FBB0;ARROWHEAD-SHAPED POINTER;So;0;ON;;;;;N;;;;; +1FBB1;INVERSE CHECK MARK;So;0;ON;;;;;N;;;;; +1FBB2;LEFT HALF RUNNING MAN;So;0;ON;;;;;N;;;;; +1FBB3;RIGHT HALF RUNNING MAN;So;0;ON;;;;;N;;;;; +1FBB4;INVERSE DOWNWARDS ARROW WITH TIP LEFTWARDS;So;0;ON;;;;;N;;;;; +1FBB5;LEFTWARDS ARROW AND UPPER AND LOWER ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;; +1FBB6;RIGHTWARDS ARROW AND UPPER AND LOWER ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;; +1FBB7;DOWNWARDS ARROW AND RIGHT ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;; +1FBB8;UPWARDS ARROW AND RIGHT ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;; +1FBB9;LEFT HALF FOLDER;So;0;ON;;;;;N;;;;; +1FBBA;RIGHT HALF FOLDER;So;0;ON;;;;;N;;;;; +1FBBB;VOIDED GREEK CROSS;So;0;ON;;;;;N;;;;; +1FBBC;RIGHT OPEN SQUARED DOT;So;0;ON;;;;;N;;;;; +1FBBD;NEGATIVE DIAGONAL CROSS;So;0;ON;;;;;N;;;;; +1FBBE;NEGATIVE DIAGONAL MIDDLE RIGHT TO LOWER CENTRE;So;0;ON;;;;;N;;;;; +1FBBF;NEGATIVE DIAGONAL DIAMOND;So;0;ON;;;;;N;;;;; +1FBC0;WHITE HEAVY SALTIRE WITH ROUNDED CORNERS;So;0;ON;;;;;N;;;;; +1FBC1;LEFT THIRD WHITE RIGHT POINTING INDEX;So;0;ON;;;;;N;;;;; +1FBC2;MIDDLE THIRD WHITE RIGHT POINTING INDEX;So;0;ON;;;;;N;;;;; +1FBC3;RIGHT THIRD WHITE RIGHT POINTING INDEX;So;0;ON;;;;;N;;;;; +1FBC4;NEGATIVE SQUARED QUESTION MARK;So;0;ON;;;;;N;;;;; +1FBC5;STICK FIGURE;So;0;ON;;;;;N;;;;; +1FBC6;STICK FIGURE WITH ARMS RAISED;So;0;ON;;;;;N;;;;; +1FBC7;STICK FIGURE LEANING LEFT;So;0;ON;;;;;N;;;;; +1FBC8;STICK FIGURE LEANING RIGHT;So;0;ON;;;;;N;;;;; +1FBC9;STICK FIGURE WITH DRESS;So;0;ON;;;;;N;;;;; +1FBCA;WHITE UP-POINTING CHEVRON;So;0;ON;;;;;N;;;;; +1FBF0;SEGMENTED DIGIT ZERO;Nd;0;EN; 0030;0;0;0;N;;;;; +1FBF1;SEGMENTED DIGIT ONE;Nd;0;EN; 0031;1;1;1;N;;;;; +1FBF2;SEGMENTED DIGIT TWO;Nd;0;EN; 0032;2;2;2;N;;;;; +1FBF3;SEGMENTED DIGIT THREE;Nd;0;EN; 0033;3;3;3;N;;;;; +1FBF4;SEGMENTED DIGIT FOUR;Nd;0;EN; 0034;4;4;4;N;;;;; +1FBF5;SEGMENTED DIGIT FIVE;Nd;0;EN; 0035;5;5;5;N;;;;; +1FBF6;SEGMENTED DIGIT SIX;Nd;0;EN; 0036;6;6;6;N;;;;; +1FBF7;SEGMENTED DIGIT SEVEN;Nd;0;EN; 0037;7;7;7;N;;;;; +1FBF8;SEGMENTED DIGIT EIGHT;Nd;0;EN; 0038;8;8;8;N;;;;; +1FBF9;SEGMENTED DIGIT NINE;Nd;0;EN; 0039;9;9;9;N;;;;; 20000;;Lo;0;L;;;;;N;;;;; -2A6D6;;Lo;0;L;;;;;N;;;;; +2A6DD;;Lo;0;L;;;;;N;;;;; 2A700;;Lo;0;L;;;;;N;;;;; 2B734;;Lo;0;L;;;;;N;;;;; 2B740;;Lo;0;L;;;;;N;;;;; 2B81D;;Lo;0;L;;;;;N;;;;; 2B820;;Lo;0;L;;;;;N;;;;; 2CEA1;;Lo;0;L;;;;;N;;;;; +2CEB0;;Lo;0;L;;;;;N;;;;; +2EBE0;;Lo;0;L;;;;;N;;;;; 2F800;CJK COMPATIBILITY IDEOGRAPH-2F800;Lo;0;L;4E3D;;;;N;;;;; 2F801;CJK COMPATIBILITY IDEOGRAPH-2F801;Lo;0;L;4E38;;;;N;;;;; 2F802;CJK COMPATIBILITY IDEOGRAPH-2F802;Lo;0;L;4E41;;;;N;;;;; @@ -30249,6 +33452,8 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 2FA1B;CJK COMPATIBILITY IDEOGRAPH-2FA1B;Lo;0;L;9F16;;;;N;;;;; 2FA1C;CJK COMPATIBILITY IDEOGRAPH-2FA1C;Lo;0;L;9F3B;;;;N;;;;; 2FA1D;CJK COMPATIBILITY IDEOGRAPH-2FA1D;Lo;0;L;2A600;;;;N;;;;; +30000;;Lo;0;L;;;;;N;;;;; +3134A;;Lo;0;L;;;;;N;;;;; E0001;LANGUAGE TAG;Cf;0;BN;;;;;N;;;;; E0020;TAG SPACE;Cf;0;BN;;;;;N;;;;; E0021;TAG EXCLAMATION MARK;Cf;0;BN;;;;;N;;;;; diff --git a/codex/stdlib/Artifacts.md b/codex/stdlib/Artifacts.md new file mode 100644 index 0000000..80f4c62 --- /dev/null +++ b/codex/stdlib/Artifacts.md @@ -0,0 +1,21 @@ +# Artifacts + +```@meta +DocTestSetup = :(using Artifacts) +``` + +Starting with Julia 1.6, the artifacts support has moved from `Pkg.jl` to Julia itself. +Until proper documentation can be added here, you can learn more about artifacts in the +`Pkg.jl` manual at . + +!!! compat "Julia 1.6" + Julia's artifacts API requires at least Julia 1.6. In Julia + versions 1.3 to 1.5, you can use `Pkg.Artifacts` instead. + + +```@docs +Artifacts.artifact_meta +Artifacts.artifact_hash +Artifacts.find_artifacts_toml +Artifacts.@artifact_str +``` diff --git a/codex/stdlib/Downloads.md b/codex/stdlib/Downloads.md new file mode 100644 index 0000000..23628fd --- /dev/null +++ b/codex/stdlib/Downloads.md @@ -0,0 +1,9 @@ +# Downloads + +```@docs +Downloads.download +Downloads.request +Downloads.Response +Downloads.RequestError +Downloads.Downloader +``` diff --git a/codex/stdlib/LazyArtifacts.md b/codex/stdlib/LazyArtifacts.md new file mode 100644 index 0000000..9de6b21 --- /dev/null +++ b/codex/stdlib/LazyArtifacts.md @@ -0,0 +1,10 @@ +# Lazy Artifacts + +```@meta +DocTestSetup = :(using LazyArtifacts) +``` + +In order for a package to download artifacts lazily, `LazyArtifacts` must be +explicitly listed as a dependency of that package. + +For further information on artifacts, see [Artifacts](@ref). diff --git a/codex/stdlib/SuiteSparse.md b/codex/stdlib/SuiteSparse.md new file mode 100644 index 0000000..e8654ca --- /dev/null +++ b/codex/stdlib/SuiteSparse.md @@ -0,0 +1,34 @@ +# Sparse Linear Algebra + +```@meta +DocTestSetup = :(using LinearAlgebra, SparseArrays, SuiteSparse) +``` + +Sparse matrix solvers call functions from [SuiteSparse](http://suitesparse.com). The following factorizations are available: + +| Type | Description | +|:--------------------------------- |:--------------------------------------------- | +| `SuiteSparse.CHOLMOD.Factor` | Cholesky factorization | +| `SuiteSparse.UMFPACK.UmfpackLU` | LU factorization | +| `SuiteSparse.SPQR.QRSparse` | QR factorization | + +Other solvers such as [Pardiso.jl](https://github.com/JuliaSparse/Pardiso.jl/) are as external packages. [Arpack.jl](https://julialinearalgebra.github.io/Arpack.jl/stable/) provides `eigs` and `svds` for iterative solution of eigensystems and singular value decompositions. + +These factorizations are described in the [`Linear Algebra`](@ref man-linalg) section of the manual: +1. [`cholesky`](@ref) +2. [`ldlt`](@ref) +3. [`lu`](@ref) +4. [`qr`](@ref) + +```@docs +SuiteSparse.CHOLMOD.lowrankupdate +SuiteSparse.CHOLMOD.lowrankupdate! +SuiteSparse.CHOLMOD.lowrankdowndate +SuiteSparse.CHOLMOD.lowrankdowndate! +SuiteSparse.CHOLMOD.lowrankupdowndate! +``` + + +```@meta +DocTestSetup = nothing +``` diff --git a/codex/stdlib/TOML.md b/codex/stdlib/TOML.md new file mode 100644 index 0000000..36e8ec6 --- /dev/null +++ b/codex/stdlib/TOML.md @@ -0,0 +1,132 @@ +# TOML + +TOML.jl is a Julia standard library for parsing and writing [TOML +v1.0](https://toml.io/en/) files. + +## Parsing TOML data + +```jldoctest +julia> using TOML + +julia> data = """ + [database] + server = "192.168.1.1" + ports = [ 8001, 8001, 8002 ] + """; + +julia> TOML.parse(data) +Dict{String, Any} with 1 entry: + "database" => Dict{String, Any}("server"=>"192.168.1.1", "ports"=>[8001, 8001… +``` + +To parse a file, use [`TOML.parsefile`](@ref). If the file has a syntax error, +an exception is thrown: + +```jldoctest +julia> using TOML + +julia> TOML.parse(""" + value = 0.0.0 + """) +ERROR: TOML Parser error: +none:1:16 error: failed to parse value + value = 0.0.0 + ^ +[...] +``` + +There are other versions of the parse functions ([`TOML.tryparse`](@ref) +and [`TOML.tryparsefile`]) that instead of throwing exceptions on parser error +returns a [`TOML.ParserError`](@ref) with information: + +```jldoctest +julia> using TOML + +julia> err = TOML.tryparse(""" + value = 0.0.0 + """); + +julia> err.type +ErrGenericValueError::ErrorType = 14 + +julia> err.line +1 + +julia> err.column +16 +``` + + +## Exporting data to TOML file + +The [`TOML.print`](@ref) function is used to print (or serialize) data into TOML +format. + +```jldoctest +julia> using TOML + +julia> data = Dict( + "names" => ["Julia", "Julio"], + "age" => [10, 20], + ); + +julia> TOML.print(data) +names = ["Julia", "Julio"] +age = [10, 20] + +julia> fname = tempname(); + +julia> open(fname, "w") do io + TOML.print(io, data) + end + +julia> TOML.parsefile(fname) +Dict{String, Any} with 2 entries: + "names" => ["Julia", "Julio"] + "age" => [10, 20] +``` + +Keys can be sorted according to some value + +```jldoctest +julia> using TOML + +julia> TOML.print(Dict( + "abc" => 1, + "ab" => 2, + "abcd" => 3, + ); sorted=true, by=length) +ab = 2 +abc = 1 +abcd = 3 +``` + +For custom structs, pass a function that converts the struct to a supported +type + +```jldoctest +julia> using TOML + +julia> struct MyStruct + a::Int + b::String + end + +julia> TOML.print(Dict("foo" => MyStruct(5, "bar"))) do x + x isa MyStruct && return [x.a, x.b] + error("unhandled type $(typeof(x))") + end +foo = [5, "bar"] +``` + + +## References +```@docs +TOML.parse +TOML.parsefile +TOML.tryparse +TOML.tryparsefile +TOML.print +TOML.Parser +TOML.ParserError +``` diff --git a/make.jl b/make.jl index 95e3f3b..5f38fde 100644 --- a/make.jl +++ b/make.jl @@ -166,12 +166,12 @@ const PAGES = [ t_Base => BaseDocs, t_Standard_Library => StdlibDocs, t_Developer_Documentation => DevDocs, - hide("NEWS.md"), + # hide("NEWS.md"), ] else const PAGES = [ t_Julia_Documentation => "index.md", - hide("NEWS.md"), + # hide("NEWS.md"), t_Manual => Manual, t_Base => BaseDocs, t_Standard_Library => StdlibDocs, @@ -196,7 +196,7 @@ else prettyurls = !("local" in ARGS), canonical = t_html_canonical, analytics = t_analytics, - assets = ["assets/julia-manual.css", ], + assets = ["assets/julia-manual.css", "assets/custom.css"], collapselevel = 1, ) end diff --git a/src/NEWS.md b/src/NEWS.md deleted file mode 100644 index f542849..0000000 --- a/src/NEWS.md +++ /dev/null @@ -1,109 +0,0 @@ -Julia v1.3 Release Notes -======================== - -New language features ---------------------- - -* Support for Unicode 12.1.0 ([#32002](https://github.com/JuliaLang/julia/issues/32002)). -* Methods can now be added to an abstract type ([#31916](https://github.com/JuliaLang/julia/issues/31916)). - -Language changes ----------------- - - -Multi-threading changes ------------------------ - -* All system-level I/O operations (e.g. files and sockets) are now thread-safe. - This does not include subtypes of `IO` that are entirely in-memory, such as `IOBuffer`, - although it specifically does include `BufferStream`. - ([#32309](https://github.com/JuliaLang/julia/issues/32309), [#32174](https://github.com/JuliaLang/julia/issues/32174), [#31981](https://github.com/JuliaLang/julia/issues/31981), [#32421](https://github.com/JuliaLang/julia/issues/32421)). -* The global random number generator (`GLOBAL_RNG`) is now thread-safe (and thread-local) ([#32407](https://github.com/JuliaLang/julia/issues/32407)). -* New experimental `Threads.@spawn` macro that runs a task on any available thread ([#32600](https://github.com/JuliaLang/julia/issues/32600)). - -Build system changes --------------------- - - -New library functions ---------------------- - -* `findfirst`, `findlast`, `findnext` and `findprev` now accept a character as first argument - to search for that character in a string passed as the second argument ([#31664](https://github.com/JuliaLang/julia/issues/31664)). -* New `findall(pattern, string)` method where `pattern` is a string or regex ([#31834](https://github.com/JuliaLang/julia/issues/31834)). -* `istaskfailed` is now documented and exported, like its siblings `istaskdone` and `istaskstarted` ([#32300](https://github.com/JuliaLang/julia/issues/32300)). -* `RefArray` and `RefValue` objects now accept index `CartesianIndex()` in `getindex` and `setindex!` ([#32653](https://github.com/JuliaLang/julia/issues/32653)) - -Standard library changes ------------------------- - -* `Regex` can now be multiplied (`*`) and exponentiated (`^`), like strings ([#23422](https://github.com/JuliaLang/julia/issues/23422)). -* `Cmd` interpolation (``` `$(x::Cmd) a b c` ``` where) now propagates `x`'s process flags - (environment, flags, working directory, etc) if `x` is the first interpolant and errors - otherwise ([#24353](https://github.com/JuliaLang/julia/issues/24353)). -* Zero-dimensional arrays are now consistently preserved in the return values of mathematical - functions that operate on the array(s) as a whole (and are not explicitly broadcasted across their elements). - Previously, the functions `+`, `-`, `*`, `/`, `conj`, `real` and `imag` returned the unwrapped element - when operating over zero-dimensional arrays ([#32122](https://github.com/JuliaLang/julia/issues/32122)). -* `IPAddr` subtypes now behave like scalars when used in broadcasting ([#32133](https://github.com/JuliaLang/julia/issues/32133)). -* `clamp` can now handle missing values ([#31066](https://github.com/JuliaLang/julia/issues/31066)). -* `empty` now accepts a `NamedTuple` ([#32534](https://github.com/JuliaLang/julia/issues/32534)). -* `mod` now accepts a unit range as the second argument to easily perform offset modular arithmetic to ensure the result is inside the range ([#32628](https://github.com/JuliaLang/julia/issues/32628)). - -#### Libdl - -* `dlopen()` can now be invoked in `do`-block syntax, similar to `open()`. - -#### LinearAlgebra - -* The BLAS submodule no longer exports `dot`, which conflicts with that in LinearAlgebra ([#31838](https://github.com/JuliaLang/julia/issues/31838)). -* `diagm` and `spdiagm` now accept optional `m,n` initial arguments to specify a size ([#31654](https://github.com/JuliaLang/julia/issues/31654)). -* `Hessenberg` factorizations `H` now support efficient shifted solves `(H+µI) \ b` and determinants, and use a specialized tridiagonal factorization for Hermitian matrices. There is also a new `UpperHessenberg` matrix type ([#31853](https://github.com/JuliaLang/julia/issues/31853)). - -#### SparseArrays - -* `SparseMatrixCSC(m,n,colptr,rowval,nzval)` perform consistency checks for arguments: - `colptr` must be properly populated and lengths of `colptr`, `rowval`, and `nzval` - must be compatible with `m`, `n`, and `eltype(colptr)`. -* `sparse(I, J, V, m, n)` verifies lengths of `I`, `J`, `V` are equal and compatible with - `eltype(I)` and `m`, `n`. -* The `sprand` function is now 2 to 5 times faster ([#30494](https://github.com/JuliaLang/julia/issues/30494)). As a consequence of this change, the random stream of matrices produced with `sprand` and `sprandn` has changed. - -#### Dates - -* `DateTime` and `Time` formatting/parsing now supports 12-hour clocks with AM/PM via `I` and `p` codes, similar to `strftime` ([#32308](https://github.com/JuliaLang/julia/issues/32308)). -* Fixed `repr` such that it displays `Time` as it would be entered in Julia ([#32103](https://github.com/JuliaLang/julia/issues/32103)). - -#### Sockets - -* `getipaddrs` returns IP addresses in the order provided by libuv ([#32260](https://github.com/JuliaLang/julia/issues/32260)). -* `getipaddr` prefers to return the first `IPv4` interface address provided by libuv ([#32260](https://github.com/JuliaLang/julia/issues/32260)). - -#### Statistics - -* `mean` now accepts both a function argument and a `dims` keyword ([#31576](https://github.com/JuliaLang/julia/issues/31576)). - -#### Sockets - -* Added `InetAddr` constructor from `AbstractString`, representing IP address, and `Integer`, - representing port number ([#31459](https://github.com/JuliaLang/julia/issues/31459)). - -#### Miscellaneous - -* `foldr` and `mapfoldr` now work on any iterator that supports `Iterators.reverse`, not just arrays ([#31781](https://github.com/JuliaLang/julia/issues/31781)). - -Deprecated or removed ---------------------- - -* `@spawn expr` from the `Distributed` standard library should be replaced with `@spawnat :any expr` ([#32600](https://github.com/JuliaLang/julia/issues/32600)). - -External dependencies ---------------------- - -Tooling Improvements ---------------------- - -* The `ClangSA.jl` static analysis package has been imported, which makes use of - the clang static analyzer to validate GC invariants in Julia's C code. The analysis - may be run using `make -C src analyzegc`. - diff --git a/src/assets/custom.css b/src/assets/custom.css index d7a8d7d..acbdb4b 100644 --- a/src/assets/custom.css +++ b/src/assets/custom.css @@ -18,3 +18,7 @@ li p { article footer { padding: 0em 0em 2em 0em; } + +html.theme--documenter-dark article code { + color: #03cbe2; +} diff --git a/src/stdlib/Artifacts.md b/src/stdlib/Artifacts.md new file mode 100644 index 0000000..80f4c62 --- /dev/null +++ b/src/stdlib/Artifacts.md @@ -0,0 +1,21 @@ +# Artifacts + +```@meta +DocTestSetup = :(using Artifacts) +``` + +Starting with Julia 1.6, the artifacts support has moved from `Pkg.jl` to Julia itself. +Until proper documentation can be added here, you can learn more about artifacts in the +`Pkg.jl` manual at . + +!!! compat "Julia 1.6" + Julia's artifacts API requires at least Julia 1.6. In Julia + versions 1.3 to 1.5, you can use `Pkg.Artifacts` instead. + + +```@docs +Artifacts.artifact_meta +Artifacts.artifact_hash +Artifacts.find_artifacts_toml +Artifacts.@artifact_str +``` diff --git a/src/stdlib/Downloads.md b/src/stdlib/Downloads.md new file mode 100644 index 0000000..23628fd --- /dev/null +++ b/src/stdlib/Downloads.md @@ -0,0 +1,9 @@ +# Downloads + +```@docs +Downloads.download +Downloads.request +Downloads.Response +Downloads.RequestError +Downloads.Downloader +``` diff --git a/src/stdlib/LazyArtifacts.md b/src/stdlib/LazyArtifacts.md new file mode 100644 index 0000000..9de6b21 --- /dev/null +++ b/src/stdlib/LazyArtifacts.md @@ -0,0 +1,10 @@ +# Lazy Artifacts + +```@meta +DocTestSetup = :(using LazyArtifacts) +``` + +In order for a package to download artifacts lazily, `LazyArtifacts` must be +explicitly listed as a dependency of that package. + +For further information on artifacts, see [Artifacts](@ref). diff --git a/src/stdlib/SuiteSparse.md b/src/stdlib/SuiteSparse.md new file mode 100644 index 0000000..e8654ca --- /dev/null +++ b/src/stdlib/SuiteSparse.md @@ -0,0 +1,34 @@ +# Sparse Linear Algebra + +```@meta +DocTestSetup = :(using LinearAlgebra, SparseArrays, SuiteSparse) +``` + +Sparse matrix solvers call functions from [SuiteSparse](http://suitesparse.com). The following factorizations are available: + +| Type | Description | +|:--------------------------------- |:--------------------------------------------- | +| `SuiteSparse.CHOLMOD.Factor` | Cholesky factorization | +| `SuiteSparse.UMFPACK.UmfpackLU` | LU factorization | +| `SuiteSparse.SPQR.QRSparse` | QR factorization | + +Other solvers such as [Pardiso.jl](https://github.com/JuliaSparse/Pardiso.jl/) are as external packages. [Arpack.jl](https://julialinearalgebra.github.io/Arpack.jl/stable/) provides `eigs` and `svds` for iterative solution of eigensystems and singular value decompositions. + +These factorizations are described in the [`Linear Algebra`](@ref man-linalg) section of the manual: +1. [`cholesky`](@ref) +2. [`ldlt`](@ref) +3. [`lu`](@ref) +4. [`qr`](@ref) + +```@docs +SuiteSparse.CHOLMOD.lowrankupdate +SuiteSparse.CHOLMOD.lowrankupdate! +SuiteSparse.CHOLMOD.lowrankdowndate +SuiteSparse.CHOLMOD.lowrankdowndate! +SuiteSparse.CHOLMOD.lowrankupdowndate! +``` + + +```@meta +DocTestSetup = nothing +``` diff --git a/src/stdlib/TOML.md b/src/stdlib/TOML.md new file mode 100644 index 0000000..36e8ec6 --- /dev/null +++ b/src/stdlib/TOML.md @@ -0,0 +1,132 @@ +# TOML + +TOML.jl is a Julia standard library for parsing and writing [TOML +v1.0](https://toml.io/en/) files. + +## Parsing TOML data + +```jldoctest +julia> using TOML + +julia> data = """ + [database] + server = "192.168.1.1" + ports = [ 8001, 8001, 8002 ] + """; + +julia> TOML.parse(data) +Dict{String, Any} with 1 entry: + "database" => Dict{String, Any}("server"=>"192.168.1.1", "ports"=>[8001, 8001… +``` + +To parse a file, use [`TOML.parsefile`](@ref). If the file has a syntax error, +an exception is thrown: + +```jldoctest +julia> using TOML + +julia> TOML.parse(""" + value = 0.0.0 + """) +ERROR: TOML Parser error: +none:1:16 error: failed to parse value + value = 0.0.0 + ^ +[...] +``` + +There are other versions of the parse functions ([`TOML.tryparse`](@ref) +and [`TOML.tryparsefile`]) that instead of throwing exceptions on parser error +returns a [`TOML.ParserError`](@ref) with information: + +```jldoctest +julia> using TOML + +julia> err = TOML.tryparse(""" + value = 0.0.0 + """); + +julia> err.type +ErrGenericValueError::ErrorType = 14 + +julia> err.line +1 + +julia> err.column +16 +``` + + +## Exporting data to TOML file + +The [`TOML.print`](@ref) function is used to print (or serialize) data into TOML +format. + +```jldoctest +julia> using TOML + +julia> data = Dict( + "names" => ["Julia", "Julio"], + "age" => [10, 20], + ); + +julia> TOML.print(data) +names = ["Julia", "Julio"] +age = [10, 20] + +julia> fname = tempname(); + +julia> open(fname, "w") do io + TOML.print(io, data) + end + +julia> TOML.parsefile(fname) +Dict{String, Any} with 2 entries: + "names" => ["Julia", "Julio"] + "age" => [10, 20] +``` + +Keys can be sorted according to some value + +```jldoctest +julia> using TOML + +julia> TOML.print(Dict( + "abc" => 1, + "ab" => 2, + "abcd" => 3, + ); sorted=true, by=length) +ab = 2 +abc = 1 +abcd = 3 +``` + +For custom structs, pass a function that converts the struct to a supported +type + +```jldoctest +julia> using TOML + +julia> struct MyStruct + a::Int + b::String + end + +julia> TOML.print(Dict("foo" => MyStruct(5, "bar"))) do x + x isa MyStruct && return [x.a, x.b] + error("unhandled type $(typeof(x))") + end +foo = [5, "bar"] +``` + + +## References +```@docs +TOML.parse +TOML.parsefile +TOML.tryparse +TOML.tryparsefile +TOML.print +TOML.Parser +TOML.ParserError +```

dS;(?7L&X=8RiB2w!I0JT| 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"%b!Xoc&BDtnzaLXYu-BQyP|b;*6PFAwxZb4}IF5 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�$@Z)2`n#R;4Y0Ywxqb8YrTKnM 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