Julia v1.4.0-rc1 is now available

The first release candidate for Julia v1.4.0 is now available. You can get binaries at Download Julia for Linux (i686, x86-64, ARMv7, AArch64), macOS, FreeBSD (x86-64), and Windows (32-, 64-bit). Check out the NEWS file to see what will be new in 1.4.0.

As a release candidate, this should not be considered production-ready. Rather, it’s intended to give users a chance to try out their code with 1.4.0 prior to a full release. Note that 1.4 on Travis, AppVeyor (with Appveyor.jl), and Cirrus (with CirrusCI.jl) now points to 1.4.0-rc1.

Let us know in the issue tracker if you run into any issues. (Note that any bugs you may encounter should be posted there rather than being discussed in this thread for developer visibility.) Assuming no problems arise with this release candidate, we’ll move forward with a full 1.4.0 release soon.

52 Likes

That a[begin] feature is interesting and confusing to me. What’s the motivation for it? How is it different from a[1]? I read through issue #33946 but couldn’t find a good reason.

1 Like

Not every AbstractArray begins at 1. The most trivial example is GitHub - JuliaArrays/OffsetArrays.jl: Fortran-like arrays with arbitrary, zero or negative starting indices. but there are others which may not even be indexed by integers.

13 Likes

Should then be possible to consider a[:4] (and a[4:]) like in Python instead of throwing an error, or would be breaking existing code?

1 Like

You mean as shortcut for a[begin:4] and a[4:end]? While I see that it’s a bit shorter than the (new) 1.4 style, I find it harder to read aswell. And it begins to fail once you want to use variables:

currentendindex = 5
a[:currentendindex]
#-> Error, here, getindex is not defined for symbol

OTOH trying to resemble python hasn’t been the target at any time :smiley:. And the new syntax with begin and end just feels very clear & concise IMO.

8 Likes

Hi!

I have activated 1.4 in travis, but I get the following error:

$ curl -A "$CURL_USER_AGENT" -sSf -L --retry 7 'https://julialang-s3.julialang.org/bin/linux/x64/1.4/julia-1.4-latest-linux-x86_64.tar.gz' | tar -C ~/julia -x -z --strip-components=1 -f -
curl: (22) The requested URL returned error: 404 Not Found

You can see the full log of my build at:
https://travis-ci.com/gridap/Gridap.jl/jobs/279625250?utm_medium=notification&utm_source=email

Consider the possibility where you would use a variable instead of a literal integer, eg

i = 3
a[:i]

and you will see that it is problematic since :i is a symbol.

@jonathan-durbin: note that the introduction of begin has been in the works for a long time. If you want to participate in these discussions, it is best to subscribe to notifications from the Julia repository.

10 Likes

I am being a bit dumb…, a link to the new features/Changelog for 1.4.0-rc1 would be useful.

1 Like

Yes, it’s a bit confusing, it’s already history:
https://github.com/JuliaLang/julia/blob/master/HISTORY.md#julia-v14-release-notes

2 Likes

See also Julia v1.4 Release Notes · The Julia Language

2 Likes

And RandomBasedArrays can start with any number, in fact a different one every time you try to access an element.

5 Likes

Pre-release binaries are not available under those URLs

1 Like

I have a somewhat strange problem with 1.4 rc1. Consider the following

julia> g(S,e,p)=S[1 + map(x->mod(x, e), -p)]
g (generic function with 1 method)

julia> s="g(S,e,p)=S[1 + map(x->mod(x, e), -p)]"
"g(S,e,p)=S[1 + map(x->mod(x, e), -p)]"

julia> print(Meta.parse(s,1)[1])
g(S, e, p) = begin
        #= none:1 =#
        S[1 + map((x->(#= none:1 =#;
                            mod(x, e))), -p)]
    end

now copy and paste the output of the last print to the REPL

julia> g(S, e, p) = begin
               #= none:1 =#
               S[1 + map((x->(#= none:1 =#;
                                   mod(x, e))), -p)]
           end
ERROR: syntax: invalid named tuple element "mod(x, e)"
Stacktrace:
 [1] top-level scope at REPL[48]:1

This does not happen in 1.3, but what happens is still a bit funny

julia> print(Meta.parse(s,1)[1])
g(S, e, p) = begin
        #= none:1 =#
        S[1 + map((x->begin
                            #= none:1 =#
                            mod(x, e)
                        end), -p)]
    end
julia> g(S, e, p) = begin
               #= none:1 =#
               S[1 + map((x->begin
                                   #= none:1 =#
                                   mod(x, e)
                               end), -p)]
           end
┌ Warning: Deprecated syntax `"begin" inside indexing expression` at REPL[3]:3.
└ @ REPL[3]:3
g (generic function with 1 method)

Anyway, this change has broken my automatic Gap to Julia translator (which works fine in 1.3, despite outputting sometimes the warning above), so I would like to understand what is going on.

Thanks in advance for any help…

There shouldn’t be a semicolon after the comment #= none:1 =#. I’ll see if I can put together a PR to fix this.

1 Like

Thanks for the info!

However, I do not understand what means this sentence in the original mesage:

Note that 1.4 on Travis, AppVeyor (with Appveyor.jl ), and Cirrus (with CirrusCI.jl) now points to 1.4.0-rc1.

Is it possible to run 1.4.0-rc1 on Travis? I have tried to replace 1.3 by 1.4 in my .travis.yml file, and it didn’t work.

What doesn’t work?

Did the stream of rand(Base.OneTo(n)) change? Julia 1.3:

               _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _\ |  |
  | | |_| | | | (_| |  |  Version 1.3.0 (2019-11-26)
 _/ |\__'_|_|_|\__'_|  |  Official https://julialang.org/ release
|__/                   |

julia> using Random; Random.seed!(1); rand(Base.OneTo(6))
1

Julia 1.4rc1:

               _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _\ |  |
  | | |_| | | | (_| |  |  Version 1.4.0-rc1.0 (2020-01-23)
 _/ |\__'_|_|_|\__'_|  |  
|__/                   |

julia> using Random; Random.seed!(1); rand(Base.OneTo(6))
3

In https://github.com/JuliaLang/julia/blob/v1.4.0-rc1/NEWS.md#random only rand(::Tuple) is mentioned, but as far as I can tell that’s not the same thing (unless rand(Base.OneTo(n)) is implemented as rand(::Tuple) under the hood)

rand(::Tuple) uses Base.OneTo, and there was an inefficiency in rand(::MersenneTwister, ::OneTo) (which was an oversight), now fixed. I simply forgot to put it in the NEWS.md file, or just thought Base.OneTo was not an official API (which apparently it seems to be).

1 Like

Well, in RandomBasedArrays.jl I’m using rand(eachindex(p)) (reference) to get a random index, and tests are failing in 1.4 because of the different stream of numbers.

Maybe OneBaseTo is not official API but it’s used by official API.

BTW: is there a good way to test random numbers that doesn’t rely on the stream of random numbers being the same forever?

If your functions take rng as an argument, you can create your own AbstractRNG implementation for testing purposes which just returns numbers in sequence pulled from e.g. const nums = [5837, 432, ..]. I think such an implementation would be a worthwhile package–something like MockRandom.