diff --git a/NEWS.md b/NEWS.md index a4189e1e67afe0..037200a2087f47 100644 --- a/NEWS.md +++ b/NEWS.md @@ -26,6 +26,10 @@ New language features `@generated` and normal implementations of part of a function. Surrounding code will be common to both versions ([#23168]). + * The `missing` singleton object (of type `Missing`) has been added to represent + missing values ([#24653]). It propagates through standard operators and mathematical functions, + and implements three-valued logic, similar to SQLs `NULL` and R's NA`. + Language changes ---------------- @@ -1666,3 +1670,4 @@ Command-line option changes [#24320]: https://github.com/JuliaLang/julia/issues/24320 [#24396]: https://github.com/JuliaLang/julia/issues/24396 [#24413]: https://github.com/JuliaLang/julia/issues/24413 +[#24653]: https://github.com/JuliaLang/julia/issues/24653 \ No newline at end of file diff --git a/doc/src/manual/noteworthy-differences.md b/doc/src/manual/noteworthy-differences.md index 26954d159b59c2..ae2506efd40fb1 100644 --- a/doc/src/manual/noteworthy-differences.md +++ b/doc/src/manual/noteworthy-differences.md @@ -15,9 +15,7 @@ may trip up Julia users accustomed to MATLAB: can create the array `a = [0 0 0 3.2]` and `a(5) = 7` can grow it into `a = [0 0 0 3.2 7]`, the corresponding Julia statement `a[5] = 7` throws an error if the length of `a` is less than 5 or if this statement is the first use of the identifier `a`. Julia has [`push!`](@ref) and [`append!`](@ref), - which grow `Vector`s much more efficiently than MATLAB's `a(end+1) = val`. - * The imaginary unit `sqrt(-1)` is represented in Julia as [`im`](@ref), not `i` or `j` as in MATLAB. - * In Julia, literal numbers without a decimal point (such as `42`) create integers instead of floating + which grow `Vector`s much more efficiently than * In Julia, literal numbers without a decimal point (such as `42`) create integers instead of floating point numbers. Arbitrarily large integer literals are supported. As a result, some operations such as `2^-1` will throw a domain error as the result is not an integer (see [the FAQ entry on domain errors](@ref faq-domain-errors) for details). @@ -180,7 +178,10 @@ For users coming to Julia from R, these are some noteworthy differences: code is often achieved by using devectorized loops. * Julia is eagerly evaluated and does not support R-style lazy evaluation. For most users, this means that there are very few unquoted expressions or column names. - * Julia does not support the `NULL` type. + * Julia does not support the `NULL` type. The closest equivalent is [`nothing`](@ref), but it + behaves like a scalar value rather than like a list. Use `x == nothing` instead of `is.null(x)`. + * In Julia, missing values are represented by the [`missing`](@ref) object rather than by `NA`. + Use [`ismissing(x)`](@ref) instead of `isna(x)`. * Julia lacks the equivalent of R's `assign` or `get`. * In Julia, `return` does not require parentheses. * In R, an idiomatic way to remove unwanted values is to use logical indexing, like in the expression diff --git a/test/ambiguous.jl b/test/ambiguous.jl index c8aacfabb474aa..5d6e7ebf09c2ba 100644 --- a/test/ambiguous.jl +++ b/test/ambiguous.jl @@ -286,6 +286,8 @@ end pop!(need_to_handle_undef_sparam, which(Base.convert, Tuple{Type{Union{Missing, T}} where T, Any})) pop!(need_to_handle_undef_sparam, which(Base.promote_rule, Tuple{Type{Union{Missing, S}} where S, Type{T} where T})) pop!(need_to_handle_undef_sparam, which(Base.zero, Tuple{Type{Union{Missing, T}} where T})) + pop!(need_to_handle_undef_sparam, which(Base.one, Tuple{Type{Union{Missing, T}} where T})) + pop!(need_to_handle_undef_sparam, which(Base.oneunit, Tuple{Type{Union{Missing, T}} where T})) @test need_to_handle_undef_sparam == Set() end end diff --git a/test/missing.jl b/test/missing.jl index 2c599ee326abd3..a2ea8e3b1eaba9 100644 --- a/test/missing.jl +++ b/test/missing.jl @@ -134,6 +134,10 @@ Base.one(::Type{Unit}) = 1 @test oneunit(Union{T, Missing}) === T(1) end + @test_throws MethodError zero(Union{Symbol, Missing}) + @test_throws MethodError one(Union{Symbol, Missing}) + @test_throws MethodError oneunit(Union{Symbol, Missing}) + for T in (Unit,) @test zero(Union{T, Missing}) === T(0) @test one(Union{T, Missing}) === 1