Introducing Julia/The REPL

From Wikibooks, open books for an open world
Jump to: navigation, search
« Introducing Julia
The REPL
»
Getting started Array and tuples

The REPL[edit]

The julia program starts the interactive REPL, the Read/Evaluate/Print/Loop, by default. It lets you type expressions in Julia code and see the results of the evaluation printed on the screen immediately. It:

  • Reads what you type
  • Evaluates it
  • Prints out the return value, then
  • Loops back and does it all over again

The REPL is a great place to start experimenting with the language. But it's not the best environment to do serious programming work of any scale in – for that, a text editor, or interactive notebook environment (e.g. IJulia/Jupyter) is a better choice. But there are advantages to using the REPL: it's simple, and should work without any installation or configuration. There's a built-in help system, too.

Using the REPL[edit]

You type some Julia code and then press Return/Enter. Julia evaluates what you typed and returns the result:

julia> 42 <Return/Enter>
42

julia>

If you're using the Jupyter (IPython) notebook, you probably have to type Control-Enter, or Shift-Enter.

If you don't want to see the result of the expression printed, use a semicolon at the end of the expression:

julia> 42;

julia>

Also, if you want to access the value of the last expression you typed on the REPL, it's stored within the variable ans:

julia> ans
42

If you don't complete the expression on the first line, continue typing until you finish. For example:

julia> 2 +  <Return/Enter>

now Julia waits patiently until you finish the expression:

2  <Return/Enter>

and then you'll see the answer:

4

julia>


Help and searching for help[edit]

Type a question mark ?

julia> ?

and you'll immediately switch to Help mode, and the prompt changes to yellow (in the terminal):

help?>

Now you can type the name of something (function names should be written without parentheses):

   help?> quit
   search: quit QuickSort PartialQuickSort quantile quantile!
   
     quit()
    
     Quit the program indicating that the processes completed successfully. This function calls exit(0) (see exit).

   julia>

Notice that the help system has tried to find all the words that match the letters you typed, and shows you what it found.

If you want to search the documentation, you can use apropos and a search string:

julia> apropos("determinant")
Base.LinAlg.logabsdet
Base.LinAlg.det
Base.LinAlg.logdet

You'll see a list of functions whose names or descriptions contain the string.

julia> apropos("Pearson")
Base.cor
help?> cor
search: cor Core xcorr VecOrMat factor Vector vecnorm factorize factorial Factorization DenseVecOrMat @vectorize_2arg

 cor(x)
 
 Return the number one.
 
 cor(X[, vardim=1])
 
 Compute the Pearson correlation matrix of the matrix X along the dimension vardim.
 
 cor(x, y)
 
 Compute the Pearson correlation between the vectors x and y.
 
 cor(X, Y[, vardim=1])
 
 Compute the Pearson correlation between the vectors or matrices X and Y along the dimension
 vardim.

Shell mode[edit]

If you type a semicolon

julia> ;

you immediately switch to shell mode:

shell>

(And the prompt changes to red). In shell mode you can type any shell (ie non-Julia) command and see the result:

shell> ls
file.txt   executable.exe   directory file2.txt

julia>

then the prompt switches back to julia>, so you have to type a semicolon every time you want to give a shell command. The commands available within this mode are the ones used by your system's shell.

Orientation[edit]

Here are some other useful interactive functions and macros available at the REPL-prompt:

  • whos() – prints information about the current global symbols
julia> whos()
                         Base  20691 KB     Module : Base
                       Compat     39 KB     Module : Compat
                         Core   2735 KB     Module : Core
               DataStructures    215 KB     Module : DataStructures
                       IJulia    133 KB     Module : IJulia
               IPythonDisplay     18 KB     Module : IPythonDisplay 
                         JSON    111 KB     Module : JSON
                         Main  24321 KB     Module : Main
                       Nettle    147 KB     Module : Nettle
                          ZMQ     62 KB     Module : ZMQ
  • @which – tells you which method will be called for a function and particular arguments:
julia> @which sin(3)
sin(x::Real) in Base.Math at math.jl:418
  • versioninfo() – gets Julia version and platform information:
julia> versioninfo()

Julia Version 0.6.0-pre.alpha.0
Commit 29bc2ac (2017-02-28 13:15 UTC)
Platform Info:
  OS: macOS (x86_64-apple-darwin13.4.0)
  CPU: Intel(R) Core(TM) i5-2500S CPU @ 2.70GHz
  WORD_SIZE: 64
  BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY Sandybridge)
  LAPACK: libopenblas64_
  LIBM: libopenlibm
  LLVM: libLLVM-3.9.1 (ORCJIT, sandybridge)

There's also a quick way to find out the version:

julia> VERSION
v"0.6.0-pre.alpha.0"
  • edit("pathname") – edits the file pathname
  • @edit rand() – edits the definition of the built-in function rand() in your default editor
  • less("filename-in-current-directory") – displays a file
  • clipboard("stuff") – copies "stuff" to the system clipboard
  • clipboard() – pastes the contents of the keyboard into the current REPL line
  • dump(x) – displays information about a Julia object x on the screen
  • names(x) – gets an array of the names exported by the module x
  • fieldnames(x) – gets an array of the data fields that belong to the symbol x
  • workspace() – replaces the top-level module (Main) with a new one, with a clean workspace

The <TAB> key: autocompletion[edit]

The TAB key is usually able to complete – or suggest a completion for – something whose name you start typing. For example, if I type w and then press the TAB key (press twice when there are multiple options), all the functions that are currently available beginning with 'w' are listed:

julia> w <TAB>
wait       warn        which       whos        widen       workers     write       writedlm
walkdir    watch_file  while       widemul     withenv     workspace   writecsv

This works both for Julia entities and in shell mode. Here, for example, is how I can navigate to a directory from inside Julia:

shell> cd ~
/Users/me

shell> cd Doc <TAB>
shell> cd Documents/

shell> ls
...

Remember you can get help about functions using ? and typing in its full name (or using TAB-completion).

TAB-completion also works for Unicode-symbols, e.g. type \alp and press TAB to get \alpha and then press TAB again to get α.

History[edit]

You can look back through a record of your previous commands using the Up and Down arrow keys (and you can quit and restart without erasing that history). So you don't have to type a long multi-line expression again, because you can just recall it from history. And if you've typed loads of expressions, you can search through them, both back and forwards, by pressing Ctrl-R and Ctrl-S.

Scope and performance[edit]

One warning about the REPL. The REPL operates at the global scope level of Julia. Usually, when writing longer code, you would put your code inside a function, and organise functions into modules and packages. Julia's compiler works much more effectively when your code is organized into functions, and your code will run much faster as a result. There are also some things that you can't do at the top level – such as specify types for the values of variables.

Changing the prompt[edit]

You can change the prompt from julia> to something else, such as >. The easiest way to do this is to check out the Julia package OhMyREPL.jl on GitHub which lets you customize the REPL's appearance and behaviour.

If you just want to set the prompt every time you start a Julia session, you can add this to your '.juliarc.jl start-up file.

function myrepl(repl)
    repl.interface = REPL.setup_interface(repl)
    repl.interface.modes[1].prompt = "julia-$(VERSION.major).$(VERSION.minor)> "
    return
end

atreplinit(myrepl)

This sets the current REPL prompt to show the Julia version number that you're using.

Julia and mathematics[edit]

You can use Julia as a powerful calculator, using the REPL. It's good practice, too. (This is a tradition in introductions to interactive programming languages, and it's a good way to meet the language.)

Typing long numbers[edit]

Half the world uses a comma (,) to divide long numbers into groups of three, the other half uses a period (.). (And the rest of us use scientific notation...) In Julia you can use an underscore (_) to separate groups:

julia> 1_000_000 - 2_015
997985

although you won't see one in the response.

To use scientific notation, just type "e" and remember to avoid spaces:

julia> planck_length = 1.61619997e-34

How fast is my computer in gigaflops?

julia> peakflops() / 1e9
48.778354495441356
 
julia> peakflops() / 1e9
54.20509453559899

(Notice how the second time is faster!)

Operators as functions[edit]

julia> 2 + 2
4

julia> 2 + 3 + 4
9

An equivalent form for adding numbers is:

julia> +(2, 2)
4

The operators that you usually use between values are ordinary Julia functions, and can be used in the same way as other functions. Similarly:

julia> 2 + 3 + 4
9

can be written as

julia> +(2, 3, 4)
9

and

julia> 2 * 3 * 4
24

can be written as

julia> *(2,3,4)
24

Some maths constants are provided:

julia> pi
π = 3.1415926535897...

julia> golden
φ = 1.6180339887498...

julia> e
e = 2.7182818284590...

All the usual operators are available:

julia> 2 + 3 - 4 * 5 / 6 % 7
1.6666666666666665

Notice the precedence of the operators. In this case it's:

((2 + 3) - ((4 * 5) / 6) % 7)

Multiplication is usually written *, but this can be omitted when multiplying a variable by a number literal:

julia> x = 2
2

julia> 2x + 1
5

This makes equations much easier to write.

You'll sometimes need parentheses to control the evaluation order:

julia> (1 + sqrt(5)) / 2
1.618033988749895

Some others to watch out for include:

  • ^ power
  • % remainder/modulo

To make rational numbers, use two slashes (//):

julia> x = 666//999
2//3

There's also reverse division "\", so that x/y = y\x.

The standard arithmetic operators also have special updating versions, which you can use to update variables quickly:

  • +=
  • -=
  • *=
  • /=
  • \=
  • %=
  • ^=

For example, after defining a variable x:

julia> x = 5
5

you can add 2 to it like this:

julia> x += 2
7

multiply it by 100 like this:

julia> x *= 100
700

and reduce it to its modulus 11 value:

julia> x %= 11
7

There are element-wise operators which work on arrays. This means that you can multiply two arrays element by element:

julia> [2,4] .* [10, 20]
2-element Array{Int64,1}:
 20
 80

Arrays are fundamental to Julia, and so have their own chapter in this book.

If you divide two integers using /, the answer is always a floating-point number. If you're familiar with Python version 2, this is a difference to be aware of:

Python 2.7.10 (default, Aug 22 2015, 20:33:39)
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.59.1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 3/2
1

Here Python returns an integer result, whereas Julia returns a float:

julia> 3/2
1.5

julia> 8/2
4.0

(Python 3 also returns a float here.)

Julia offers an integer division operator ÷ (type \div TAB, or use the function version div(). This should be used when you want an integer result rather than the floating-point returned by /.

julia> 3 ÷ 2
1

julia> div(3, 2)
1

Integer overflow[edit]

If you think your calculations are going to burst out of the 64-bit restriction, choose Big Integers by applying the big function to store the operands as big numbers:

julia> 2^64 # oops 0

julia> big(2)^64 # better 18446744073709551616

julia> 2^big(64) # equally better 18446744073709551616

To get the fastest execution speeds for your Julia programs, you should be aware of how your data and variables can be stored without introducing 'type instability'.

Number bases[edit]

These handy utility functions might come in useful when using the REPL as a calculator.

The bits() function shows the literal binary representation of a number, as stored:

julia> bits(20.0)
"0100000000110100000000000000000000000000000000000000000000000000"

julia> bits(20)
"0000000000000000000000000000000000000000000000000000000000010100"

Notice that the floating point 'version' is stored differently.

To go from a binary string back to decimal, you can use parse(), which accepts a target type and number base:

julia> parse(Int, "0000011", 2)
3 
julia> parse(Int, "defaced", 16)
233811181

For working in bases other than the default 10, try hex() and oct():

julia> hex(65535)
"ffff"
julia> oct(64)
"100"

The function base(base, number) converts a number to a string in the given base:

julia> base(16,255)
"ff"

Whereas digits(number, base) returns an array of the digits of number in the given base:

julia> digits(255, 16)
2-element Array{Int64,1}:
 15
 15

Here's a good place to mention num2hex() and hex2num(), functions used to convert between a hexadecimal string and the binary representation of the equivalent floating-point number.

Variables[edit]

In this expression:

julia> x = 3

x is a variable, a named storage location for a data object. In Julia, variables can be named pretty much how you like, although don't start variable names with numbers or punctuation. You can use Unicode characters, if you want.

To assign a value, use a single equals sign.

julia> a = 1
1

julia> b = 2
2

julia> c = 3
3

To test equality, you should use the == operator or isequal() function.

You should avoid using names that Julia has already taken. For example, words like mean and median are used for imported function names, but Julia doesn't stop you redefining them – although you might see a message warning you of possible problems ahead.

julia> mean = 0
Warning: imported binding for mean overwritten in module Main
0

If you make this mistake, you can restore the original meaning like this, if mean is a function in the Base module:

julia> mean = Base.mean
mean (generic function with 6 methods)

In Julia, you can also assign multiple variables at the same time:

julia> a, b = 5, 3
(5,3)

Notice that the return value of this expression is a parenthesis-bounded comma-separated ordered list of elements: tuple for short.

julia> a
5

julia> b
3
Multiplying numbers and variables[edit]

It's worth repeating that you can preface a variable name with a number to multiply them, without having to use an asterisk (*). For example:

julia> x = 42
42

julia> 2x
84

julia> .5x
21.0

julia> 2pi
6.283185307179586

You can use \cdot (see the next section) to provide the "dot" multiplication operator:

julia> 4 ⋅ 5
20

(\times produces the cross-product operator.)

Special characters[edit]

The Julia REPL provides easy access to special characters, such as Greek alphabetic characters, subscripts, and special maths symbols. If you type a backslash, you can then type a string (usually the equivalent LATEX string) to insert the corresponding character. For example, if you type:

julia> \sqrt <TAB>

Julia replaces the \sqrt with a square root symbol:

julia> 

Some other examples:

\Gamma Γ
\mercury
\degree °
\cdot
\in

There's a full list in the Julia source code, which you can find at julia/latex_symbols.jl. As a general principle, in Julia you're encouraged to look at the source code, so there are useful built-in functions for looking at Julia source files. For example, on macOS the Julia source files are stored in /Applications/Julia-0.6.app/Contents/Resources/julia/share/julia/base. So:

julia> less("/Applications/Julia-0.6.app/Contents/Resources/julia/share/julia/base/latex_symbols.jl") # macOS only

runs the file through a pager (ie the less command in Unix). If you're brave, try using edit() rather than less(). This launches an editor and opens the file.

It's also possible to use emoji and other Unicode characters in the REPL.

For emoji, type the Emoji character name, between colons, after the backslash, then press <TAB>:

julia> \:id: <TAB>

which changes to:

julia> 🆔

You can find a list at https://docs.julialang.org/en/latest/manual/unicode-input.html#Unicode-Input-1.

Entering Unicode symbols that aren't in this list is possible but more OS-dependent: on macOS you 'hold down' the Ctrl/Alt key while typing the Unicode hex digits; on Windows it's Ctrl+Shift+u followed by the hex digits.)

julia> ✎ = 3
3

julia> 
3

Maths functions[edit]

Because Julia is particularly suited for scientific and technical computing, there are many mathematical functions that you can use immediately, and you don't have to import them or use prefixes – they're already available in the Base module.

The trigonometry functions expect values in radians:

julia> sin(pi / 2)
1.0

but there are degree-based versions too: sind(90) finds the sine of 90 degrees. Use deg2rad() and rad2deg() to convert between degrees and radians.

There are also lots of log functions:

julia> log(12)
2.4849066497880004

and the accurate hypot() function:

julia> hypot(3,4)
5.0

The norm() function returns the "p"-norm of a vector or the operator norm of a matrix. Here's divrem():

julia> divrem(13,3) # returns the division and the remainder
(4,1)

There are dozens of others. Special functions include erf(), dawson(), eta(), zeta(), a full collection of Bessel functions, and so on.

There's a system-wide variable called ans that remembers the most recent result, so that you can use it in the next expression.

julia> 1 * 2 * 3 * 4 * 5
120

julia> ans/10
12.0

Statistics functions[edit]

In the statistics realm, all the basic statistics functions are built-in. For example:

julia> mean([1, 2, 3, 4, 5, 6, 7, 8])
4.5

You'll also find:

cor() find the Pearson correlation
cov() find the covariance
mean() find the mean of an array
std() find the standard deviation of an array
var() find the variance
median() find the median

among many others, and there are many more available in the StatsBase.jl package.

Exercise[edit]

Guess, then find out using the help system, what mod2pi() and isapprox() do.

Descriptions of all the functions provided as standard with Julia are described here: [1]

Random numbers[edit]

rand() – gets one random Float64 between 0 and 1

julia> rand()
0.11258244478647295

rand(2, 2) – an array of Float64s with dimensions 2, 2

rand(type, 2, 2) – an array of values of this type with dims 2, 2

rand(range, dims) – array of numbers in a range (including both ends) with specified dimensions:

julia> rand(0:10, 6)
6-element Array{Int64,1}:
 6
 7
 9
 6
 3
 10

(See the Arrays chapter for more about range objects.)

The rand() function can generate a true or false value if you tell it to, by passing the Bool keyword:

julia> rand(Bool)
false

or a bunch of trues and falses:

julia> rand(Bool, 20)
20-element Array{Bool,1}:
 false
 true
 false
 false
 false
 true
 true
 false
 false
 false
 false
 false
 false
 false
 true
 true
 false
 true
 true
 false

(Check out randperm() and shuffle() for more randomness.)

Random numbers in a distribution[edit]

randn() gives you one random number in a normal distribution with mean 0 and standard deviation 1. randn(n) gives you n such numbers:

julia> randn()
0.8060073309441075

julia> randn(10),
([1.31598,1.55126,-1.14605,-0.562148,0.69725,0.468769,-1.58275,0.238471,2.72857,1.11561],)

(the comma after randn(10) is just intended for line visualization)

If you've installed the Plots plotting package, you can plot this:

julia> using Plots; gr()
julia> histogram(randn(10000), nbins=100)

histogram plot created in Julia using Plots

Seeding the random number generator[edit]

Before you use random numbers, you can seed the random number generator with a specific value. This ensures that subsequent random numbers will follow the same sequence, if they start from the same seed. You can seed the generator using the srand() or MersenneTwister() functions.

julia> srand(10);

julia> rand(0:10, 6)
6-element Array{Int64,1}:
 6
 5
 9
 1
 1
 0
julia> rand(0:10, 6)
6-element Array{Int64,1}:
 10
 3
 6
 8
 0
 1

After restarting Julia, the same seed guarantees the same random numbers:


julia> exit()
$ julia
               _
   _       _ _(_)_     |  A fresh approach to technical computing
  (_)     | (_) (_)    |  Documentation: http://docs.julialang.org
   _ _   _| |_  __ _   |  Type "?help" for help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version xxxxxxxxx
 _/ |\__'_|_|_|\__'_|  |  Commit  xxxxxxxxx
|__/                   |  x86_64-apple-darwin13.4.0
 
julia> srand(10);

julia> rand(0:10, 6)
6-element Array{Int64,1}:
 6
 5
 9
 1
 1
 0

julia> rand(0:10, 6)
6-element Array{Int64,1}:
 10
 3
 6
 8
 0
 1