diff --git a/Make.inc b/Make.inc index 811bb3768bb8a..fbb02f99706b0 100644 --- a/Make.inc +++ b/Make.inc @@ -742,23 +742,21 @@ else endif endef -ifeq ($(BUILD_OS), WINNT) +ifeq ($(BUILD_OS), WINNT) # MSYS spawn = $(1) -else ifneq (,$(findstring CYGWIN,$(BUILD_OS))) +cygpath_w = $(1) +else ifneq (,$(findstring CYGWIN,$(BUILD_OS))) # Cygwin spawn = $(1) +cygpath_w = `cygpath -w $(1)` else -ifeq ($(OS), WINNT) +ifeq ($(OS), WINNT) # unix-to-Windows cross-compile spawn = wine $(1) -else +cygpath_w = `winepath -w $(1)` +else # not Windows spawn = $(1) -endif -endif - -ifneq (,$(findstring CYGWIN,$(BUILD_OS))) -cygpath_w = `cygpath -w $(1)` -else cygpath_w = $(1) endif +endif exec = $(shell $(call spawn,$(1))) diff --git a/Makefile b/Makefile index 7572f022f8db7..af0cb2b6781bd 100644 --- a/Makefile +++ b/Makefile @@ -284,7 +284,7 @@ endif # Overwrite JL_SYSTEM_IMAGE_PATH in julia binaries: for julia in $(DESTDIR)$(bindir)/julia* ; do \ - $(build_bindir)/stringreplace $$(strings -t x - $$julia | grep "sys.ji$$" | awk '{print $$1;}' ) "$(private_libdir_rel)/sys.ji" 256 $(call cygpath_w,$$julia); \ + $(call spawn,$(build_bindir)/stringreplace $$(strings -t x - $$julia | grep "sys.ji$$" | awk '{print $$1;}' ) "$(private_libdir_rel)/sys.ji" 256 $(call cygpath_w,$$julia)); \ done mkdir -p $(DESTDIR)$(sysconfdir) diff --git a/NEWS.md b/NEWS.md index a020998060285..6771ab661ceb0 100644 --- a/NEWS.md +++ b/NEWS.md @@ -9,11 +9,21 @@ New language features Library improvements -------------------- - * Added generic Cholesky factorization + * New `Dates` module for calendar dates and other time-interval calculations ([#7654]). - * Cholesky factorization is now parametrized on matrix type + * Added generic Cholesky factorization, and the Cholesky factorization is now parametrized on the matrix type ([#7236]). - * Symmetric and Hermitian immutables are now parametrized on matrix type + * Symmetric and Hermitian immutables are now parametrized on matrix type ([#7992]). + + * Switch from `O(N)` to `O(logN)` algorithm for `dequeue!(pq, key)` + with PriorityQueues. This provides major speedups for large + queues. + + * PriorityQueues now include the order type among their parameters, + `PriorityQueue{KeyType,ValueType,OrderType}`. An empty queue can + be constructed as `pq = PriorityQueue(KeyType,ValueType)`, if you + intend to use the default `Forward` order, or + `pq = PriorityQueue(KeyType, ValueType, OrderType)` otherwise. Julia v0.3.0 Release Notes ========================== @@ -924,6 +934,7 @@ Too numerous to mention. [#7125]: https://github.com/JuliaLang/julia/issues/7125 [#7131]: https://github.com/JuliaLang/julia/issues/7131 [#7146]: https://github.com/JuliaLang/julia/issues/7146 +[#7236]: https://github.com/JuliaLang/julia/issues/7236 [#7242]: https://github.com/JuliaLang/julia/issues/7242 [#7359]: https://github.com/JuliaLang/julia/issues/7359 [#7365]: https://github.com/JuliaLang/julia/issues/7365 @@ -933,3 +944,6 @@ Too numerous to mention. [#7464]: https://github.com/JuliaLang/julia/issues/7464 [#7513]: https://github.com/JuliaLang/julia/issues/7513 [#7647]: https://github.com/JuliaLang/julia/issues/7647 +[#7654]: https://github.com/JuliaLang/julia/issues/7654 +[#7917]: https://github.com/JuliaLang/julia/issues/7917 +[#7992]: https://github.com/JuliaLang/julia/issues/7992 diff --git a/base/REPL.jl b/base/REPL.jl index fd1e0cbbb98cb..4a4f7a9085a98 100644 --- a/base/REPL.jl +++ b/base/REPL.jl @@ -276,20 +276,23 @@ bytestring_beforecursor(buf::IOBuffer) = bytestring(pointer(buf.data), buf.ptr-1 function complete_line(c::REPLCompletionProvider, s) partial = bytestring_beforecursor(s.input_buffer) - ret, range, should_complete = completions(partial, endof(partial)) + full = LineEdit.input_string(s) + ret, range, should_complete = completions(full, endof(partial)) return ret, partial[range], should_complete end function complete_line(c::ShellCompletionProvider, s) # First parse everything up to the current position partial = bytestring_beforecursor(s.input_buffer) - ret, range, should_complete = shell_completions(partial, endof(partial)) + full = LineEdit.input_string(s) + ret, range, should_complete = shell_completions(full, endof(partial)) return ret, partial[range], should_complete end function complete_line(c::LatexCompletions, s) partial = bytestring_beforecursor(LineEdit.buffer(s)) - ret, range, should_complete = latex_completions(partial, endof(partial))[2] + full = LineEdit.input_string(s) + ret, range, should_complete = latex_completions(full, endof(partial))[2] return ret, partial[range], should_complete end diff --git a/base/REPLCompletions.jl b/base/REPLCompletions.jl index 5d1b6c9053c40..8c519384db80f 100644 --- a/base/REPLCompletions.jl +++ b/base/REPLCompletions.jl @@ -107,23 +107,27 @@ function complete_keyword(s::ByteString) sorted_keywords[r] end -function complete_path(path::ByteString) - matches = ByteString[] +function complete_path(path::String, pos) dir, prefix = splitdir(path) - if length(dir) == 0 - files = readdir() - elseif isdir(dir) - files = readdir(dir) - else - return matches + local files + try + if length(dir) == 0 + files = readdir() + elseif isdir(dir) + files = readdir(dir) + else + return UTF8String[], 0:-1, false + end + catch + return UTF8String[], 0:-1, false end + matches = UTF8String[] for file in files if beginswith(file, prefix) - p = joinpath(dir, file) - push!(matches, isdir(p) ? joinpath(p,"") : p) + push!(matches, isdir(joinpath(dir, file)) ? joinpath(file,"") : file) end end - matches + matches, (nextind(path, pos-sizeof(prefix))):pos, length(matches) > 0 end function complete_methods(input::String) @@ -176,18 +180,23 @@ function latex_completions(string, pos) end function completions(string, pos) - inc_tag = Base.incomplete_tag(parse(string[1:pos], raise=false)) + # First parse everything up to the current position + partial = string[1:pos] + inc_tag = Base.incomplete_tag(parse(partial , raise=false)) if inc_tag in [:cmd, :string] - startpos = nextind(string, rsearch(string, non_filename_chars, pos)) + startpos = nextind(partial, rsearch(partial, non_filename_chars, pos)) r = startpos:pos - paths = complete_path(string[r]) - if inc_tag == :string && length(paths) == 1 && !isdir(paths[1]) + paths, r, success = complete_path(string[r], pos) + if inc_tag == :string && + length(paths) == 1 && # Only close if there's a single choice, + !isdir(string[startpos:start(r)-1] * paths[1]) && # except if it's a directory + (length(string) <= pos || string[pos+1] != '"') # or there's already a " at the cursor. paths[1] *= "\"" end - return sort(paths), r, true + return sort(paths), r, success end - ok, ret = latex_completions(string,pos) + ok, ret = latex_completions(string, pos) ok && return ret if inc_tag == :other && string[pos] == '(' @@ -230,7 +239,7 @@ function completions(string, pos) return sort(unique(suggestions)), (dotpos+1):pos, true end -function shell_completions(string,pos) +function shell_completions(string, pos) # First parse everything up to the current position scs = string[1:pos] local args, last_parse @@ -239,34 +248,12 @@ function shell_completions(string,pos) catch return UTF8String[], 0:-1, false end - # Now look at the last this we parsed + # Now look at the last thing we parsed isempty(args.args[end].args) && return UTF8String[], 0:-1, false arg = args.args[end].args[end] if isa(arg,String) # Treat this as a path (perhaps give a list of comands in the future as well?) - dir,name = splitdir(arg) - local files - try - if isempty(dir) - files = readdir() - else - isdir(dir) || return UTF8String[], 0:-1, false - files = readdir(dir) - end - catch - return UTF8String[], 0:-1, false - end - # Filter out files and directories that do not begin with the partial name we were - # completing and append "/" to directories to simplify further completion - ret = map(filter(x->beginswith(x, name), files)) do x - if !isdir(joinpath(dir, x)) - return x - else - return x*"/" - end - end - r = (nextind(string, pos-sizeof(name))):pos - return ret, r, true + return complete_path(arg, pos) elseif isexpr(arg, :escape) && (isexpr(arg.args[1], :incomplete) || isexpr(arg.args[1], :error)) r = first(last_parse):prevind(last_parse, last(last_parse)) partial = scs[r] diff --git a/base/collections.jl b/base/collections.jl index ab7428feb9427..c1e601e4c270d 100644 --- a/base/collections.jl +++ b/base/collections.jl @@ -1,10 +1,11 @@ module Collections -import Base: setindex!, done, get, haskey, isempty, length, next, getindex, start +import Base: setindex!, done, get, hash, haskey, isempty, length, next, getindex, start import ..Order: Forward, Ordering, lt export + Pair, PriorityQueue, dequeue!, enqueue!, @@ -106,37 +107,48 @@ end # PriorityQueue # ------------- +immutable Pair{A,B} + a::A + b::B +end + +function hash(p::Pair, h::Uint) + h = hash(p.a, h) + hash(p.b, h) +end +hash(p::Pair) = hash(p, zero(Uint)) + # A PriorityQueue that acts like a Dict, mapping values to their priorities, # with the addition of a dequeue! function to remove the lowest priority # element. -type PriorityQueue{K,V} <: Associative{K,V} +type PriorityQueue{K,V,O<:Ordering} <: Associative{K,V} # Binary heap of (element, priority) pairs. - xs::Array{(K, V), 1} - o::Ordering + xs::Array{Pair{K,V}, 1} + o::O # Map elements to their index in xs index::Dict{K, Int} - function PriorityQueue(o::Ordering) - new(Array((K, V), 0), o, Dict{K, Int}()) + function PriorityQueue(o::O) + new(Array(Pair{K,V}, 0), o, Dict{K, Int}()) end - PriorityQueue() = PriorityQueue{K,V}(Forward) + PriorityQueue() = PriorityQueue{K,V,O}(Forward) function PriorityQueue(ks::AbstractArray{K}, vs::AbstractArray{V}, - o::Ordering) + o::O) # TODO: maybe deprecate if length(ks) != length(vs) error("key and value arrays must have equal lengths") end - PriorityQueue{K,V}(zip(ks, vs), o) + PriorityQueue{K,V,O}(zip(ks, vs), o) end - function PriorityQueue(itr, o::Ordering) - xs = Array((K, V), length(itr)) + function PriorityQueue(itr, o::O) + xs = Array(Pair{K,V}, length(itr)) index = Dict{K, Int}() for (i, (k, v)) in enumerate(itr) - xs[i] = (k, v) + xs[i] = Pair{K,V}(k, v) if haskey(index, k) error("PriorityQueue keys must be unique") end @@ -153,36 +165,37 @@ type PriorityQueue{K,V} <: Associative{K,V} end end -PriorityQueue(o::Ordering=Forward) = PriorityQueue{Any,Any}(o) +PriorityQueue(o::Ordering=Forward) = PriorityQueue{Any,Any,typeof(o)}(o) +PriorityQueue{K,V}(::Type{K}, ::Type{V}, o::Ordering=Forward) = PriorityQueue{K,V,typeof(o)}(o) # TODO: maybe deprecate PriorityQueue{K,V}(ks::AbstractArray{K}, vs::AbstractArray{V}, - o::Ordering=Forward) = PriorityQueue{K,V}(ks, vs, o) + o::Ordering=Forward) = PriorityQueue{K,V,typeof(o)}(ks, vs, o) -PriorityQueue{K,V}(kvs::Associative{K,V}, o::Ordering=Forward) = PriorityQueue{K,V}(kvs, o) +PriorityQueue{K,V}(kvs::Associative{K,V}, o::Ordering=Forward) = PriorityQueue{K,V,typeof(o)}(kvs, o) -PriorityQueue{K,V}(a::AbstractArray{(K,V)}, o::Ordering=Forward) = PriorityQueue{K,V}(a, o) +PriorityQueue{K,V}(a::AbstractArray{(K,V)}, o::Ordering=Forward) = PriorityQueue{K,V,typeof(o)}(a, o) length(pq::PriorityQueue) = length(pq.xs) isempty(pq::PriorityQueue) = isempty(pq.xs) haskey(pq::PriorityQueue, key) = haskey(pq.index, key) -peek(pq::PriorityQueue) = pq.xs[1] +peek(pq::PriorityQueue) = (kv = pq.xs[1]; (kv.a, kv.b)) function percolate_down!(pq::PriorityQueue, i::Integer) x = pq.xs[i] @inbounds while (l = heapleft(i)) <= length(pq) r = heapright(i) - j = r > length(pq) || lt(pq.o, pq.xs[l][2], pq.xs[r][2]) ? l : r - if lt(pq.o, pq.xs[j][2], x[2]) - pq.index[pq.xs[j][1]] = i + j = r > length(pq) || lt(pq.o, pq.xs[l].b, pq.xs[r].b) ? l : r + if lt(pq.o, pq.xs[j].b, x.b) + pq.index[pq.xs[j].a] = i pq.xs[i] = pq.xs[j] i = j else break end end - pq.index[x[1]] = i + pq.index[x.a] = i pq.xs[i] = x end @@ -191,27 +204,39 @@ function percolate_up!(pq::PriorityQueue, i::Integer) x = pq.xs[i] @inbounds while i > 1 j = heapparent(i) - if lt(pq.o, x[2], pq.xs[j][2]) - pq.index[pq.xs[j][1]] = i + if lt(pq.o, x.b, pq.xs[j].b) + pq.index[pq.xs[j].a] = i pq.xs[i] = pq.xs[j] i = j else break end end - pq.index[x[1]] = i + pq.index[x.a] = i pq.xs[i] = x end +# Equivalent to percolate_up! with an element having lower priority than any other +function force_up!(pq::PriorityQueue, i::Integer) + x = pq.xs[i] + @inbounds while i > 1 + j = heapparent(i) + pq.index[pq.xs[j].a] = i + pq.xs[i] = pq.xs[j] + i = j + end + pq.index[x.a] = i + pq.xs[i] = x +end function getindex{K,V}(pq::PriorityQueue{K,V}, key) - pq.xs[pq.index[key]][2] + pq.xs[pq.index[key]].b end function get{K,V}(pq::PriorityQueue{K,V}, key, deflt) i = get(pq.index, key, 0) - i == 0 ? deflt : pq.xs[i][2] + i == 0 ? deflt : pq.xs[i].b end @@ -219,8 +244,8 @@ end function setindex!{K,V}(pq::PriorityQueue{K, V}, value, key) if haskey(pq, key) i = pq.index[key] - _, oldvalue = pq.xs[i] - pq.xs[i] = (key, value) + oldvalue = pq.xs[i].b + pq.xs[i] = Pair{K,V}(key, value) if lt(pq.o, oldvalue, value) percolate_down!(pq, i) else @@ -229,6 +254,7 @@ function setindex!{K,V}(pq::PriorityQueue{K, V}, value, key) else enqueue!(pq, key, value) end + value end @@ -237,7 +263,7 @@ function enqueue!{K,V}(pq::PriorityQueue{K,V}, key, value) error("PriorityQueue keys must be unique") end - push!(pq.xs, (key, value)) + push!(pq.xs, Pair{K,V}(key, value)) pq.index[key] = length(pq) percolate_up!(pq, length(pq)) pq @@ -249,19 +275,17 @@ function dequeue!(pq::PriorityQueue) y = pop!(pq.xs) if !isempty(pq) pq.xs[1] = y - pq.index[pq.xs[1][1]] = 1 + pq.index[y.a] = 1 percolate_down!(pq, 1) end - delete!(pq.index, x[1]) - x[1] + delete!(pq.index, x.a) + x.a end function dequeue!(pq::PriorityQueue, key) - idx = pop!(pq.index, key) # throws key error if missing - deleteat!(pq.xs, idx) - for (k,v) in pq.index - (v >= idx) && (pq.index[k] = (v-1)) - end + idx = pq.index[key] + force_up!(pq, idx) + dequeue!(pq) key end @@ -273,7 +297,7 @@ done(pq::PriorityQueue, i) = done(pq.index, i) function next(pq::PriorityQueue, i) (k, idx), i = next(pq.index, i) - return ((k, pq.xs[idx][2]), i) + return ((k, pq.xs[idx].b), i) end diff --git a/base/dates/io.jl b/base/dates/io.jl index 1c5081379bf31..6553f76bab80b 100644 --- a/base/dates/io.jl +++ b/base/dates/io.jl @@ -32,7 +32,7 @@ const MONTHTOVALUE = (UTF8String=>Dict{UTF8String,Int})["english"=>english] const MONTHTOVALUEABBR = (UTF8String=>Dict{UTF8String,Int})["english"=>abbrenglish] # Date/DateTime Parsing -abstract Slot{P<:AbstractTime} <: AbstractTime +abstract Slot{P<:AbstractTime} immutable DelimitedSlot{P<:AbstractTime} <: Slot{P} i::Int diff --git a/base/dates/periods.jl b/base/dates/periods.jl index 2fed874c84f49..72a689c4e1224 100644 --- a/base/dates/periods.jl +++ b/base/dates/periods.jl @@ -14,7 +14,7 @@ for p in (:Year,:Month,:Week,:Day,:Hour,:Minute,:Second,:Millisecond) # periodisless @eval periodisless(x::$p,y::$p) = value(x) < value(y) # String parsing (mainly for IO code) - @eval $p(x::String) = $p(parseint(x)) + @eval $p(x::String) = $p(parseint(Int64,x)) # Period accessors @eval $p(x::TimeType) = $p($(symbol(lowercase(string(p))))(x)) end @@ -68,7 +68,7 @@ let vec_ops = [:.+,:.-,:.*,:.%,:div] end # intfuncs -Base.gcdx{T<:Period}(a::T,b::T) = ((g,x,y)=gcdx(Dates.value(a),Dates.value(b)); return T(g),x,y) +Base.gcdx{T<:Period}(a::T,b::T) = ((g,x,y)=gcdx(value(a),value(b)); return T(g),x,y) Base.abs{T<:Period}(a::T) = T(abs(value(a))) periodisless(::Period,::Year) = true diff --git a/base/dates/ranges.jl b/base/dates/ranges.jl index 161de7ff502b0..932c1c3f5d86b 100644 --- a/base/dates/ranges.jl +++ b/base/dates/ranges.jl @@ -4,8 +4,8 @@ Base.colon{T<:DateTime}(start::T, stop::T) = StepRange(start, Day(1), stop) # Given a start and end date, how many steps/periods are in between -guess(a::DateTime,b::DateTime,c) = ifloor((int128(b) - int128(a))/toms(c)) -guess(a::Date,b::Date,c) = int(div(int(b - a),days(c))) +guess(a::DateTime,b::DateTime,c) = ifloor(Int64,(int128(b) - int128(a))/toms(c)) +guess(a::Date,b::Date,c) = int64(div(int64(b - a),days(c))) function len(a,b,c) lo, hi, st = min(a,b), max(a,b), abs(c) i = guess(a,b,c)-1 diff --git a/base/linalg/lapack.jl b/base/linalg/lapack.jl index 18d145d35485f..248a0a7e6ead0 100644 --- a/base/linalg/lapack.jl +++ b/base/linalg/lapack.jl @@ -2843,7 +2843,13 @@ for (syev, syevr, sygvd, elty) in # DOUBLE PRECISION A( LDA, * ), W( * ), WORK( * ), Z( LDZ, * ) function syevr!(jobz::BlasChar, range::BlasChar, uplo::BlasChar, A::StridedMatrix{$elty}, vl::FloatingPoint, vu::FloatingPoint, il::Integer, iu::Integer, abstol::FloatingPoint) chkstride1(A) - n = chksquare(A) + n = chksquare(A) + if range == 'I' + 1 <= il <= iu <= n || throw(ArgumentError("illegal choice of eigenvalue indices")) + end + if range == 'V' + vl < vu || throw(ArgumentError("lower boundary must be less than upper boundary")) + end lda = max(1,stride(A,2)) m = Array(BlasInt, 1) w = similar(A, $elty, n) @@ -2979,6 +2985,12 @@ for (syev, syevr, sygvd, elty, relty) in function syevr!(jobz::BlasChar, range::BlasChar, uplo::BlasChar, A::StridedMatrix{$elty}, vl::FloatingPoint, vu::FloatingPoint, il::Integer, iu::Integer, abstol::FloatingPoint) chkstride1(A) n = chksquare(A) + if range == 'I' + 1 <= il <= iu <= n || throw(ArgumentError("illegal choice of eigenvalue indices")) + end + if range == 'V' + vl < vu || throw(ArgumentError("lower boundary must be less than upper boundary")) + end lda = max(1,stride(A,2)) m = Array(BlasInt, 1) w = similar(A, $relty, n) diff --git a/base/pkg/entry.jl b/base/pkg/entry.jl index 041a42f4890fa..b8acb271f1682 100644 --- a/base/pkg/entry.jl +++ b/base/pkg/entry.jl @@ -153,9 +153,11 @@ function clone(url::String, pkg::String) Base.rm(pkg, recursive=true) rethrow() end - isempty(Reqs.parse("$pkg/REQUIRE")) && return info("Computing changes...") - resolve() + if !edit(Reqs.add, pkg) + isempty(Reqs.parse("$pkg/REQUIRE")) && return + resolve() + end end function clone(url_or_pkg::String) diff --git a/base/range.jl b/base/range.jl index 12ff8c5b1b584..85ed100b3dded 100644 --- a/base/range.jl +++ b/base/range.jl @@ -164,6 +164,7 @@ linrange(a::Real, b::Real, len::Integer) = ## interface implementations +similar(r::Range, T::Type, dims::(Integer...)) = Array(T, dims...) similar(r::Range, T::Type, dims::Dims) = Array(T, dims) size(r::Range) = (length(r),) diff --git a/contrib/julia-mode.el b/contrib/julia-mode.el index 67f51b3297232..82c1d08dfca5e 100644 --- a/contrib/julia-mode.el +++ b/contrib/julia-mode.el @@ -105,10 +105,24 @@ ].* \\(in\\)\\(\\s-\\|$\\)+") (defconst julia-function-regex - (rx symbol-start "function" (1+ space) (group (1+ (or word ?_ ?!))))) + (rx symbol-start "function" + (1+ space) + ;; Don't highlight module names in function declarations: + (* (seq (1+ (or word ?_)) ".")) + ;; The function name itself + (group (1+ (or word ?_ ?!))))) (defconst julia-type-regex - (rx symbol-start "type" (1+ space) (group (1+ (or word ?_))))) + (rx symbol-start (or "immutable" "type" "abstract") (1+ space) (group (1+ (or word ?_))))) + +(defconst julia-type-annotation-regex + (rx "::" (group (1+ (or word ?_))))) + +(defconst julia-type-parameter-regex + (rx symbol-start (1+ (or word ?_)) "{" (group (1+ (or word ?_))) "}")) + +(defconst julia-subtype-regex + (rx "<:" (1+ space) (group (1+ (or word ?_))) (0+ space) (or "\n" "{" "end"))) (defconst julia-macro-regex "@\\w+") @@ -118,8 +132,14 @@ '("if" "else" "elseif" "while" "for" "begin" "end" "quote" "try" "catch" "return" "local" "abstract" "function" "macro" "ccall" "finally" "typealias" "break" "continue" "type" "global" - "module" "using" "import" "export" "const" "let" "bitstype" "do" - "baremodule" "importall" "immutable"))) + "module" "using" "import" "export" "const" "let" "bitstype" "do" "in" + "baremodule" "importall" "immutable") + 'symbols)) + +(defconst julia-builtin-regex + (regexp-opt + '("error" "throw") + 'symbols)) (defconst julia-font-lock-keywords (list @@ -129,13 +149,18 @@ (cons julia-macro-regex 'font-lock-keyword-face) (cons (regexp-opt - '("true" "false" "C_NULL" "Inf" "NaN" "Inf32" "NaN32" "nothing")) + '("true" "false" "C_NULL" "Inf" "NaN" "Inf32" "NaN32" "nothing") + 'symbols) 'font-lock-constant-face) (list julia-unquote-regex 2 'font-lock-constant-face) (list julia-char-regex 2 'font-lock-string-face) (list julia-forloop-in-regex 1 'font-lock-keyword-face) (list julia-function-regex 1 'font-lock-function-name-face) (list julia-type-regex 1 'font-lock-type-face) + (list julia-type-annotation-regex 1 'font-lock-type-face) + (list julia-type-parameter-regex 1 'font-lock-type-face) + (list julia-subtype-regex 1 'font-lock-type-face) + (list julia-builtin-regex 1 'font-lock-builtin-face) )) (defconst julia-block-start-keywords @@ -618,9 +643,14 @@ Do not move back beyond MIN." (puthash "\\textperthousand" "‰" julia-latexsubs) (puthash "\\textpertenthousand" "‱" julia-latexsubs) (puthash "\\prime" "′" julia-latexsubs) +(puthash "\\pprime" "″" julia-latexsubs) +(puthash "\\ppprime" "‴" julia-latexsubs) (puthash "\\backprime" "‵" julia-latexsubs) +(puthash "\\backpprime" "‶" julia-latexsubs) +(puthash "\\backppprime" "‷" julia-latexsubs) (puthash "\\guilsinglleft" "‹" julia-latexsubs) (puthash "\\guilsinglright" "›" julia-latexsubs) +(puthash "\\pppprime" "⁗" julia-latexsubs) (puthash "\\nolinebreak" "\u2060" julia-latexsubs) (puthash "\\^0" "⁰" julia-latexsubs) (puthash "\\^i" "ⁱ" julia-latexsubs) diff --git a/deps/Makefile b/deps/Makefile index a8c15cac3200d..16ecd202f604c 100644 --- a/deps/Makefile +++ b/deps/Makefile @@ -43,7 +43,7 @@ endif endif ifeq ($(OS), Linux) -ifeq ($(shell which patchelf),) +ifeq ($(shell which patchelf 2>/dev/null),) STAGE1_DEPS += patchelf PATCHELF=$(build_bindir)/patchelf else diff --git a/doc/manual/arrays.rst b/doc/manual/arrays.rst index f0e8a007a5923..e1d148d0dd14c 100644 --- a/doc/manual/arrays.rst +++ b/doc/manual/arrays.rst @@ -139,6 +139,8 @@ Expression Yields Note that this form does not do any concatenation; each argument becomes an element of the resulting array. +.. _comprehensions: + Comprehensions -------------- diff --git a/doc/manual/conversion-and-promotion.rst b/doc/manual/conversion-and-promotion.rst index 0676d96033c12..402c6171126c6 100644 --- a/doc/manual/conversion-and-promotion.rst +++ b/doc/manual/conversion-and-promotion.rst @@ -164,10 +164,10 @@ conversions declared in `rational.jl `_, right after the declaration of the type and its constructors:: - convert{T<:Int}(::Type{Rational{T}}, x::Rational) = Rational(convert(T,x.num),convert(T,x.den)) - convert{T<:Int}(::Type{Rational{T}}, x::Int) = Rational(convert(T,x), convert(T,1)) + convert{T<:Integer}(::Type{Rational{T}}, x::Rational) = Rational(convert(T,x.num),convert(T,x.den)) + convert{T<:Integer}(::Type{Rational{T}}, x::Integer) = Rational(convert(T,x), convert(T,1)) - function convert{T<:Int}(::Type{Rational{T}}, x::FloatingPoint, tol::Real) + function convert{T<:Integer}(::Type{Rational{T}}, x::FloatingPoint, tol::Real) if isnan(x); return zero(T)//zero(T); end if isinf(x); return sign(x)//zero(T); end y = x @@ -182,10 +182,10 @@ right after the declaration of the type and its constructors:: y = 1/y end end - convert{T<:Int}(rt::Type{Rational{T}}, x::FloatingPoint) = convert(rt,x,eps(x)) + convert{T<:Integer}(rt::Type{Rational{T}}, x::FloatingPoint) = convert(rt,x,eps(x)) convert{T<:FloatingPoint}(::Type{T}, x::Rational) = convert(T,x.num)/convert(T,x.den) - convert{T<:Int}(::Type{T}, x::Rational) = div(convert(T,x.num),convert(T,x.den)) + convert{T<:Integer}(::Type{T}, x::Rational) = div(convert(T,x.num),convert(T,x.den)) The initial four convert methods provide conversions to rational types. The first method converts one type of rational to another type of @@ -359,10 +359,10 @@ Finally, we finish off our ongoing case study of Julia's rational number type, which makes relatively sophisticated use of the promotion mechanism with the following promotion rules:: - promote_rule{T<:Int}(::Type{Rational{T}}, ::Type{T}) = Rational{T} - promote_rule{T<:Int,S<:Int}(::Type{Rational{T}}, ::Type{S}) = Rational{promote_type(T,S)} - promote_rule{T<:Int,S<:Int}(::Type{Rational{T}}, ::Type{Rational{S}}) = Rational{promote_type(T,S)} - promote_rule{T<:Int,S<:FloatingPoint}(::Type{Rational{T}}, ::Type{S}) = promote_type(T,S) + promote_rule{T<:Integer}(::Type{Rational{T}}, ::Type{T}) = Rational{T} + promote_rule{T<:Integer,S<:Integer}(::Type{Rational{T}}, ::Type{S}) = Rational{promote_type(T,S)} + promote_rule{T<:Integer,S<:Integer}(::Type{Rational{T}}, ::Type{Rational{S}}) = Rational{promote_type(T,S)} + promote_rule{T<:Integer,S<:FloatingPoint}(::Type{Rational{T}}, ::Type{S}) = promote_type(T,S) The first rule asserts that promotion of a rational number with its own numerator/denominator type, simply promotes to itself. The second rule diff --git a/doc/manual/dates.rst b/doc/manual/dates.rst index b74378713b95a..c502f9c2d2957 100644 --- a/doc/manual/dates.rst +++ b/doc/manual/dates.rst @@ -6,7 +6,7 @@ The ``Dates`` module provides two types for working with dates: ``Date`` and ``DateTime``, representing day and millisecond precision, respectively; both are subtypes of the abstract ``TimeType``. 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`` 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`` and ``DateTime`` are basically immutable ``Int64`` 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`` type is *timezone-unaware* (in Python parlance) or is analogous to a *LocalDateTime* in Java 8. Additional time zone functionality can be added through the `Timezones.jl package `_, which compiles the `Olsen Time Zone Database `_. Both ``Date`` and ``DateTime`` are based on the 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 0 exists. The ISO standard, however, states that 1 BC/BCE is year 0, so ``0000-12-31`` is the day before ``0001-01-01``, and year ``-0001`` (yes, negative 1 for the year) is 2 BC/BCE, year ``-0002`` is 3 BC/BCE, etc. +Both ``Date`` and ``DateTime`` are basically immutable ``Int64`` 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`` type is *timezone-unaware* (in Python parlance) or is analogous to a *LocalDateTime* in Java 8. Additional time zone functionality can be added through the `Timezones.jl package `_, which compiles the `Olsen Time Zone Database `_. Both ``Date`` and ``DateTime`` are based on the 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`` and ``DateTime`` 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 `_ 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. @@ -56,14 +56,16 @@ Delimited slots are marked by specifying the delimiter the parser should expect Fixed-width slots are specified by repeating the period character the number of times corresponding to the width. 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. Just like the query functions ``dayname`` and ``monthname``, however, custom locales can be loaded in a similar fashion by passing in the ``locale=>Dict{UTF8String,Int}`` mapping to the ``Dates.MONTHTOVALUEABBR`` and ``Dates.MONTHTOVALUE`` dicts for abbreviated and full-name month names, respectively. +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`` and ``monthname``, custom locales can be loaded by passing in the ``locale=>Dict{UTF8String,Int}`` mapping to the ``Dates.MONTHTOVALUEABBR`` and ``Dates.MONTHTOVALUE`` dicts for abbreviated and full-name month names, respectively. -A full suite of parsing and formatting tests and examples is available in ``tests/dates``. +A full suite of parsing and formatting tests and examples is available in `tests/dates/io.jl `_. Durations/Comparisons --------------------- -Finding the length of time between two ``Date`` or ``DateTime`` is straightforward given their underlying representation as ``UTInstant{Day}`` and ``UTInstant{Millisecond}``, respectively. The difference between ``Date`` is returned in the number of ``Day``, and ``DateTime`` in the number of ``Millisecond``. Similarly, comparing ``TimeType`` is a simple matter of comparing the underlying machine instants (which in turn compares the internal ``Int64`` values).:: +Finding the length of time between two ``Date`` or ``DateTime`` is straightforward given their underlying representation as ``UTInstant{Day}`` and ``UTInstant{Millisecond}``, respectively. The difference between ``Date`` is returned in the number of ``Day``, and ``DateTime`` in the number of ``Millisecond``. Similarly, comparing ``TimeType`` is a simple matter of comparing the underlying machine instants (which in turn compares the internal ``Int64`` values). + +:: julia> dt = Date(2012,2,29) 2012-02-29 @@ -192,7 +194,7 @@ Month of the year:: julia> Dates.daysinmonth(t) 31 -As well as informationa about the ``TimeType``'s year and quarter:: +As well as information about the ``TimeType``'s year and quarter:: julia> Dates.isleapyear(t) false @@ -233,7 +235,7 @@ Now just imagine that instead of 7-7-7, the slots are Year-Month-Day, or in our 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:sup:`TM`:: +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:: julia> Date(2014,1,29) + Dates.Day(1) + Dates.Month(1) 2014-03-01 @@ -247,7 +249,7 @@ Tricky? Perhaps. What is an innocent ``Dates`` user to do? The bottom line is to 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. +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`` as input and return or *adjust to* the first or last of the desired period relative to the input. @@ -324,10 +326,13 @@ The final method in the adjuster API is the ``recur`` function. ``recur`` vector 2014-10-14 2014-11-11 +Additional examples and tests are availabe in `test/dates/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`` types are simple ``Int64`` wrappers and are constructed by wrapping any convertible to ``Int64`` type, i.e. ``Year(1)`` or ``Month(3.0)``. Arithmetic between ``Period`` of the same type behave like integers, and limited ``Period-Real`` arithmetic is available. +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`` types are simple ``Int64`` wrappers and are constructed by wrapping any ``Int64`` convertible type, i.e. ``Year(1)`` or ``Month(3.0)``. Arithmetic between ``Period`` of the same type behave like integers, and limited ``Period-Real`` arithmetic is available. :: julia> y1 = Dates.Year(1) @@ -361,4 +366,4 @@ Periods are a human view of discrete, sometimes irregular durations of time. Con 3 years -See also the API reference for the :mod:`Dates` module. +See the `API reference `_ for additional information on methods exported from the :mod:`Dates` module. diff --git a/doc/manual/faq.rst b/doc/manual/faq.rst index ffb4dc156742f..b074272a35fd3 100644 --- a/doc/manual/faq.rst +++ b/doc/manual/faq.rst @@ -213,14 +213,14 @@ overflow and promote results to bigger integer types such as ``Int128`` or ``BigInt`` in the case of overflow. Unfortunately, this introduces major overhead on every integer operation (think incrementing a loop counter) – it requires emitting code to perform run-time overflow checks after arithmetic -instructions and braches to handle potential overflows. Worse still, this +instructions and branches to handle potential overflows. Worse still, this would cause every computation involving integers to be type-unstable. As we mentioned above, `type-stability is crucial <#man-type-stable>`_ for effective generation of efficient code. If you can't count on the results of integer operations being integers, it's impossible to generate fast, simple code the way C and Fortran compilers do. -A variation on this approach, which avoids the appearance of type instabilty is to merge the ``Int`` and ``BigInt`` types into a single hybrid integer type, that internally changes representation when a result no longer fits into the size of a machine integer. While this superficially avoids type-instability at the level of Julia code, it just sweeps the problem under the rug by foisting all of the same difficulties onto the C code implementing this hybrid integer type. This approach *can* be made to work and can even be made quite fast in many cases, but has several drawbacks. One problem is that the in-memory representation of integers and arrays of integers no longer match the natural representation used by C, Fortran and other languages with native machine integers. Thus, to interoperate with those languages, we would ultimately need to introduce native integer types anyway. Any unbounded representation of integers cannot have a fixed number of bits, and thus cannot be stored inline in an array with fixed-size slots – large integer values will always require separate heap-allocated storage. And of course, no matter how clever a hybrid integer implementation one uses, there are always performance traps – situations where performance degrades unexpectedly. Complex representation, lack of interoperability with C and Fortran, the inability to represent integer arrays without additional heap storage, and unpredictable performance characteristics make even the cleverest hybrid integer implementations a poor choice for high-performance numerical work. +A variation on this approach, which avoids the appearance of type instability is to merge the ``Int`` and ``BigInt`` types into a single hybrid integer type, that internally changes representation when a result no longer fits into the size of a machine integer. While this superficially avoids type-instability at the level of Julia code, it just sweeps the problem under the rug by foisting all of the same difficulties onto the C code implementing this hybrid integer type. This approach *can* be made to work and can even be made quite fast in many cases, but has several drawbacks. One problem is that the in-memory representation of integers and arrays of integers no longer match the natural representation used by C, Fortran and other languages with native machine integers. Thus, to interoperate with those languages, we would ultimately need to introduce native integer types anyway. Any unbounded representation of integers cannot have a fixed number of bits, and thus cannot be stored inline in an array with fixed-size slots – large integer values will always require separate heap-allocated storage. And of course, no matter how clever a hybrid integer implementation one uses, there are always performance traps – situations where performance degrades unexpectedly. Complex representation, lack of interoperability with C and Fortran, the inability to represent integer arrays without additional heap storage, and unpredictable performance characteristics make even the cleverest hybrid integer implementations a poor choice for high-performance numerical work. An alternative to using hybrid integers or promoting to BigInts is to use saturating integer arithmetic, where adding to the largest integer value @@ -251,7 +251,7 @@ value. This is precisely what Matlab™ does:: -9223372036854775808 -At first blush, this seems reasonable enough since 9223372036854775807 is much closer to 9223372036854775808 than -9223372036854775808 is and integers are still represented with a fixed size in a natural way that is compatible with C and Fortran. Saturated integer arithmetic, however, is deeply problematic. The first and most obvious issue is that this is not the way machine integer arithmetic works, so implementing saturated operations requires emiting instructions after each machine integer operation to check for underflow or overflow and replace the result with ``typemin(Int)`` or ``typemax(Int)`` as appropriate. This alone expands each integer operation from a single, fast instruction into half a dozen instructions, probably including branches. Ouch. But it gets worse – saturating integer arithmetic isn't associative. Consider this Matlab computation:: +At first blush, this seems reasonable enough since 9223372036854775807 is much closer to 9223372036854775808 than -9223372036854775808 is and integers are still represented with a fixed size in a natural way that is compatible with C and Fortran. Saturated integer arithmetic, however, is deeply problematic. The first and most obvious issue is that this is not the way machine integer arithmetic works, so implementing saturated operations requires emitting instructions after each machine integer operation to check for underflow or overflow and replace the result with ``typemin(Int)`` or ``typemax(Int)`` as appropriate. This alone expands each integer operation from a single, fast instruction into half a dozen instructions, probably including branches. Ouch. But it gets worse – saturating integer arithmetic isn't associative. Consider this Matlab computation:: >> n = int64(2)^62 4611686018427387904 diff --git a/doc/manual/mathematical-operations.rst b/doc/manual/mathematical-operations.rst index 2ef2bdc5997c8..62971bbcac03e 100644 --- a/doc/manual/mathematical-operations.rst +++ b/doc/manual/mathematical-operations.rst @@ -270,6 +270,16 @@ 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. +The operator ``.<`` is intended for array objects; the operation +``A .< B`` is valid only if ``A`` and ``B`` have the same dimensions. The +operator returns an array with boolean entries and with the same dimensions +as ``A`` and ``B``. Such operators are called *elementwise*; Julia offers a +suite of elementwise operators: ``.*``, ``.+``, etc. Some of the elementwise +operators can take a scalar operand such as the example ``0 .< A .< 1`` in +the preceding paragraph. +This notation means that the scalar operand should be replicated for each entry of +the array. + Note the evaluation behavior of chained comparisons:: v(x) = (println(x); x) diff --git a/doc/manual/strings.rst b/doc/manual/strings.rst index ef304c8241736..440e29ab55dff 100644 --- a/doc/manual/strings.rst +++ b/doc/manual/strings.rst @@ -853,7 +853,7 @@ for ``v"0.2-rc2"``. It is good practice to use such special versions in comparisons (particularly, the trailing ``-`` should always be used on upper bounds unless there's a good reason not to), but they must not be used as the actual version number of -anything, as they are illegal in the semantic versioning scheme. +anything, as they are invalid in the semantic versioning scheme. Besides being used for the ``VERSION`` constant, ``VersionNumber`` objects are widely used in the ``Pkg`` module, to specify packages versions and their diff --git a/doc/manual/style-guide.rst b/doc/manual/style-guide.rst index a665476187d18..7425366c8a54e 100644 --- a/doc/manual/style-guide.rst +++ b/doc/manual/style-guide.rst @@ -143,11 +143,23 @@ In this case ``cell(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. -Avoid underscores in names --------------------------- - -If a function name requires multiple words, it might represent more than one -concept. It is better to keep identifier names concise. +Use naming conventions consistent with Julia's ``base/`` +-------------------------------------------------------- + +- modules and type names use capitalization and camel case: + ``module SparseMatrix``, ``immutable UnitRange``. +- functions are lowercase (``maximum``, ``convert``) and, + when readable, with multiple words squashed together (``isequal``, ``haskey``). + When necessary, use underscores as word separators. + Underscores are also used to indicate a combination of + concepts (``remotecall_fetch`` as a more efficient implementation + of ``remotecall(fetch(...))``) or as modifiers (``sum_kbn``). +- conciseness is valued, but avoid abbreviation + (``indexin`` rather than ``indxin``) as it becomes difficult to + remember whether and how particular words are abbreviated. + +If a function name requires multiple words, consider whether it might +represent more than one concept and might be better split into pieces. Don't overuse try-catch ----------------------- diff --git a/doc/manual/types.rst b/doc/manual/types.rst index 7407aba0774b9..a0a2dda0c6449 100644 --- a/doc/manual/types.rst +++ b/doc/manual/types.rst @@ -232,10 +232,41 @@ subtype of its right operand: julia> Integer <: FloatingPoint false -Since abstract types have no instantiations and serve as no more than -nodes in the type graph, there is not much more to say about them until -we introduce parametric abstract types later on in `Parametric -Types <#man-parametric-types>`_. +An important use of abstract types is to provide default implementations for +concrete types. To give a simple example, consider:: + + function myplus(x,y) + x+y + 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 :ref:`man-methods` for more +information on multiple dispatch.) + +Assuming no method more specific than the above is found, Julia next internally +defines and compiles a method called ``myplus`` specifically for two ``Int`` +arguments based on the generic function given above, i.e., it implicitly +defines and compiles:: + + function myplus(x::Int,y::Int) + x+y + end + +and finally, it invokes this specific method. + +Thus, abstract types allow programmers to write generic functions that can +later be used as the default method by many combinations of concrete types. +Thanks to multiple dispatch, the programmer has full control over whether the +default or more specific method is used. + +An important point to note is that there is no loss in performance if the +programmer relies on a function whose arguments are abstract types, because it +is recompiled for each tuple of argument concrete types with which it is +invoked. (There may be a performance issue, however, in the case of function +arguments that are containers of abstract types; see :ref:`man-performance-tips`.) + Bits Types ---------- @@ -459,6 +490,29 @@ would be considered identical, or if they might need to change independently over time. If they would be considered identical, the type should probably be immutable. +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. + + Declared Types -------------- @@ -1042,7 +1096,7 @@ This is accomplished via the following code in ``base/boot.jl``:: end Of course, this depends on what ``Int`` is aliased to — but that is -pre-defined to be the correct type — either ``Int32`` or ``Int64``. +predefined to be the correct type — either ``Int32`` or ``Int64``. For parametric types, ``typealias`` can be convenient for providing names for cases where some of the parameter choices are fixed. diff --git a/doc/manual/variables-and-scoping.rst b/doc/manual/variables-and-scoping.rst index 447de95614dbe..9efef7ef99f18 100644 --- a/doc/manual/variables-and-scoping.rst +++ b/doc/manual/variables-and-scoping.rst @@ -260,18 +260,18 @@ block without creating any new bindings: end 1 -The first example is illegal because you cannot declare the same -variable as local in the same scope twice. The second example is legal +The first example is invalid because you cannot declare the same +variable as local in the same scope twice. The second example is valid since the ``let`` introduces a new scope block, so the inner local ``x`` is a different variable than the outer local ``x``. For Loops and Comprehensions ---------------------------- -For loops and comprehensions have a special additional behavior: any -new variables introduced in their body scopes are freshly allocated for -each loop iteration. Therefore these constructs are similar to ``while`` -loops with ``let`` blocks inside:: +``for`` loops and :ref:`comprehensions ` have a special +additional behavior: any new variables introduced in their body scopes are +freshly allocated for each loop iteration. Therefore these constructs are +similar to ``while`` loops with ``let`` blocks inside:: Fs = cell(2) for i = 1:2 diff --git a/doc/stdlib/base.rst b/doc/stdlib/base.rst index 110dc2c415227..a6b00a57c379d 100644 --- a/doc/stdlib/base.rst +++ b/doc/stdlib/base.rst @@ -143,9 +143,10 @@ All Objects ----------- .. function:: is(x, y) -> Bool -.. function:: x ≡ y -> Bool + ===(x,y) -> Bool + ≡(x,y) -> Bool - Determine whether ``x`` and ``y`` are identical, in the sense that no program could distinguish them. Compares mutable objects by address in memory, and compares immutable objects (such as numbers) by contents at the bit level. This function is sometimes called ``egal``. The ``===`` operator is an alias for this function. + Determine whether ``x`` and ``y`` are identical, in the sense that no program could distinguish them. Compares mutable objects by address in memory, and compares immutable objects (such as numbers) by contents at the bit level. This function is sometimes called ``egal``. .. function:: isa(x, type) -> Bool @@ -589,11 +590,10 @@ Iterable Collections -------------------- .. function:: in(item, collection) -> Bool -.. function:: item in collection -> Bool -.. function:: item ∈ collection -> Bool -.. function:: collection ∋ item -> Bool -.. function:: item ∉ collection -> Bool -.. function:: collection ∌ item -> Bool + ∈(item,collection) -> Bool + ∋(collection,item) -> Bool + ∉(item,collection) -> Bool + ∌(collection,item) -> Bool Determine whether an item is in the given collection, in the sense that it is ``==`` to one of the values generated by iterating over the collection. @@ -912,9 +912,9 @@ Iterable Collections Return an array of type ``Array{element_type,1}`` of all items in a collection. .. function:: issubset(a, b) -.. function:: A ⊆ S -> Bool -.. function:: A ⊈ S -> Bool -.. function:: A ⊊ S -> Bool + ⊆(A,S) -> Bool + ⊈(A,S) -> Bool + ⊊(A,S) -> Bool Determine whether every element of ``a`` is also in ``b``, using the ``in`` function. @@ -1056,7 +1056,7 @@ Set-Like Collections Construct a sorted set of the integers generated by the given iterable object, or an empty set. Implemented as a bit string, and therefore designed for dense integer sets. Only non-negative integers can be stored. If the set will be sparse (for example holding a single very large integer), use ``Set`` instead. .. function:: union(s1,s2...) -.. function:: s1 ∪ s2 + ∪(s1,s2) Construct the union of two or more sets. Maintains order with arrays. @@ -1065,7 +1065,7 @@ Set-Like Collections Union each element of ``iterable`` into set ``s`` in-place. .. function:: intersect(s1,s2...) -.. function:: s1 ∩ s2 + ∩(s1,s2) Construct the intersection of two or more sets. Maintains order and multiplicity of the first argument for arrays and ranges. @@ -1109,9 +1109,9 @@ Set-Like Collections Intersects IntSets ``s1`` and ``s2`` and overwrites the set ``s1`` with the result. If needed, s1 will be expanded to the size of ``s2``. .. function:: issubset(A, S) -> Bool -.. function:: A ⊆ S -> Bool + ⊆(A,S) -> Bool - True if ``A ⊆ S`` (A is a subset of or equal to S) + True if A is a subset of or equal to S. Fully implemented by: ``IntSet``, ``Set``. @@ -2503,7 +2503,7 @@ Mathematical Operators Element-wise exponentiation operator. .. function:: div(a,b) -.. function:: a ÷ b + ÷(a,b) Compute a/b, truncating to an integer. @@ -2616,7 +2616,7 @@ Mathematical Operators .. _!=: .. function:: !=(x, y) -.. function:: x ≠ y + ≠(x,y) Not-equals comparison operator. Always gives the opposite answer as ``==``. New types should generally not implement this, and rely on the fallback @@ -2624,13 +2624,13 @@ Mathematical Operators .. _===: .. function:: ===(x, y) -.. function:: x ≡ y + ≡(x,y) See the :func:`is` operator .. _!==: .. function:: !==(x, y) -.. function:: x ≢ y + ≢(x,y) Equivalent to ``!is(x, y)`` @@ -2645,7 +2645,7 @@ Mathematical Operators .. _<=: .. function:: <=(x, y) -.. function:: x ≤ y + ≤(x,y) Less-than-or-equals comparison operator. @@ -2657,7 +2657,7 @@ Mathematical Operators .. _>=: .. function:: >=(x, y) -.. function:: x ≥ y + ≥(x,y) Greater-than-or-equals comparison operator. @@ -2668,7 +2668,7 @@ Mathematical Operators .. _.!=: .. function:: .!=(x, y) -.. function:: x .≠ y + .≠(x,y) Element-wise not-equals comparison operator. @@ -2679,7 +2679,7 @@ Mathematical Operators .. _.<=: .. function:: .<=(x, y) -.. function:: x .≤ y + .≤(x,y) Element-wise less-than-or-equals comparison operator. @@ -2690,7 +2690,7 @@ Mathematical Operators .. _.>=: .. function:: .>=(x, y) -.. function:: x .≥ y + .≥(x,y) Element-wise greater-than-or-equals comparison operator. @@ -3132,19 +3132,16 @@ Mathematical Functions Return ``x`` with its sign flipped if ``y`` is negative. For example ``abs(x) = flipsign(x,x)``. .. function:: sqrt(x) -.. function:: √x - Return :math:`\sqrt{x}`. Throws ``DomainError`` for negative ``Real`` arguments. Use complex negative arguments instead. - The prefix operator ``√`` is equivalent to ``sqrt``. + Return :math:`\sqrt{x}`. Throws ``DomainError`` for negative ``Real`` arguments. Use complex negative arguments instead. The prefix operator ``√`` is equivalent to ``sqrt``. .. function:: isqrt(n) Integer square root: the largest integer ``m`` such that ``m*m <= n``. .. function:: cbrt(x) -.. function:: ∛x - Return :math:`x^{1/3}`. The prefix operator ``∛`` is equivalent to ``cbrt``. + Return :math:`x^{1/3}`. The prefix operator ``∛`` is equivalent to ``cbrt``. .. function:: erf(x) @@ -3665,7 +3662,7 @@ Numbers Get the additive identity element for the type of x (x can also specify the type itself). .. data:: pi -.. data:: π + π The constant pi diff --git a/doc/stdlib/collections.rst b/doc/stdlib/collections.rst index a245a7cc7c51a..a72ed03b24322 100644 --- a/doc/stdlib/collections.rst +++ b/doc/stdlib/collections.rst @@ -14,7 +14,7 @@ The ``PriorityQueue`` type is a basic priority queue implementation allowing for arbitrary key and priority types. Multiple identical keys are not permitted, but the priority of existing keys can be changed efficiently. -.. function:: PriorityQueue{K,V}([ord]) +.. function:: PriorityQueue(K, V, [ord]) Construct a new PriorityQueue, with keys of type ``K`` and values/priorites of type ``V``. If an order is not given, the priority queue is min-ordered using diff --git a/doc/stdlib/dates.rst b/doc/stdlib/dates.rst index 4935e5a8c4ab2..8bd2f693cabc9 100644 --- a/doc/stdlib/dates.rst +++ b/doc/stdlib/dates.rst @@ -3,21 +3,21 @@ Dates Functions All Dates functions are defined in the ``Dates`` module; note that only the ``Date``, ``DateTime``, and ``now`` functions are exported; to use all other ``Dates`` functions, you'll need to prefix each function call with an explicit ``Dates.``, e.g. ``Dates.dayofweek(dt)``; -alternatively, you could call ``using Base.Dates`` to bring all exported functions into ``Main`` to be used without the ``Dates.`` prefix. +alternatively, you could call ``using Dates`` to bring all exported functions into ``Main`` to be used without the ``Dates.`` prefix. -.. currentmodule:: Base +.. currentmodule:: Dates -.. function:: ``DateTime(y, [m, d, h, mi, s, ms]) -> DateTime`` +.. function:: DateTime(y, [m, d, h, mi, s, ms]) -> DateTime Construct a DateTime type by parts. Arguments must be convertible to ``Int64``. -.. function:: ``DateTime(periods::Period...) -> DateTime`` +.. function:: DateTime(periods::Period...) -> DateTime Constuct a DateTime type by ``Period`` type parts. Arguments may be in any order. DateTime parts not provided will default to the value of ``Dates.default(period)``. -.. function:: ``DateTime(f::Function, y[, m, d, h, mi, s]; step=Day(1), negate=false, limit=10000) -> DateTime`` +.. function:: DateTime(f::Function, y[, m, d, h, mi, s]; step=Day(1), negate=false, limit=10000) -> DateTime Create a DateTime through the adjuster API. The starting point will be constructed from the provided ``y, m, d...`` arguments, and will be adjusted until ``f::Function`` returns true. The step size in @@ -26,44 +26,46 @@ alternatively, you could call ``using Base.Dates`` to bring all exported functio the max number of iterations the adjustment API will pursue before throwing an error (in the case that ``f::Function`` is never satisfied). -.. function:: ``DateTime(dt::Date) -> DateTime`` +.. function:: DateTime(dt::Date) -> DateTime Converts a ``Date`` type to a ``DateTime``. The hour, minute, second, and millisecond parts of the new ``DateTime`` are assumed to be zero. -.. function:: ``DateTime(dt::String, format::String; locale="english") -> DateTime`` +.. function:: DateTime(dt::String, format::String; locale="english") -> DateTime Construct a DateTime type by parsing the ``dt`` date string following the pattern given in the ``format`` string. The following codes can be used for constructing format strings: - | Code | Matches | Comment - | --------------- | -------- | ---------------------------- - | ``y`` | 1996, 96 | Returns year of 1996, 0096 - | ``m`` | 1, 01 | Matches 1 or 2-digit months - | ``u`` | Jan | Matches abbreviated months according to the ``locale`` keyword - | ``U`` | January | Matches full month names according to the ``locale`` keyword - | ``d`` | 1, 01 | Matches 1 or 2-digit days - | ``H`` | 00 | Matches hours - | ``M`` | 00 | Matches minutes - | ``S`` | 00 | Matches seconds - | ``s`` | .500 | Matches milliseconds - | ``yyyymmdd`` | 19960101 | Matches fixed-width year, month, and day + =============== ========= =============================================================== + Code Matches Comment + --------------- --------- --------------------------------------------------------------- + ``y`` 1996, 96 Returns year of 1996, 0096 + ``m`` 1, 01 Matches 1 or 2-digit months + ``u`` Jan Matches abbreviated months according to the ``locale`` keyword + ``U`` January Matches full month names according to the ``locale`` keyword + ``d`` 1, 01 Matches 1 or 2-digit days + ``H`` 00 Matches hours + ``M`` 00 Matches minutes + ``S`` 00 Matches seconds + ``s`` .500 Matches milliseconds + ``yyyymmdd`` 19960101 Matches fixed-width year, month, and day + =============== ========= =============================================================== All characters not listed above are treated as delimiters between date and time slots. So a ``dt`` string of "1996-01-15T00:00:00.0" would have a ``format`` string like "y-m-dTH:M:S.s". -.. function:: ``Date(y, [m, d]) -> Date`` +.. function:: Date(y, [m, d]) -> Date Construct a ``Date`` type by parts. Arguments must be convertible to ``Int64``. -.. function:: ``Date(period::Period...)`` +.. function:: Date(period::Period...) -> Date Constuct a Date type by ``Period`` type parts. Arguments may be in any order. Date parts not provided will default to the value of ``Dates.default(period)``. -.. function:: ``Date(f::Function, y[, m]; step=Day(1), negate=false, limit=10000) -> Date`` +.. function:: Date(f::Function, y[, m]; step=Day(1), negate=false, limit=10000) -> Date Create a Date through the adjuster API. The starting point will be constructed from the provided ``y, m`` arguments, and will be adjusted until ``f::Function`` returns true. The step size in @@ -72,207 +74,197 @@ alternatively, you could call ``using Base.Dates`` to bring all exported functio the max number of iterations the adjustment API will pursue before throwing an error (given that ``f::Function`` is never satisfied). -.. function:: ``Date(dt::DateTime) -> Date`` +.. function:: Date(dt::DateTime) -> Date Converts a ``DateTime`` type to a ``Date``. The hour, minute, second, and millisecond - parts of the ``DateTime`` are truncated, so only the year, month and day parts are kept. + parts of the ``DateTime`` are truncated, so only the year, month and day parts are used in construction. -.. function:: ``Date(dt::String, format::String; locale="english") -> Date`` +.. function:: Date(dt::String, format::String; locale="english") -> Date Construct a Date type by parsing a ``dt`` date string following the pattern given in - the ``format`` string. Follows the same convention as ``DateTime`` above. + the ``format`` string. Follows the same conventions as ``DateTime`` above. -.. function:: ``now() -> DateTime`` +.. function:: now() -> DateTime - Returns a DateTime type corresponding to the user's system + Returns a DateTime corresponding to the user's system time. Accessor Functions ~~~~~~~~~~~~~~~~~~ -.. function:: ``year(dt::TimeType) -> Int64`` +.. function:: year(dt::TimeType) -> Int64 + month(dt::TimeType) -> Int64 + week(dt::TimeType) -> Int64 + day(dt::TimeType) -> Int64 + hour(dt::TimeType) -> Int64 + minute(dt::TimeType) -> Int64 + second(dt::TimeType) -> Int64 + millisecond(dt::TimeType) -> Int64 - Return the year part of a Date or DateTime. Use ``Year(dt)`` to return a ``Year`` type. + Return the field part of a Date or DateTime as an ``Int64``. -.. function:: ``month(dt::TimeType) -> Int64`` +.. function:: Year(dt::TimeType) -> Year + Month(dt::TimeType) -> Month + Week(dt::TimeType) -> Week + Day(dt::TimeType) -> Day + Hour(dt::TimeType) -> Hour + Minute(dt::TimeType) -> Minute + Second(dt::TimeType) -> Second + Millisecond(dt::TimeType) -> Millisecond - Return the month part of a Date or DateTime. Use ``Month(dt)`` to return a ``Month`` type. + Return the field part of a Date or DateTime as a ``Period`` type. -.. function:: ``week(dt::TimeType) -> Int64`` - - Return the ISO 8601 week number of a Date or DateTime. Use ``Week(dt)`` to return a ``Week`` type. - -.. function:: ``day(dt::TimeType) -> Int64`` - - Return the day part of a Date or DateTime. Use ``Day(dt)`` to return a ``Day`` type. - -.. function:: ``hour(dt::TimeType) -> Int64`` - - Return the hour part of a DateTime. Use ``Hour(dt)`` to return a ``Hour`` type. - -.. function:: ``minute(dt::TimeType) -> Int64`` - - Return the minute part of a DateTime. Use ``Minute(dt)`` to return a ``Minute`` type. - -.. function:: ``second(dt::TimeType) -> Int64`` - - Return the second part of a DateTime. Use ``Second(dt)`` to return a ``Second`` type. - -.. function:: ``millisecond(dt::TimeType) -> Int64`` - - Return the millisecond part of a DateTime. Use ``Millisecond(dt)`` to return a ``Millisecond`` type. - -.. function:: ``yearmonth(dt::TimeType) -> (Int64, Int64)`` +.. function:: yearmonth(dt::TimeType) -> (Int64, Int64) Simultaneously return the year and month parts of a Date or DateTime. -.. function:: ``monthday(dt::TimeType) -> (Int64, Int64)`` +.. function:: monthday(dt::TimeType) -> (Int64, Int64) Simultaneously return the month and day parts of a Date or DateTime. -.. function:: ``yearmonthday(dt::TimeType) -> (Int64, Int64, Int64)`` +.. function:: yearmonthday(dt::TimeType) -> (Int64, Int64, Int64) Simultaneously return the year, month, and day parts of a Date or DateTime. Query Functions ~~~~~~~~~~~~~~~ -.. function:: ``dayname(dt::TimeType; locale="english") -> String`` +.. function:: dayname(dt::TimeType; locale="english") -> String Return the full day name corresponding to the day of the week of the Date or DateTime in the given ``locale``. -.. function:: ``dayabbr(dt::TimeType; locale="english") -> String`` +.. function:: dayabbr(dt::TimeType; locale="english") -> String Return the abbreviated name corresponding to the day of the week of the Date or DateTime in the given ``locale``. -.. function:: ``dayofweek(dt::TimeType) -> Int64`` +.. function:: dayofweek(dt::TimeType) -> Int64 Returns the day of the week as an ``Int64`` with ``1 = Monday, 2 = Tuesday, etc.``. -.. function:: ``dayofweekofmonth(dt::TimeType) -> Int`` +.. function:: dayofweekofmonth(dt::TimeType) -> Int For the day of week of ``dt``, returns which number it is in ``dt``'s month. So if the day of the week of ``dt`` is Monday, then ``1 = First Monday of the month, 2 = Second Monday of the month, etc.`` In the range 1:5. -.. function:: ``daysofweekinmonth(dt::TimeType) -> Int`` +.. function:: daysofweekinmonth(dt::TimeType) -> Int For the day of week of ``dt``, returns the total number of that day of the week in ``dt``'s month. Returns 4 or 5. Useful in temporal expressions for specifying the last day of a week in a month by including ``dayofweekofmonth(dt) == daysofweekinmonth(dt)`` in the adjuster function. -.. function:: ``monthname(dt::TimeType; locale="english") -> String`` +.. function:: monthname(dt::TimeType; locale="english") -> String Return the full name of the month of the Date or DateTime in the given ``locale``. -.. function:: ``monthabbr(dt::TimeType; locale="english") -> String`` +.. function:: monthabbr(dt::TimeType; locale="english") -> String Return the abbreviated month name of the Date or DateTime in the given ``locale``. -.. function:: ``daysinmonth(dt::TimeType) -> Int`` +.. function:: daysinmonth(dt::TimeType) -> Int Returns the number of days in the month of ``dt``. Value will be 28, 29, 30, or 31. -.. function:: ``isleapyear(dt::TimeType) -> Bool`` +.. function:: isleapyear(dt::TimeType) -> Bool Returns true if the year of ``dt`` is a leap year. -.. function:: ``dayofyear(dt::TimeType) -> Int`` +.. function:: dayofyear(dt::TimeType) -> Int Returns the day of the year for ``dt`` with January 1st being day 1. -.. function:: ``daysinyear(dt::TimeType) -> Int`` +.. function:: daysinyear(dt::TimeType) -> Int Returns 366 if the year of ``dt`` is a leap year, otherwise returns 365. -.. function:: ``quarterofyear(dt::TimeType) -> Int`` +.. function:: quarterofyear(dt::TimeType) -> Int Returns the quarter that ``dt`` resides in. Range of value is 1:4. -.. function:: ``dayofquarter(dt::TimeType) -> Int`` +.. function:: dayofquarter(dt::TimeType) -> Int Returns the day of the current quarter of ``dt``. Range of value is 1:92. Adjuster Functions ~~~~~~~~~~~~~~~~~~ -.. function:: ``trunc(dt::TimeType, ::Type{Period}) -> TimeType`` +.. function:: trunc(dt::TimeType, ::Type{Period}) -> TimeType Truncates the value of ``dt`` according to the provided ``Period`` type. E.g. if ``dt`` is ``1996-01-01T12:30:00``, then ``trunc(dt,Day) == 1996-01-01T00:00:00``. -.. function:: ``firstdayofweek(dt::TimeType) -> TimeType`` +.. function:: firstdayofweek(dt::TimeType) -> TimeType Adjusts ``dt`` to the Monday of it's week. -.. function:: ``lastdayofweek(dt::TimeType) -> TimeType`` +.. function:: lastdayofweek(dt::TimeType) -> TimeType Adjusts ``dt`` to the Sunday of it's week. -.. function:: ``firstdayofmonth(dt::TimeType) -> TimeType`` +.. function:: firstdayofmonth(dt::TimeType) -> TimeType Adjusts ``dt`` to the first day of it's month. -.. function:: ``lastdayofmonth(dt::TimeType) -> TimeType`` +.. function:: lastdayofmonth(dt::TimeType) -> TimeType Adjusts ``dt`` to the last day of it's month. -.. function:: ``firstdayofyear(dt::TimeType) -> TimeType`` +.. function:: firstdayofyear(dt::TimeType) -> TimeType Adjusts ``dt`` to the first day of it's year. -.. function:: ``lastdayofyear(dt::TimeType) -> TimeType`` +.. function:: lastdayofyear(dt::TimeType) -> TimeType Adjusts ``dt`` to the last day of it's year. -.. function:: ``firstdayofquarter(dt::TimeType) -> TimeType`` +.. function:: firstdayofquarter(dt::TimeType) -> TimeType Adjusts ``dt`` to the first day of it's quarter. -.. function:: ``lastdayofquarter(dt::TimeType) -> TimeType`` +.. function:: lastdayofquarter(dt::TimeType) -> TimeType Adjusts ``dt`` to the last day of it's quarter. -.. function:: ``tonext(dt::TimeType,dow::Int;same::Bool=false) -> TimeType`` +.. function:: tonext(dt::TimeType,dow::Int;same::Bool=false) -> TimeType Adjusts ``dt`` to the next day of week corresponding to ``dow`` with ``1 = Monday, 2 = Tuesday, etc``. Setting ``same=true`` allows the current ``dt`` to be considered as the next ``dow``, allowing for no adjustment to occur. -.. function:: ``toprev(dt::TimeType,dow::Int;same::Bool=false) -> TimeType`` +.. function:: toprev(dt::TimeType,dow::Int;same::Bool=false) -> TimeType Adjusts ``dt`` to the previous day of week corresponding to ``dow`` with ``1 = Monday, 2 = Tuesday, etc``. Setting ``same=true`` allows the current ``dt`` to be considered as the previous ``dow``, allowing for no adjustment to occur. -.. function:: ``tofirst(dt::TimeType,dow::Int;of=Month) -> TimeType`` +.. function:: tofirst(dt::TimeType,dow::Int;of=Month) -> TimeType Adjusts ``dt`` to the first ``dow`` of it's month. Alternatively, ``of=Year`` will adjust to the first ``dow`` of the year. -.. function:: ``tolast(dt::TimeType,dow::Int;of=Month) -> TimeType`` +.. function:: tolast(dt::TimeType,dow::Int;of=Month) -> TimeType Adjusts ``dt`` to the last ``dow`` of it's month. Alternatively, ``of=Year`` will adjust to the last ``dow`` of the year. -.. function:: ``tonext(func::Function,dt::TimeType;step=Day(1),negate=false,limit=10000,same=false) -> TimeType`` +.. function:: tonext(func::Function,dt::TimeType;step=Day(1),negate=false,limit=10000,same=false) -> TimeType Adjusts ``dt`` by iterating at most ``limit`` iterations by ``step`` increments until ``func`` returns true. ``func`` must take a single ``TimeType`` argument and return a ``Bool``. ``same`` allows ``dt`` to be considered in satisfying ``func``. ``negate`` will make the adjustment process terminate when ``func`` returns false instead of true. -.. function:: ``toprev(func::Function,dt::TimeType;step=Day(-1),negate=false,limit=10000,same=false) -> TimeType`` +.. function:: toprev(func::Function,dt::TimeType;step=Day(-1),negate=false,limit=10000,same=false) -> TimeType Adjusts ``dt`` by iterating at most ``limit`` iterations by ``step`` increments until ``func`` returns true. ``func`` must take a single ``TimeType`` argument and return a ``Bool``. ``same`` allows ``dt`` to be considered in satisfying ``func``. ``negate`` will make the adjustment process terminate when ``func`` returns false instead of true. -.. function:: ``recur{T<:TimeType}(func::Function,dr::StepRange{T};negate=false,limit=10000) -> Array{T,1}`` +.. function:: recur{T<:TimeType}(func::Function,dr::StepRange{T};negate=false,limit=10000) -> Vector{T} ``func`` takes a single TimeType argument and returns a ``Bool`` indicating whether the input should be "included" in the final set. ``recur`` applies ``func`` over each element in the @@ -283,47 +275,19 @@ Adjuster Functions Periods ~~~~~~~ -.. function:: ``Year(y)`` +.. function:: Year(v) + Month(v) + Week(v) + Day(v) + Hour(v) + Minute(v) + Second(v) + Millisecond(v) - Construct a ``Year`` type with the given ``y`` value. + Construct a ``Period`` type with the given ``v`` value. Input must be losslessly convertible to an ``Int64``. -.. function:: ``Month(m)`` - - Construct a ``Month`` type with the given ``m`` value. - Input must be losslessly convertible to an ``Int64``. - -.. function:: ``Week(w)`` - - Construct a ``Week`` type with the given ``w`` value. - Input must be losslessly convertible to an ``Int64``. - -.. function:: ``Day(d)`` - - Construct a ``Day`` type with the given ``d`` value. - Input must be losslessly convertible to an ``Int64``. - -.. function:: ``Hour(h)`` - - Construct a ``Hour`` type with the given ``h`` value. - Input must be losslessly convertible to an ``Int64``. - -.. function:: ``Minute(mi)`` - - Construct a ``Minute`` type with the given ``mi`` value. - Input must be losslessly convertible to an ``Int64``. - -.. function:: ``Second(s)`` - - Construct a ``Second`` type with the given ``s`` value. - Input must be losslessly convertible to an ``Int64``. - -.. function:: ``Millisecond(ms)`` - - Construct a ``Millisecond`` type with the given ``ms`` value. - Input must be losslessly convertible to an ``Int64``. - -.. function:: ``default(p::Period) => Period`` +.. function:: default(p::Period) => Period Returns a sensible "default" value for the input Period by returning ``one(p)`` for Year, Month, and Day, and ``zero(p)`` for Hour, Minute, @@ -332,36 +296,36 @@ Periods Conversion Functions ~~~~~~~~~~~~~~~~~~~~ -.. function:: ``today() -> Date`` +.. function:: today() -> Date Returns the date portion of ``now()``. -.. function:: ``unix2datetime(x) -> DateTime`` +.. function:: unix2datetime(x) -> DateTime Takes the number of seconds since unix epoch ``1970-01-01T00:00:00`` and converts to the corresponding DateTime. -.. function:: ``datetime2unix(dt::DateTime) -> Float64`` +.. function:: datetime2unix(dt::DateTime) -> Float64 Takes the given DateTime and returns the number of seconds since the unix epoch as a ``Float64``. -.. function:: ``julian2datetime(j) -> DateTime`` +.. function:: julian2datetime(julian_days) -> DateTime Takes the number of Julian calendar days since epoch ``-4713-11-24T12:00:00`` and returns the corresponding DateTime. -.. function:: ``datetime2julian(dt::DateTime) -> Float64`` +.. function:: datetime2julian(dt::DateTime) -> Float64 Takes the given DateTime and returns the number of Julian calendar days since the julian epoch as a ``Float64``. -.. function:: ``rata2datetime(days) -> DateTime`` +.. function:: rata2datetime(days) -> DateTime Takes the number of Rata Die days since epoch ``0000-12-31T00:00:00`` and returns the corresponding DateTime. -.. function:: ``datetime2rata(dt::TimeType) -> Int64`` +.. function:: datetime2rata(dt::TimeType) -> Int64 Returns the number of Rata Die days since epoch from the given Date or DateTime. @@ -372,42 +336,34 @@ Constants Days of the Week: - ``Monday`` = ``Mon`` = 1 - - ``Tuesday`` = ``Tue`` = 2 - - ``Wednesday`` = ``Wed`` = 3 - - ``Thursday`` = ``Thu`` = 4 - - ``Friday`` = ``Fri`` = 5 - - ``Saturday`` = ``Sat`` = 6 - - ``Sunday`` = ``Sun`` = 7 +=============== ========= ============= +Variable Abbr. Value (Int64) +--------------- --------- ------------- +``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: - ``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 +=============== ========= ============= +Variable Abbr. Value (Int64) +--------------- --------- ------------- +``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 +=============== ========= ============= - ``December`` = ``Dec`` = 12 diff --git a/doc/stdlib/linalg.rst b/doc/stdlib/linalg.rst index 9ce7b3d119d9f..fd3acbffda025 100644 --- a/doc/stdlib/linalg.rst +++ b/doc/stdlib/linalg.rst @@ -20,12 +20,12 @@ Linear algebra functions in Julia are largely implemented by calling functions f Matrix division using a polyalgorithm. For input matrices ``A`` and ``B``, the result ``X`` is such that ``A*X == B`` when ``A`` is square. The solver that is used depends upon the structure of ``A``. A direct solver is used for upper- or lower triangular ``A``. For Hermitian ``A`` (equivalent to symmetric ``A`` for non-complex ``A``) the ``BunchKaufman`` factorization is used. Otherwise an LU factorization is used. For rectangular ``A`` the result is the minimum-norm least squares solution computed by reducing ``A`` to bidiagonal form and solving the bidiagonal least squares problem. For sparse, square ``A`` the LU factorization (from UMFPACK) is used. .. function:: dot(x, y) -.. function:: x ⋅ y + ⋅(x,y) Compute the dot product. For complex vectors, the first vector is conjugated. .. function:: cross(x, y) -.. function:: x × y + ×(x,y) Compute the cross product of two 3-vectors. diff --git a/src/cgutils.cpp b/src/cgutils.cpp index bdcf18b5541f8..f473cf51c55e0 100644 --- a/src/cgutils.cpp +++ b/src/cgutils.cpp @@ -876,6 +876,12 @@ static Value *emit_nthptr(Value *v, Value *idx, MDNode *tbaa) return tbaa_decorate(tbaa,builder.CreateLoad(vptr, false)); } +static Value *emit_nthptr_recast(Value *v, size_t n, MDNode *tbaa, Type* ptype) { + // p = (jl_value_t**)v; *(ptype)&p[n] + Value *vptr = emit_nthptr_addr(v, n); + return tbaa_decorate(tbaa,builder.CreateLoad(builder.CreateBitCast(vptr,ptype), false)); +} + static Value *typed_load(Value *ptr, Value *idx_0based, jl_value_t *jltype, jl_codectx_t *ctx) { @@ -1013,8 +1019,7 @@ static Value *emit_tuplelen(Value *t,jl_value_t *jt) return builder.CreateLShr(builder.CreatePtrToInt(lenbits, T_int64), ConstantInt::get(T_int32, 52)); #else - Value *lenbits = emit_nthptr(t, 1, tbaa_tuplelen); - return builder.CreatePtrToInt(lenbits, T_size); + return emit_nthptr_recast(t, 1, tbaa_tuplelen, T_psize); #endif } else { //unboxed @@ -1279,8 +1284,7 @@ static Value *emit_arraylen_prim(Value *t, jl_value_t *ty) { #ifdef STORE_ARRAY_LEN (void)ty; - Value *lenbits = emit_nthptr(t, 2, tbaa_arraylen); - return builder.CreatePtrToInt(lenbits, T_size); + return emit_nthptr_recast(t, 2, tbaa_arraylen, T_psize); #else jl_value_t *p1 = jl_tparam1(ty); if (jl_is_long(p1)) { diff --git a/src/codegen.cpp b/src/codegen.cpp index 7dc73cddd52db..bc86ad4ea5295 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -212,7 +212,7 @@ static Type *jl_value_llvmt; static Type *jl_pvalue_llvmt; static Type *jl_ppvalue_llvmt; static FunctionType *jl_func_sig; -static Type *jl_fptr_llvmt; +static Type *jl_pfptr_llvmt; static Type *T_int1; static Type *T_int8; static Type *T_pint8; @@ -612,7 +612,11 @@ static void jl_setup_module(Module *m, bool add) llvm::DEBUG_METADATA_VERSION); #endif if (add) +#ifdef LLVM36 + jl_ExecutionEngine->addModule(std::unique_ptr(m)); +#else jl_ExecutionEngine->addModule(m); +#endif } extern "C" void jl_generate_fptr(jl_function_t *f) @@ -1758,7 +1762,7 @@ static Value *emit_known_call(jl_value_t *ff, jl_value_t **args, size_t nargs, else if (f->fptr == &jl_f_apply && nargs==2 && ctx->vaStack && symbol_eq(args[2], ctx->vaName)) { Value *theF = emit_expr(args[1],ctx); - Value *theFptr = builder.CreateBitCast(emit_nthptr(theF,1, tbaa_func),jl_fptr_llvmt); + Value *theFptr = emit_nthptr_recast(theF,1, tbaa_func,jl_pfptr_llvmt); Value *nva = emit_n_varargs(ctx); #ifdef _P64 nva = builder.CreateTrunc(nva, T_int32); @@ -2247,7 +2251,7 @@ static Value *emit_call(jl_value_t **args, size_t arglen, jl_codectx_t *ctx, } // extract pieces of the function object // TODO: try extractvalue instead - theFptr = builder.CreateBitCast(emit_nthptr(theFunc, 1, tbaa_func), jl_fptr_llvmt); + theFptr = emit_nthptr_recast(theFunc, 1, tbaa_func, jl_pfptr_llvmt); theF = theFunc; } else { @@ -2878,10 +2882,12 @@ static Value *emit_expr(jl_value_t *expr, jl_codectx_t *ctx, bool isboxed, ConstantInt::get(T_size,0)); builder.CreateCall(prepare_call(jlenter_func), jbuf); #ifndef _OS_WINDOWS_ - Value *sj = builder.CreateCall2(prepare_call(setjmp_func), jbuf, ConstantInt::get(T_int32,0)); + CallInst *sj = builder.CreateCall2(prepare_call(setjmp_func), jbuf, ConstantInt::get(T_int32,0)); #else - Value *sj = builder.CreateCall(prepare_call(setjmp_func), jbuf); + CallInst *sj = builder.CreateCall(prepare_call(setjmp_func), jbuf); #endif + // We need to mark this on the call site as well. See issue #6757 + sj->setCanReturnTwice(); Value *isz = builder.CreateICmpEQ(sj, ConstantInt::get(T_int32,0)); BasicBlock *tryblk = BasicBlock::Create(getGlobalContext(), "try", ctx->f); @@ -4080,7 +4086,7 @@ static void init_julia_llvm_env(Module *m) ftargs.push_back(T_int32); jl_func_sig = FunctionType::get(jl_pvalue_llvmt, ftargs, false); assert(jl_func_sig != NULL); - jl_fptr_llvmt = PointerType::get(jl_func_sig, 0); + jl_pfptr_llvmt = PointerType::get(PointerType::get(jl_func_sig, 0), 0); #ifdef JL_GC_MARKSWEEP jlpgcstack_var = @@ -4582,8 +4588,12 @@ extern "C" void jl_init_codegen(void) }; SmallVector MAttrs(mattr, mattr+2); #endif - EngineBuilder eb = EngineBuilder(engine_module) - .setEngineKind(EngineKind::JIT) +#ifdef LLVM36 + EngineBuilder eb = EngineBuilder(std::unique_ptr(engine_module)); +#else + EngineBuilder eb = EngineBuilder(engine_module); +#endif + eb .setEngineKind(EngineKind::JIT) #if defined(_OS_WINDOWS_) && defined(_CPU_X86_64_) && !defined(USE_MCJIT) .setJITMemoryManager(new JITMemoryManagerWin()) #endif diff --git a/test/Makefile b/test/Makefile index d10bed65ec9b8..3240e71279562 100644 --- a/test/Makefile +++ b/test/Makefile @@ -7,7 +7,7 @@ TESTS = all core keywordargs numbers strings unicode collections hashing \ math functional bigint sorting statistics spawn parallel arpack file \ git pkg resolve suitesparse complex version pollfd mpfr broadcast \ socket floatapprox priorityqueue readdlm regex float16 combinatorics \ - sysinfo rounding ranges mod2pi euler show lineedit \ + dates sysinfo rounding ranges mod2pi euler show lineedit \ replcompletions backtrace repl test goto llvmcall default: all diff --git a/test/dates.jl b/test/dates.jl index 1687eb69800e1..711a31db4c24b 100644 --- a/test/dates.jl +++ b/test/dates.jl @@ -1,4 +1,7 @@ +module TestDates + using Base.Dates +using Base.Test include("dates/types.jl") include("dates/periods.jl") @@ -8,4 +11,6 @@ include("dates/arithmetic.jl") include("dates/conversions.jl") include("dates/ranges.jl") include("dates/adjusters.jl") -include("dates/io.jl") \ No newline at end of file +include("dates/io.jl") + +end \ No newline at end of file diff --git a/test/dates/accessors.jl b/test/dates/accessors.jl index 394be1a252155..85f7f01251ce5 100644 --- a/test/dates/accessors.jl +++ b/test/dates/accessors.jl @@ -52,26 +52,24 @@ function test_dates(from,to) end end end -test_dates(-1000,3000) +test_dates(0,2100) # Test year, month, day, hour, minute function test_dates() y = m = d = h = mi = 0 - for y in [-2013,-1,0,1,2013] - for m = 1:12 - for d = 1:Dates.daysinmonth(y,m) - for h = 0:23 - for mi = 0:59 - dt = Dates.DateTime(y,m,d,h,mi) - @test y == Dates.year(dt) - @test m == Dates.month(dt) - @test d == Dates.day(dt) - @test d == Dates.dayofmonth(dt) - @test h == Dates.hour(dt) - @test mi == Dates.minute(dt) - #@test s == Dates.second(dt) - #@test ms == Dates.millisecond(dt) - end + for m = 1:12 + for d = 1:Dates.daysinmonth(y,m) + for h = 0:23 + for mi = 0:59 + dt = Dates.DateTime(y,m,d,h,mi) + @test y == Dates.year(dt) + @test m == Dates.month(dt) + @test d == Dates.day(dt) + @test d == Dates.dayofmonth(dt) + @test h == Dates.hour(dt) + @test mi == Dates.minute(dt) + #@test s == Dates.second(dt) + #@test ms == Dates.millisecond(dt) end end end @@ -117,7 +115,7 @@ function test_dates(from,to) end end end -test_dates(-2000,2000) +test_dates(0,2100) # week function # Tests from http://en.wikipedia.org/wiki/ISO_week_date diff --git a/test/dates/adjusters.jl b/test/dates/adjusters.jl index 4c593147e0c5a..00b93e7df7ba0 100644 --- a/test/dates/adjusters.jl +++ b/test/dates/adjusters.jl @@ -303,20 +303,20 @@ januarymondays2014 = [Dates.Date(2014,1,6),Dates.Date(2014,1,13),Dates.Date(2014 @test Dates.recur(Dates.ismonday,startdate:stopdate) == januarymondays2014 @test Dates.recur(x->!Dates.ismonday(x),startdate,stopdate;negate=true) == januarymondays2014 -@test_throws ArgumentError recur((x,y)->x+y,Dates.Date(2013):Dates.Date(2014)) -@test length(recur(x->true,Dates.Date(2013):Dates.Date(2013,2))) == 32 -@test length(recur(x->true,Dates.Date(2013):Dates.Date(2013,1,1))) == 1 -@test length(recur(x->true,Dates.Date(2013):Dates.Date(2013,1,2))) == 2 -@test length(recur(x->true,Dates.Date(2013):Dates.Date(2013,1,3))) == 3 -@test length(recur(x->true,Dates.Date(2013):Dates.Date(2013,1,4))) == 4 -@test length(recur(x->true,Dates.Date(2013):Dates.Date(2013,1,5))) == 5 -@test length(recur(x->true,Dates.Date(2013):Dates.Date(2013,1,6))) == 6 -@test length(recur(x->true,Dates.Date(2013):Dates.Date(2013,1,7))) == 7 -@test length(recur(x->true,Dates.Date(2013):Dates.Date(2013,1,8))) == 8 -@test length(recur(x->true,Dates.Date(2013):Dates.Month(1):Dates.Date(2013,1,1))) == 1 -@test length(recur(x->true,Dates.Date(2013):Dates.Day(-1):Dates.Date(2012,1,1))) == 367 +@test_throws ArgumentError Dates.recur((x,y)->x+y,Dates.Date(2013):Dates.Date(2014)) +@test length(Dates.recur(x->true,Dates.Date(2013):Dates.Date(2013,2))) == 32 +@test length(Dates.recur(x->true,Dates.Date(2013):Dates.Date(2013,1,1))) == 1 +@test length(Dates.recur(x->true,Dates.Date(2013):Dates.Date(2013,1,2))) == 2 +@test length(Dates.recur(x->true,Dates.Date(2013):Dates.Date(2013,1,3))) == 3 +@test length(Dates.recur(x->true,Dates.Date(2013):Dates.Date(2013,1,4))) == 4 +@test length(Dates.recur(x->true,Dates.Date(2013):Dates.Date(2013,1,5))) == 5 +@test length(Dates.recur(x->true,Dates.Date(2013):Dates.Date(2013,1,6))) == 6 +@test length(Dates.recur(x->true,Dates.Date(2013):Dates.Date(2013,1,7))) == 7 +@test length(Dates.recur(x->true,Dates.Date(2013):Dates.Date(2013,1,8))) == 8 +@test length(Dates.recur(x->true,Dates.Date(2013):Dates.Month(1):Dates.Date(2013,1,1))) == 1 +@test length(Dates.recur(x->true,Dates.Date(2013):Dates.Day(-1):Dates.Date(2012,1,1))) == 367 # Empty range -@test length(recur(x->true,Dates.Date(2013):Dates.Date(2012,1,1))) == 0 +@test length(Dates.recur(x->true,Dates.Date(2013):Dates.Date(2012,1,1))) == 0 # All leap days in 20th century @test length(Dates.recur(Dates.Date(1900):Dates.Date(2000)) do x @@ -340,7 +340,7 @@ end == Dates.Date(2013,11,28) # Pittsburgh street cleaning dr = Dates.Date(2014):Dates.Date(2015) -@test length(recur(dr) do x +@test length(Dates.recur(dr) do x Dates.dayofweek(x) == Dates.Tue && Dates.April < Dates.month(x) < Dates.Nov && Dates.dayofweekofmonth(x) == 2 @@ -362,10 +362,10 @@ ispresidentsday(dt) = Dates.dayofweek(dt) == Dates.Mon && Dates.month(dt) == Dates.Feb && Dates.dayofweekofmonth(dt) == 3 # Last Monday of May ismemorialday(dt) = Dates.dayofweek(dt) == Dates.Mon && - Dates.month(dt) == May && + Dates.month(dt) == Dates.May && Dates.dayofweekofmonth(dt) == Dates.daysofweekinmonth(dt) islaborday(dt) = Dates.dayofweek(dt) == Dates.Mon && - Dates.month(dt) == Dates.Sep && dayofweekofmonth(dt) == 1 + Dates.month(dt) == Dates.Sep && Dates.dayofweekofmonth(dt) == 1 iscolumbusday(dt) = Dates.dayofweek(dt) == Dates.Mon && Dates.month(dt) == Dates.Oct && Dates.dayofweekofmonth(dt) == 2 isthanksgiving(dt) = Dates.dayofweek(dt) == Dates.Thu && diff --git a/test/dates/ranges.jl b/test/dates/ranges.jl index c6e16b4371c3c..cd23202d7e97f 100644 --- a/test/dates/ranges.jl +++ b/test/dates/ranges.jl @@ -34,7 +34,7 @@ function test_all_combos() dr = f:pos_step:l len = length(dr) @test len > 0 - @test typeof(len) <: Int + @test typeof(len) <: Int64 @test !isempty(dr) @test first(dr) == f @test last(dr) <= l @@ -86,7 +86,7 @@ function test_all_combos() dr = l:neg_step:f len = length(dr) @test len > 0 - @test typeof(len) <: Int + @test typeof(len) <: Int64 @test !isempty(dr) @test first(dr) == l @test last(dr) >= f @@ -139,7 +139,7 @@ function test_all_combos() dr = f:pos_step:l len = length(dr) @test len > 0 - @test typeof(len) <: Int + @test typeof(len) <: Int64 @test !isempty(dr) @test first(dr) == f @test last(dr) <= l @@ -191,7 +191,7 @@ function test_all_combos() dr = l:neg_step:f len = length(dr) @test len > 0 - @test typeof(len) <: Int + @test typeof(len) <: Int64 @test !isempty(dr) @test first(dr) == l @test last(dr) >= f diff --git a/test/dates/types.jl b/test/dates/types.jl index 3cca9c5a6bb39..1e670323a6b5e 100644 --- a/test/dates/types.jl +++ b/test/dates/types.jl @@ -49,38 +49,38 @@ test = Dates.Date(Dates.UTD(734869)) @test Dates.Date(2013,1,1) == test # Test various input types for Date/DateTime -test = Date(1,1,1) -@test Date(int8(1),int8(1),int8(1)) == test -@test Date(uint8(1),uint8(1),uint8(1)) == test -@test Date(int16(1),int16(1),int16(1)) == test -@test Date(uint8(1),uint8(1),uint8(1)) == test -@test Date(int32(1),int32(1),int32(1)) == test -@test Date(uint32(1),uint32(1),uint32(1)) == test -@test Date(int64(1),int64(1),int64(1)) == test -@test Date('\x01','\x01','\x01') == test -@test Date(true,true,true) == test -@test_throws ArgumentError Date(false,true,false) -@test Date(false,true,true) == test - Dates.Year(1) -@test_throws ArgumentError Date(true,true,false) -@test Date(uint64(1),uint64(1),uint64(1)) == test -@test Date(0xffffffffffffffff,uint64(1),uint64(1)) == test - Dates.Year(2) -@test Date(int128(1),int128(1),int128(1)) == test -@test Date(170141183460469231731687303715884105727,int128(1),int128(1)) == test - Dates.Year(2) -@test Date(uint128(1),uint128(1),uint128(1)) == test -@test Date(big(1),big(1),big(1)) == test -@test Date(big(1),big(1),big(1)) == test +test = Dates.Date(1,1,1) +@test Dates.Date(int8(1),int8(1),int8(1)) == test +@test Dates.Date(uint8(1),uint8(1),uint8(1)) == test +@test Dates.Date(int16(1),int16(1),int16(1)) == test +@test Dates.Date(uint8(1),uint8(1),uint8(1)) == test +@test Dates.Date(int32(1),int32(1),int32(1)) == test +@test Dates.Date(uint32(1),uint32(1),uint32(1)) == test +@test Dates.Date(int64(1),int64(1),int64(1)) == test +@test Dates.Date('\x01','\x01','\x01') == test +@test Dates.Date(true,true,true) == test +@test_throws ArgumentError Dates.Date(false,true,false) +@test Dates.Date(false,true,true) == test - Dates.Year(1) +@test_throws ArgumentError Dates.Date(true,true,false) +@test Dates.Date(uint64(1),uint64(1),uint64(1)) == test +@test Dates.Date(0xffffffffffffffff,uint64(1),uint64(1)) == test - Dates.Year(2) +@test Dates.Date(int128(1),int128(1),int128(1)) == test +@test Dates.Date(170141183460469231731687303715884105727,int128(1),int128(1)) == test - Dates.Year(2) +@test Dates.Date(uint128(1),uint128(1),uint128(1)) == test +@test Dates.Date(big(1),big(1),big(1)) == test +@test Dates.Date(big(1),big(1),big(1)) == test # Potentially won't work if can't losslessly convert to Int64 -@test Date(BigFloat(1),BigFloat(1),BigFloat(1)) == test -@test Date(complex(1),complex(1),complex(1)) == test -@test Date(float64(1),float64(1),float64(1)) == test -@test Date(float32(1),float32(1),float32(1)) == test -@test Date(float16(1),float16(1),float16(1)) == test -@test Date(Rational(1),Rational(1),Rational(1)) == test -@test_throws InexactError Date(BigFloat(1.2),BigFloat(1),BigFloat(1)) -@test_throws InexactError Date(1 + im,complex(1),complex(1)) -@test_throws InexactError Date(1.2,1.0,1.0) -@test_throws InexactError Date(1.2f0,1.f0,1.f0) -@test_throws InexactError Date(3//4,Rational(1),Rational(1)) == test +@test Dates.Date(BigFloat(1),BigFloat(1),BigFloat(1)) == test +@test Dates.Date(complex(1),complex(1),complex(1)) == test +@test Dates.Date(float64(1),float64(1),float64(1)) == test +@test Dates.Date(float32(1),float32(1),float32(1)) == test +@test Dates.Date(float16(1),float16(1),float16(1)) == test +@test Dates.Date(Rational(1),Rational(1),Rational(1)) == test +@test_throws InexactError Dates.Date(BigFloat(1.2),BigFloat(1),BigFloat(1)) +@test_throws InexactError Dates.Date(1 + im,complex(1),complex(1)) +@test_throws InexactError Dates.Date(1.2,1.0,1.0) +@test_throws InexactError Dates.Date(1.2f0,1.f0,1.f0) +@test_throws InexactError Dates.Date(3//4,Rational(1),Rational(1)) == test # Months, days, hours, minutes, seconds, and milliseconds must be in range @test_throws ArgumentError Dates.Date(2013,0,1) @@ -143,7 +143,7 @@ b = Dates.Date(2001) @test b > a @test a < b @test a != b -@test Date(DateTime(Date(2012,7,1))) == Date(2012,7,1) +@test Dates.Date(Dates.DateTime(Dates.Date(2012,7,1))) == Dates.Date(2012,7,1) y = Dates.Year(1) m = Dates.Month(1) @@ -162,7 +162,8 @@ ms = Dates.Millisecond(1) @test Dates.DateTime(y,m,d,h,mi,s,ms) == Dates.DateTime(1,1,1,1,1,1,1) @test Dates.DateTime(Dates.Day(10),Dates.Month(2),y) == Dates.DateTime(1,2,10) @test Dates.DateTime(Dates.Second(10),Dates.Month(2),y,Dates.Hour(4)) == Dates.DateTime(1,2,1,4,0,10) -@test Dates.DateTime(Dates.Year(1),Dates.Month(2),Dates.Day(1),Dates.Hour(4),Dates.Second(10)) == Dates.DateTime(1,2,1,4,0,10) +@test Dates.DateTime(Dates.Year(1),Dates.Month(2),Dates.Day(1), + Dates.Hour(4),Dates.Second(10)) == Dates.DateTime(1,2,1,4,0,10) @test Dates.Date(y) == Dates.Date(1) @test Dates.Date(y,m) == Dates.Date(1,1) @test Dates.Date(y,m,d) == Dates.Date(1,1,1) diff --git a/test/linalg4.jl b/test/linalg4.jl index 1a9f6a9898c57..8a5f26ed12c4f 100644 --- a/test/linalg4.jl +++ b/test/linalg4.jl @@ -354,3 +354,11 @@ A7933 = [1 2; 3 4] B7933 = copy(A7933) C7933 = full(Symmetric(A7933)) @test A7933 == B7933 + +# Issues #8057 and #8058 +for f in (eigfact, eigvals) + for A in (Symmetric(randn(2,2)), Hermitian(complex(randn(2,2), randn(2,2)))) + @test_throws ArgumentError f(A, 3, 2) + @test_throws ArgumentError f(A, 1:4) + end +end diff --git a/test/priorityqueue.jl b/test/priorityqueue.jl index 09de6854c831b..aae3da9b427e1 100644 --- a/test/priorityqueue.jl +++ b/test/priorityqueue.jl @@ -12,14 +12,26 @@ function test_issorted!(pq::PriorityQueue, priorities) end end +function test_isrequested!(pq::PriorityQueue, keys) + i = 0 + while !isempty(pq) + krqst = keys[i+=1] + krcvd = dequeue!(pq, krqst) + @test krcvd == krqst + end +end + pmax = 1000 n = 10000 -priorities = Dict(1:n, rand(1:pmax, n)) +r = rand(1:pmax, n) +priorities = Dict(1:n, r) # building from a dict pq = PriorityQueue(priorities) test_issorted!(pq, priorities) +pq = PriorityQueue(priorities) +test_isrequested!(pq, 1:n) # building from two lists ks, vs = 1:n, rand(1:pmax, n) diff --git a/test/ranges.jl b/test/ranges.jl index 898379c9974eb..3102b8dc4f9b7 100644 --- a/test/ranges.jl +++ b/test/ranges.jl @@ -344,3 +344,9 @@ for r in (0:1, 0.0:1.0) @test r*im == [r]*im @test r/im == [r]/im end + +# issue #7709 +@test length(map(identity, 0x01:0x05)) == 5 +@test length(map(identity, 0x0001:0x0005)) == 5 +@test length(map(identity, uint64(1):uint64(5))) == 5 +@test length(map(identity, uint128(1):uint128(5))) == 5 diff --git a/test/replcompletions.jl b/test/replcompletions.jl index 34a866fb0f018..77b265ff6a058 100644 --- a/test/replcompletions.jl +++ b/test/replcompletions.jl @@ -61,6 +61,11 @@ c,r = test_complete(s) @test r == 19:23 @test s[r] == "getin" +# inexistent completion inside a string +s = "Pkg.add(\"lol" +c,r,res = test_complete(s) +@test res == false + # test latex symbol completions s = "\\alpha" c,r = test_latexcomplete(s) @@ -96,8 +101,33 @@ c,r = test_latexcomplete(s) @unix_only begin #Assume that we can rely on the existence and accessibility of /tmp + + # Tests path in Julia code and closing " if it's a file + # Issue #8047 + s = "@show \"/dev/nul" + c,r = test_complete(s) + @test "null\"" in c + @test r == 13:15 + @test s[r] == "nul" + + # Tests path in Julia code and not closing " if it's a directory + # Issue #8047 + s = "@show \"/tm" + c,r = test_complete(s) + @test "tmp/" in c + @test r == 9:10 + @test s[r] == "tm" + + # Tests path in Julia code and not double-closing " + # Issue #8047 + s = "@show \"/dev/nul\"" + c,r = completions(s, 15) + @test "null" in c + @test r == 13:15 + @test s[r] == "nul" + s = "/t" - c,r = test_scomplete("/t") + c,r = test_scomplete(s) @test "tmp/" in c @test r == 2:2 @test s[r] == "t" diff --git a/test/runtests.jl b/test/runtests.jl index caf3c8ac7193f..9b9e3bab88dc2 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -6,10 +6,9 @@ testnames = [ "functional", "bigint", "sorting", "statistics", "spawn", "backtrace", "priorityqueue", "arpack", "file", "suitesparse", "version", "resolve", "pollfd", "mpfr", "broadcast", "complex", "socket", - "floatapprox", "readdlm", "regex", "float16", "combinatorics", + "floatapprox", "readdlm", "regex", "float16", "combinatorics", "dates", "sysinfo", "rounding", "ranges", "mod2pi", "euler", "show", - "lineedit", "replcompletions", "repl", "test", "examples", "goto", - "llvmcall", "dates" + "lineedit", "replcompletions", "repl", "test", "examples", "goto", "llvmcall" ] @unix_only push!(testnames, "unicode")