Basics Of Julia Programming Language For Data Scientists
Julia is a relatively new, fast, high-level dynamic programming language. Although it is a general-purpose language and can be used to write all kinds of applications, much of its package ecosystem and features are designed for high-level numerical computing. Julia draws from various languages, from the more low-level systems programming languages like C to high-level dynamic typing languages such as Python, R and MATLAB. And this is reflected in its optional typing nature, its syntax and its features. Register for our free hands-on workshop on oneAPI AI Analytics Toolkit Julia doesn’t have classes; it works around this by supporting the quick creation of custom types and methods for these types. However, these functions are not limited to the types they are created for and can have many versions, a feature called multiple dispatching. It supports direct calls to C functions without any wrapper API, for example, the struct keyword used to define custom types. And instead of defining scope based on indentation like Python, Julia uses the keyword end, much akin to MATLAB. It would be ridiculous to summarize all its features and idiosyncrasies; you can refer to the wiki or docs welcome page for a more comprehensive description of Julia. With that, let’s begin our journey of learning the basics of Julia and then using it to create machine learning solutions. But before we do that, you’ll need to install Julia and set up a development environment. Although Julia comes with its own REPL, much like Python IDLE, we will be using Jupyter notebooks. Here’s how to set up Julia for running it in Jupyter notebooks: Download and install Julia from its website.Open the Julia command line.Run the command using Pkg (you’ll learn more about this later).Install the Julia kernel for Jupyter using  Pkg.add("IJulia").Now when you create a Jupiter notebook and you will have an option to select Julia. Basics of Julia IO, Variables and Arithmetics Input & Output We’ll start how every programming tutorial starts with the trusty “Hello World” statement. For printing things to the terminal Julia provides the println() method. println("Hello World") Hello World To take in input from the command line you can use the (Java-inspired?) readline() and readlines() methods. Operators All arithmetic operators behave similar to their Python counterparts, except for the exponent operator, **, which is replaced by ^ in Julia. println(6 + 5) println(3 - 8) println(5 * 7) println(666 / 11) println(666 % 11) println(2 ^ 10) 11 -5 35 60.54545454545455 6 1024 Variables Variable names in Julia must start with an underscore, an alphabet, or a subset of Unicode code points greater than 00A0 . The following characters may also include ! and digits. Weirdly enough, Julia also supports using emojis and operators like + as an identifier; keep in mind that the behaviour of the operators does change after being used as an identifier. This happens because the + symbol is originally an identifier that refers to a sum function. best_num = 73 println(typeof(best_num)) π = 3.1415 println(typeof(π)) ????  = "Like a boss" println(typeof( ???? )) # doesn't work in Jupyter notebooks, try in Julia  CLI # + = "Do you know the way?" # print(+) Int64 Float64 String You can find out more about Julia’s variable naming and styling conventions here. Comments & Strings Like Python, single-line comments can be made in Julia using the # symbol, for multi-line comments, it uses the #=  =# syntax. # One line comment #= Multiple line comment=# There are two ways of defining a string in Julia; we’ve already used single quotes, “ ”, the other is is triple quotes, “”” “””. There are a few functional differences between strings enclosed in single and triple quotes. The biggest being that you can use quotes “ inside triple-quote strings without needing to escape it. "This is a string." """Look, Ma! No "errors"! """ Strings are indexable and sliceable, but the indexing starts at one. Yes, Julia uses 1-based indexing, not 0-based like Python. Wars are fought over lesser issues. Additionally, Julia provides keywords begin and end that can be used as shorthand for the first and last indices. println(s[end]) println(s[begin]) println(s[begin + 2]) println(s[2:5]) . T i his Another thing to note is the ‘ ‘ define a character, not a string. typeof('a') Char In Julia, the $ symbol is used to insert variables into a string and to evaluate expressions within a string. name = "Aditya" num_articles = 40 num_papers = 18 println("Hello, my name is $name.") println("I have written $num_articles articles and covered $num_papers research papers.") Hello, my name is Aditya. I have written 40 articles and covered 18 research papers. There are three ways of concatenating strings in Julia. The first is to use string interpolation. s1 = "How many cats " s2 = "is too many cats?" ???? = 3 println("$s1$s2") "How many cats is too many cats?" Another is to use the string() method that can also be used to convert other non-string inputs to strings. string("I don't know, but ", ????, " is too few.") "I don't know, but 3 is too few." Or use the * operator. s1*s2 You can learn more about Strings in Julia here. Data Structures Julia offers three data structures, Tuple, Arrays and Dictionaries. Functionally all of these act just like their Python counterparts; just the syntax is a bit different. Tuples Much like Python, tuples are immutable and also have a dictionary-like variant. To define a tuple an ordered collection of elements enclosed in ( ). animals = ("penguins", "cats", " kangaroo") animals[1] "penguins" Introduced in Julia 1.0, NamedTuples act just like tuples except that each element has a name associated with it.  They use a special syntax using = inside a tuple. animals = (bird = "ducks", mammal = "cats", marsupial = "kangaroo") animals.bird # animals[1] Dictionaries Dictionaries are used to store sets of data related to one another and can be created using the Dict() function and the => syntax. contacts  = Dict("Sheldon" => "732-1371", "Ghostbusters" => "555-2368") contacts["Elliot"] = "127-0001" contacts Dict{String, String} with 2 entries: "Sheldon"      => "732-1371" "Ghostbusters" => "555-2368" The pop!() method can be used to delete elements from a dictionary. pop!(contacts , "Elliot")  #we'll learn about the ! later contacts Dict{String, String} with 2 entries: "Sheldon"      => "732-1371" "Ghostbusters" => "555-2368" Arrays Arrays in Julia are ordered mutable collections that can store mixed types. They can be indexed, sliced and edited using the push!() & pop!() methods. HIMYM = ["Ted", "Barney", "Lily", "Marshall", "Robin"] fibonacci = [1, 1, 2, 3, 5, 8, 13] mix = [7, 3, "Ted", "Robyn"] HIMYM[2] = "The Lengend Himself" println(HIMYM) ["Ted", "The Lengend Himself", "Lily", "Marshall", "Robin"] push!(fibonacci, 21) push!(fibonacci, 34) pop!(fibonacci) println(fibonacci) 9-element Vector{Int64}: 1 1 2 3 5 8 13 21 The concept of shallow and deep copies persists in Julia as well, and to copy an Array, you can use the familiar copy() method. numbers = fibonacci numbers[1] = 404 println(fibonacci) [404, 1, 2, 3, 5, 8, 13, 21] fibonacci[1] = 1 numbers = copy(fibonacci) numbers[1] = 404 println(fibonacci) [1, 1, 2, 3, 5, 8, 13, 21] You can read more about data structures in Julia here. Looping & Conditionals while loops HIMYM = ["Ted", "Barney", "Lily", "Marshall", "Robin"] i = 1 while i <= length(HIMYM) friend = myfriends[i] println("Have you met $friend?") global i += 1 end Have you met Ted? Have you met Robin? Have you met Barney? Have you met Lily? Have you met Marshall? for loops The above example can be recreated using for loops as for friend in HIMYM println("Have you met $friend?") end The real power of for loops comes to light when working with multidimensional data. Let’s create additional tables to illustrate this. m, n = 5, 5 A = fill(0, (m, n)) for j in 1:n for i in 1:m A[i, j] = i + j end end println(A) Here’s a relatively more compact Julia syntax for writing nested for loops. B = fill(0, (m, n)) for j in 1:n, i in 1:m B[i, j] = i + j end println(B) And finally, the most “Julia” way using an array comprehension. C = [i + j for i in 1:m, j in 1:n] You can learn more about loops in Julia here. Conditionals Not only does Julia offer the if-else syntax it also supports the much-missed ternary operator syntax for writing conditional statements. x = 7 y = 3 if x > y x else y end is equivalent to (x > y) ? x : y You can learn more about control flow statements here. Functions Julia supports three ways of declaring functions. The first used the keywords function and end: function sayhi(name) println("Hi $name, it's great to see you!") end function f(x) x^2 end These functions can also be written as one line functions: sayhi2(name) = println("Hi $name, it's great to see you!") f2(x) = x^2 or as “anonymous” functions sayhi3 = name -> println("Hi $name, it's great to see you!") f3 = x -> x^2 Duck-typing in Julia In Julia, functions try to make do with whatever type of argument is passed to them.  For example, hello will work an integer, and f will work on a matrix or string. println(hello(55595472)) A = rand(3, 3) println(f(A)) println(f("hi")) Hello 55595472, it's great to see you! [1.098291594301114 0.5733286686511377 1.2973169349506042; 1.5089880137440685 1.0767547143728742 1.7354001978884117; 0.6092825261800483 0.5512628958029917 0.958821963007823] "hihi" Mutating and Non-Mutating Functions By convention, functions followed by a ! alter their arguments and functions without ! don’t. This is not some hard-set rule for all functions; it’s just a better and easier way of differentiating mutating functions. v = [3, 5, 2] sort(v) println(v) [3, 5, 2] sort(v) returns a sorted array, but v remains unchanged. On the other hand, sort!(v) modifies the contents of v, which are now sorted within the array v sort!(v) println(v) [2, 3, 5] Higher-Order Functions Higher-order functions are functions that take another function as an argument. Let’s go through two of the higher-order functions offered by Julia: map and broadcast. map() applies the function to each element of the data structure passed to it. println(map(x -> x^3, [1, 2, 3])) [1, 8, 27] broadcast() is a more generalized version of map(); it can do everything map() can do and more. Both functions apply a function across a data structure. The difference between the two is how they treat multidimensional arrays. println(map(+, 9, [2,2,2])) println(broadcast(+, 9, [2,2,2])) [11] [11, 11, 11] map() combines the columns first which are then used as arguments to the given function; on the other hand, broadcast() does an element-wise application of the given function. Furthermore, broadcast() also has a more concise syntax using the . operator that allows us to write complex elementwise expressions more naturally. A = [i + 3*j for j in 0:2, i in 1:3] println(A .+ 2 .* f.(A) ./ A) # instead of println(broadcast(x -> x + 2 * f(x) / x, A)) [3.0 6.0 9.0; 12.0 15.0 18.0; 21.0 24.0 27.0] [3.0 6.0 9.0; 12.0 15.0 18.0; 21.0 24.0 27.0] You can read more about functions in Julia here. Working with Packages in Julia Julia has over 2000 packages, which sounds like a lot but compared to Python’s whopping 1,37,000, the package ecosystem still has some growing to do. That being said Julia has first-class function calls to other languages; these provide foreign function interfaces. You can easily call into Python or R, for example, with PyCall or Rcall.  This enables developers to use their trusted favourite package/library from other languages. To see all available packages, check out: https://pkg.julialang.org/https://juliaobserver.com/ To use a package in a Julia installation, you’ll need to use the package manager, Pkg, to add it explicitly. You have already installed the package “IJulia” at the beginning of the article. Now let’s briefly see one of the best Julia packages I have encountered in my limited experience: the Plots.jl package that enables developers to switch between backends while using the same API seamlessly. We’ll illustrate this by using GR and Plotly backends, but first, let’s add the package and “import” it using the “using” command. using Pkg Pkg.add("Plots") using Plots and create some dummy data to plot. price = [14.4, 14.5, 14.8, 15.2, 15.5, 15.8] quantity = [45000, 20000, 15000, 5000, 400, 17] Pkg.add("GR") gr() #switching backend plot(quantity, price, label="line") scatter!(quantity, price, label="points") Notice how we use scatter!() and not scatter(); if we were to use the non-mutating variant, it would create a new plot with only the scatter plot. Pkg.add("PlotlyJS") plotlyjs() #switching backend You can get the Jupyter notebook with the above code here. I couldn’t get Julia to work on Colab; let me know if you have any luck. Last Epoch This article gave a brief overview of the basics syntax and features of Julia. Among the ones it covered, some things are extremely useful and intuitive. Like the use of ! symbol to indicate mutating functions or the compact . symbol syntax of the broadcast() method. On the other hand, there are also some icky choices like the use of * for concatenating strings or the use of the cumbersome => in dictionaries. (This all comes from a very Python-biased perspective.) That being said, Julia does have a lot of promise in its ability to interact with other languages seamlessly and run even devectorized code as fast as C. Furthermore, it’s still early in its development process, it isn’t even a decade old. It will evolve over the next decade or so. As for us, over the next few weeks, we’ll cover more Julia Packages and use them to create various machine learning and deep learning models.
Julia is a relatively new, fast, high-level dynamic programming language. Although it is a general-purpose language and can be used to write all kinds of applications, much of its package ecosystem and features are designed for high-level numerical computing. Julia draws from various languages, from the more low-level systems programming languages like C to high-level […]
Julia is a relatively new, fast, high-level dynamic programming language. This article gives a brief overview of the basics of Julia; its syntax and features.
["Julia Language", "julia scientific programming"]
["machine learning", "Plotly", "AWS", "AI", "ML", "Colab", "Julia Language", "Ray", "deep learning", "analytics", "Jupyter", "julia scientific programming"]
["AI", "machine learning", "ML", "deep learning", "analytics", "Ray", "Jupyter", "Colab", "Plotly", "AWS"]
A machine learning enthusiast with a knack for finding patterns. In my free time, I like to delve into the world of non-fiction books and video essays.