Julia 1.0 has now been released
8 Aug 2018 London - The much anticipated 1.0 release of Julia is the culmination of nearly a decade of work to build a language for greedy programmers. The JuliaCon2018 event celebrated the event with a reception where the community officially set the version to 1.0.0 together.
Julia was first publicly announced with a number of strong demands on the language. The community requested a language that is open source and with a liberal license. The language requires the speed of C with the dynamism of Ruby. It has to be homoiconic, with true macros like Lisp, but with obvious, familiar mathematical notation like Matlab. The community wanted something as usable for general programming as Python, as easy for statistics as R, as natural for string processing as Perl, as powerful for linear algebra as Matlab, as good at gluing programmes together as the shell. The language should be easy to learn and keep the most serious hackers happy. It should be interactive and compiled.
A vibrant and thriving community has grown up around this language, with people from all around the world iteratively refining and shaping Julia in pursuit of that goal. Over 700 people have contributed to Julia itself and even more people have made thousands of amazing open source Julia packages.
Now, the community has built a language that is:
- Fast: Julia was designed from the beginning for high performance. Julia programmes compile to efficient native code for multiple platforms via LLVM.
- General: It uses multiple dispatch as a paradigm, making it easy to express many object-oriented and functional programming patterns. The standard library provides asynchronous I/O, process control, logging, profiling, a package manager, and more.
- Dynamic: Julia is dynamically-typed, feels like a scripting language, and has good support for interactive use.
- Technical: It excels at numerical computing with a syntax that is great for math, many supported numeric data types, and parallelism out of the box. Julia's multiple dispatch is a natural fit for defining number and array-like data types.
- Optionally typed: Julia has a rich language of descriptive data types, and type declarations can be used to clarify and solidify programmes.
- Composable: Julia's packages naturally work well together. Matrices of unit quantities, or data table columns of currencies and colours, just work, and with good performance.
The single most significant new feature in Julia 1.0, of course, is a commitment to language API stability: code you write for Julia 1.0 will continue to work in Julia 1.1, 1.2, etc. The language is "fully baked". The core language devs and community alike can focus on packages, tools, and new features built upon this solid foundation.
Julia 1.0 in not just about stability, it also introduces several new, powerful and innovative language features. Some of the new features since version 0.6 include:
- A brand new built-in package manager brings enormous performance improvements and makes it easier than ever to install packages and their dependencies. It also supports per-project package environments and recording the exact state of a working application to share with others - and with your future self. Finally, the redesign also introduces seamless support for private packages and package repositories. You can install and manage private packages with the same tools as youre used to for the open source package ecosystem. The presentation at JuliaCon provides a good overview of the new design and behaviour.
- Julia has a new canonical representation for missing values. Being able to represent and work with missing data is fundamental to statistics and data science. In typical Julian fashion, the new solution is general, composable and high-performance. Any generic collection type can efficiently support missing values simply by allowing elements to include the pre-defined value missing. The performance of such "union-typed" collections would have been too slow in previous Julia versions, but compiler improvements now allow Julia to match the speed of custom C or C++ missing data representations in other systems, while also being far more general and flexible.
- The built-in String type can now safely hold arbitrary data. Your programme won't fail hours or days into a job because of a single stray byte of invalid Unicode. All string data is preserved while indicating which characters are valid or invalid, allowing your applications to safely and conveniently work with real world data with all of its inevitable imperfections.
- Broadcasting is already a core language feature with convenient syntax - and it is now more powerful than ever. In Julia 1.0 it is simple to extend broadcasting to custom types and implement efficient optimized computations on GPUs and other vectorized hardware, paving the way for even greater performance gains in the future.
- Named tuples are a new language feature which make representing and accessing data by name efficient and convenient.
- The dot operator can now be overloaded, allowing types to use the obj.property syntax for meanings other than getting and setting struct fields. This is especially useful for smoother interop with class-based languages such as Python and Java. Property accessor overloading also allows the syntax for getting a column of data to match named tuple syntax: you can write table.version to access the version column of a table just as row.version accesses the version field of a single row.
- Julia's optimizer has gotten smarter. A few highlights are worth mentioning. The optimizer can now propagate constants through function calls, allowing much better dead-code elimination and static evaluation than before. The compiler is also much better at avoiding allocation of short-lived wrappers around long-lived objects, which frees programmers to use convenient high-level abstractions without performance costs.
- Parametric type constructors are now always called with the same syntax as they are declared. This eliminates an obscure but confusing corner of language syntax.
- The iteration protocol has been completely redesigned to make it easier to implement many kinds of iterables. Instead of defining methods of three different generic functions - start, next, done - one now defines one-and two-argument methods of the iterate function. This often allows iteration to be conveniently defined with a single definition with a default value for the start state. More importantly, it makes it possible to implement iterators that only know if they are done once they have tried and failed to produce a value. These kinds of iterators are ubiquitous in I/O, networking, and producer/consumer patterns; Julia can now express these iterators in a straightforward and correct manner.
- Scope rules have been simplified. Constructs that introduce local scopes now do so consistently, regardless of whether a global binding for a name already exists or not. This eliminates the "soft/hard scope" distinction that previously existed and means that now Julia can always statically determine whether variables are local or global.
- The language itself is significantly leaner, with many components split out into "standard library" packages that ship with Julia but are not part of the "base" language. In the future, this will also allow standard libraries to be versioned and upgraded independently of Julia itself, allowing them to evolve and improve at a faster rate.
The community has performed a thorough review of all of Julia's APIs to improve consistency and usability. Many obscure legacy names and inefficient programming patterns have been renamed or refactored to more elegantly match Julia's capabilities. This has prompted changes to make working with collections more consistent and coherent, to ensure that argument ordering follows a consistent standard throughout the language, and to incorporate faster keyword arguments into APIs where appropriate.
A number of new external packages are being built specifically around the new capabilities of Julia 1.0. For example:
- The data processing and manipulation ecosystem is being revamped to take advantage of the new missingness support.
- Cassette.jl provides a powerful mechanism to inject code-transformation passes into Julia's compiler, enabling post-hoc analysis and extension of existing code. Beyond instrumentation for programmers like profiling and debugging, this can even implement automatic differentiation for machine learning tasks.
- Heterogeneous architecture support has been greatly improved and is further decoupled from the internals of the Julia compiler. Intel KNLs just work in Julia. Nvidia GPUs are programmed using the CUDANative.jl package, and a port to Google TPUs is in the works.
There are countless other improvements, both large and small. More information and download are available at the Julia website.