Author Archives: Steven Whitaker

Mastering the Julia REPL

By: Steven Whitaker

Re-posted from: https://blog.glcs.io/julia-repl

Julia is a relatively new,
free, and open-source programming language.
It has a syntax
similar to that of other popular programming languages
such as MATLAB and Python,
but it boasts being able to achieve C-like speeds.

Similarly to other dynamic languages,
Julia provides a REPL
(read-eval-print loop)
for interactive development.

Here are some reasons why
the Julia REPL is a useful tool:

  • It speeds up prototyping
    because not all your code
    needs to compile each time
    you tweak a function.
  • It enables interactively
    working with and inspecting
    Julia objects
    (for example,
    to see what data is stored,
    or to discover object fields).
  • It provides different prompt modes,
    enabling interactive access
    to documentation
    and providing a clean interface
    for package management.

In this post,
we will learn how to use the Julia REPL,
including the different prompt modes
and some useful keybindings.

This post assumes you already have Julia installed.
If you haven’t yet,
check out our earlier
post on how to install Julia.

Starting the Julia REPL

The Julia REPL starts immediately
when the Julia executable runs,
either by double-clicking the executable
or by calling julia from the terminal
(with no arguments).

$ julia
               _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.X.X (20XX-XX-XX)
 _/ |\__'_|_|_|\__'_|  |  Official https://julialang.org/ release
|__/                   |

julia>

Once the REPL starts,
you will be at the Julia prompt.

REPL Prompt Modes

The Julia REPL can operate
in different prompt modes:

  • Julia mode (the default),
  • help mode,
  • Pkg mode, and
  • shell mode.

To enter help, Pkg, or shell mode,
place the cursor
at the beginning of the Julia mode prompt
and
type a question mark (?),
a closing bracket (]),
or a semicolon (;),
respectively.
To return to Julia mode,
place the cursor
at the beginning of the prompt
and press Backspace.

Toggling REPL modes

Julia Mode

The default prompt mode
is the Julia prompt,
where Julia code can be evaluated.
We can type any valid Julia code
and press Enter,
and then the code will be evaluated
and the result displayed.

julia> 1 + 1
2

We can also type invalid Julia code,
and the REPL will tell us what went wrong.

julia> 1 + 1)
ERROR: syntax: extra token ")" after end of expression

We can assign variables
and define functions
to use in subsequent expressions.

julia> a = "hello"
"hello"

julia> function say(x)
           "say " * x
       end
say (generic function with 1 method)

julia> say(a)
"say hello"

Note that the most recently evaluated statement
is stored in a variable called ans.

julia> ans
"say hello"

If desired,
we can suppress output
with a semicolon ;.

julia> "no output";

Note, however,
that a semicolon does not suppress
the output of commands like print.

julia> print("this still prints");
this still prints

Including Code from a File

We can also evaluate code
stored in a file.
For example,
suppose we have a file, code.jl,
with the following contents:

# code.jl

function plus1(x)
    return x + 1
end

a = 3
b = plus1(a)

We can run this code in the REPL
with the include function:

julia> include("code.jl")
4

Note that 4 is the result
of the last evaluated line
of the file,
so that is what is displayed
at the REPL.

Now that code.jl has been included,
we can use what was defined
in the file.

julia> c = a + b
7

julia plus1(c)
8

Numbered Prompt

As noted earlier,
ans stores the value
of the most recently evaluated statement.
This means that ans is overwritten
every time code is evaluated.
Sometimes, however,
it can be useful to store
more than just the most recent result.
Julia provides a numbered prompt
for this purpose.
It can be activated as follows:

julia> using REPL

julia> REPL.numbered_prompt!()

Then the prompt will change
from julia> to In [x]:,
and results that would have been written to ans
will now be written to Out[x].

In [3]: 2^7
128

In [4]: Out[3]
128

Help Mode

Help mode is useful if,
as the name suggests,
you need help.
Help mode displays the documentation
(if available)
for what is typed in the prompt.

With your cursor at the beginning
of the Julia prompt,
type ? to enter help mode.
Doing so will change the prompt
from julia> to help?>.
From there,
just type what you want help with.

We can pull up the documentation for a function:

help?> print
search: print println printstyled sprint isprint prevind parentindices

  print([io::IO], xs...)


  Write to io (or to the default output stream stdout if io is not given)
  a canonical (un-decorated) text representation.
  

We can find help
for a variable we have defined:

julia> a = 4;

help?> a
search: a any all abs ans Any axes atan asin asec any! all! acsc acot acos

  No documentation found.

  a is of type Int64.
  

We can also figure out
how to type unicode characters:

help?> 
"" can be typed by \equiv<tab>

(Just copy-paste the unicode character
you want help typing.)

Pkg Mode

Pkg mode provides a convenient interface
for package management.

With your cursor at the beginning
of the Julia prompt,
type ] to enter Pkg mode.
Doing so will change the prompt
from julia> to (environment) pkg>.
Here,
environment refers to
the currently active package environment,
which by default is @v1.X
(where 1.X is the Julia version currently running).

(A package environment is essentially
the set of packages currently available to use.
We will talk more about package environments
in a future post.)

Once in Pkg mode,
we can (among other things)

  • list the currently available packages:
    pkg> st
    
  • add packages:
    pkg> add Plots
    
  • remove packages:
    pkg> rm Plots
    
  • and update packages:
    pkg> up
    

We can also ask for help:

pkg> ?
  Welcome to the Pkg REPL-mode. To return to the julia> prompt, either press
  backspace when the input line is empty or press Ctrl+C.
  

pkg> ? st
  [st|status] [-d|--diff] [-o|--outdated] [pkgs...]
  [st|status] [-d|--diff] [-o|--outdated] [-p|--project] [pkgs...]
  [st|status] [-d|--diff] [-o|--outdated] [-m|--manifest] [pkgs...]
  [st|status] [-d|--diff] [-e|--extensions] [-p|--project] [pkgs...]
  [st|status] [-d|--diff] [-e|--extensions] [-m|--manifest] [pkgs...]
  [st|status] [-c|--compat] [pkgs...]


  Show the status of the current environment.
  

Visit the full Pkg documentation
for more details.

Shell Mode

Shell mode enables quick access
to the system shell.

With your cursor at the beginning
of the Julia prompt,
type ; to enter help mode.
Doing so will change the prompt
from julia> to shell>.

Once in shell mode,
we can type system commands.
For example:

shell> echo shell mode
shell mode

Note that on Windows,
windows shell commands are not exposed.
However,
PowerShell or the command prompt
can respectively be accessed via

shell> powershell

or

shell> cmd

Useful Keybindings

There are several useful keybindings,
or keyboard shortcuts,
that help improve and streamline
work at the REPL.

Accessing Previous Commands

When working at the REPL,
it is often the case
where previous commands need to be repeated,
possibly with some modification.
There are two keybindings
for accessing previous REPL commands.

  • Up (i.e., the up arrow key):
    Press Up
    to cycle through previous commands
    in reverse chronological order.
    If there is text before the cursor,
    only commands that match
    up to the cursor
    will be found.
    For example,
    pressing Up on a blank REPL line
    will bring up the previous command,
    while pressing Up
    after typing in
    will bring up the previous command
    that starts with in
    (e.g., include("code.jl"),
    but not 1 + 1).
  • ctrl-r and ctrl-s:
    Press Control and the r key simultaneously
    to enable reverse search mode,
    and then type part of the command to find.
    The most recent command
    that matches the search query
    will be found.
    Press ctrl-r again to find
    the next most recent, matching command,
    and so on.
    If you accidentally skip the command
    you were looking for,
    press ctrl-s to search
    in the opposite direction
    (forward search mode).
    Press Enter to select the command found,
    or press ctrl-c to exit search mode.

Tab Completion

Tab completion is another useful feature
of the Julia REPL.
After typing the first character(s)
of a word,
press Tab to complete the word
if there is an existing Julia object
that matches what was typed.
For example:

julia> my_very_long_variable = 1;

julia> my<tab>
julia> my_very_long_variable

If there are multiple matches,
Tab will complete up to the ambiguity.
Press Tab again to display the matches.

julia> prin<tab>
julia> print<tab>

print        println      printstyled

Dictionary keys and object fields
can also be discovered
with tab completion.

julia> d = Dict("key1" => 1, "key2" => 2, "another_key" => 3);

julia> d["k<tab>
julia> d["key<tab>

"key1"  "key2"
julia> t = (foo = 1, foobar = 2);

julia> t.f<tab>
julia> t.foo<tab>

foo     foobar

Finally,
tab completion can also display
available function methods.

julia> split(<tab>
split(str::T, splitter; limit, keepempty) where T<:AbstractString @ Base strings/util.jl:601
split(str::AbstractString; limit, keepempty) @ Base strings/util.jl:608

Splitting a Command into Multiple Lines (alt-Enter)

Normally, when typing at the REPL,
pressing Enter
will evaluate the typed expression
(if it is a complete expression).
Sometimes, however,
we just want to insert a new line.
Pressing alt-Enter
(or alt-Shift-Enter on Windows)
will do just that.

Using a Text Editor (alt-e)

Instead of typing commands
at the REPL directly,
we can type commands
in a text editor of our choice
(e.g., specified by the EDITOR
environment variable on Linux)
by pressing alt-e.
After saving and exiting the text editor,
the contents will be pasted
into the REPL.

Halting Execution (ctrl-c)

If we want to stop a command,
we can press ctrl-c
to send an interrupt signal
and return to the Julia prompt.

julia> sleep(100)
^CERROR: InterruptException:


julia>

Note that ctrl-c displays as ^C
in the REPL.

Pressing ctrl-c can also be
an effective way
to get an empty prompt
(even if no code is running).

julia> I've typed a lot and don't feel like pressing Backspace^C

julia>

Terminating the REPL (ctrl-d)

Finally,
pressing ctrl-d
is a quick way
to terminate the REPL.

Summary

In this post,
we learned about the Julia REPL,
including the different prompt modes
and some useful keybindings.

How has your experience been
with the Julia REPL?
Let us know in the comments below!

Comfortable with the Julia REPL?
Move on to the
next post to learn about vectorizing, or broadcasting, functions!
Or,
feel free to take a look
at our other Julia tutorial posts!

Additional Links

Mastering the Julia REPL

By: Steven Whitaker

Re-posted from: https://glcs.hashnode.dev/julia-repl

Julia is a relatively new,free, and open-source programming language.It has a syntaxsimilar to that of other popular programming languagessuch as MATLAB and Python,but it boasts being able to achieve C-like speeds.

Similarly to other dynamic languages,Julia provides a REPL(read-eval-print loop)for interactive development.

Here are some reasons whythe Julia REPL is a useful tool:

  • It speeds up prototypingbecause not all your codeneeds to compile each timeyou tweak a function.
  • It enables interactivelyworking with and inspectingJulia objects(for example,to see what data is stored,or to discover object fields).
  • It provides different prompt modes,enabling interactive accessto documentationand providing a clean interfacefor package management.

In this post,we will learn how to use the Julia REPL,including the different prompt modesand some useful keybindings.

This post assumes you already have Julia installed.If you haven’t yet,check out our earlierpost on how to install Julia.

Starting the Julia REPL

The Julia REPL starts immediatelywhen the Julia executable runs,either by double-clicking the executableor by calling julia from the terminal(with no arguments).

$ julia               _   _       _ _(_)_     |  Documentation: https://docs.julialang.org  (_)     | (_) (_)    |   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.  | | | | | | |/ _` |  |  | | |_| | | | (_| |  |  Version 1.X.X (20XX-XX-XX) _/ |\__'_|_|_|\__'_|  |  Official https://julialang.org/ release|__/                   |julia>

Once the REPL starts,you will be at the Julia prompt.

REPL Prompt Modes

The Julia REPL can operatein different prompt modes:

  • Julia mode (the default),
  • help mode,
  • Pkg mode, and
  • shell mode.

To enter help, Pkg, or shell mode,place the cursorat the beginning of the Julia mode promptandtype a question mark (?),a closing bracket (]),or a semicolon (;),respectively.To return to Julia mode,place the cursorat the beginning of the promptand press Backspace.

Toggling REPL modes

Julia Mode

The default prompt modeis the Julia prompt,where Julia code can be evaluated.We can type any valid Julia codeand press Enter,and then the code will be evaluatedand the result displayed.

julia> 1 + 12

We can also type invalid Julia code,and the REPL will tell us what went wrong.

julia> 1 + 1)ERROR: ParseError:# Error @ REPL[1]:1:61 + 1)#      extra tokens after end of expressionStacktrace: [1] top-level scope   @ none:1

We can assign variablesand define functionsto use in subsequent expressions.

julia> a = "hello""hello"julia> function say(x)           "say " * x       endsay (generic function with 1 method)julia> say(a)"say hello"

Note that the most recently evaluated statementis stored in a variable called ans.

julia> ans"say hello"

If desired,we can suppress outputwith a semicolon ;.

julia> "no output";

Note, however,that a semicolon does not suppressthe output of commands like print.

julia> print("this still prints");this still prints

Including Code from a File

We can also evaluate codestored in a file.For example,suppose we have a file, code.jl,with the following contents:

# code.jlfunction plus1(x)    return x + 1enda = 3b = plus1(a)

We can run this code in the REPLwith the include function:

julia> include("code.jl")4

Note that 4 is the resultof the last evaluated lineof the file,so that is what is displayedat the REPL.

Now that code.jl has been included,we can use what was definedin the file.

julia> c = a + b7julia plus1(c)8

Numbered Prompt

As noted earlier,ans stores the valueof the most recently evaluated statement.This means that ans is overwrittenevery time code is evaluated.Sometimes, however,it can be useful to storemore than just the most recent result.Julia provides a numbered promptfor this purpose.It can be activated as follows:

julia> using REPLjulia> REPL.numbered_prompt!()

Then the prompt will changefrom julia> to In [x]:,and results that would have been written to answill now be written to Out[x].

In [3]: 2^7128In [4]: Out[3]128

Help Mode

Help mode is useful if,as the name suggests,you need help.Help mode displays the documentation(if available)for what is typed in the prompt.

With your cursor at the beginningof the Julia prompt,type ? to enter help mode.Doing so will change the promptfrom julia> to help?>.From there,just type what you want help with.

We can pull up the documentation for a function:

help?> printsearch: print println printstyled sprint isprint prevind parentindices  print([io::IO], xs...)  Write to io (or to the default output stream stdout if io is not given)  a canonical (un-decorated) text representation.  

We can find helpfor a variable we have defined:

julia> a = 4;help?> asearch: a any all abs ans Any axes atan asin asec any! all! acsc acot acos  No documentation found.  a is of type Int64.  

We can also figure outhow to type unicode characters:

help?> "" can be typed by \equiv<tab>

(Just copy-paste the unicode characteryou want help typing.)

Pkg Mode

Pkg mode provides a convenient interfacefor package management.

With your cursor at the beginningof the Julia prompt,type ] to enter Pkg mode.Doing so will change the promptfrom julia> to (environment) pkg>.Here,environment refers tothe currently active package environment,which by default is @v1.X(where 1.X is the Julia version currently running).

(A package environment is essentiallythe set of packages currently available to use.We will talk more about package environmentsin a future post.)

Once in Pkg mode,we can (among other things)

  • list the currently available packages:
    pkg> st
  • add packages:
    pkg> add Plots
  • remove packages:
    pkg> rm Plots
  • and update packages:
    pkg> up

We can also ask for help:

pkg> ?  Welcome to the Pkg REPL-mode. To return to the julia> prompt, either press  backspace when the input line is empty or press Ctrl+C.  pkg> ? st  [st|status] [-d|--diff] [-o|--outdated] [pkgs...]  [st|status] [-d|--diff] [-o|--outdated] [-p|--project] [pkgs...]  [st|status] [-d|--diff] [-o|--outdated] [-m|--manifest] [pkgs...]  [st|status] [-d|--diff] [-e|--extensions] [-p|--project] [pkgs...]  [st|status] [-d|--diff] [-e|--extensions] [-m|--manifest] [pkgs...]  [st|status] [-c|--compat] [pkgs...]  Show the status of the current environment.  

Visit the full Pkg documentationfor more details.

Shell Mode

Shell mode enables quick accessto the system shell.

With your cursor at the beginningof the Julia prompt,type ; to enter help mode.Doing so will change the promptfrom julia> to shell>.

Once in shell mode,we can type system commands.For example:

shell> echo shell modeshell mode

Note that on Windows,windows shell commands are not exposed.However,PowerShell or the command promptcan respectively be accessed via

shell> powershell

or

shell> cmd

Useful Keybindings

There are several useful keybindings,or keyboard shortcuts,that help improve and streamlinework at the REPL.

Accessing Previous Commands

When working at the REPL,it is often the casewhere previous commands need to be repeated,possibly with some modification.There are two keybindingsfor accessing previous REPL commands.

  • Up (i.e., the up arrow key):Press Upto cycle through previous commandsin reverse chronological order.If there is text before the cursor,only commands that matchup to the cursorwill be found.For example,pressing Up on a blank REPL linewill bring up the previous command,while pressing Upafter typing inwill bring up the previous commandthat starts with in(e.g., include("code.jl"),but not 1 + 1).
  • ctrl-r and ctrl-s:Press Control and the r key simultaneouslyto enable reverse search mode,and then type part of the command to find.The most recent commandthat matches the search querywill be found.Press ctrl-r again to findthe next most recent, matching command,and so on.If you accidentally skip the commandyou were looking for,press ctrl-s to searchin the opposite direction(forward search mode).Press Enter to select the command found,or press ctrl-c to exit search mode.

Tab Completion

Tab completion is another useful featureof the Julia REPL.After typing the first character(s)of a word,press Tab to complete the wordif there is an existing Julia objectthat matches what was typed.For example:

julia> my_very_long_variable = 1;julia> my<tab>julia> my_very_long_variable

If there are multiple matches,Tab will complete up to the ambiguity.Press Tab again to display the matches.

julia> prin<tab>julia> print<tab>print        println      printstyled

Dictionary keys and object fieldscan also be discoveredwith tab completion.

julia> d = Dict("key1" => 1, "key2" => 2, "another_key" => 3);julia> d["k<tab>julia> d["key<tab>"key1"  "key2"
julia> t = (foo = 1, foobar = 2);julia> t.f<tab>julia> t.foo<tab>foo     foobar

Finally,tab completion can also displayavailable function methods.

julia> split(<tab>split(str::T, splitter; limit, keepempty) where T<:AbstractString @ Base strings/util.jl:601split(str::AbstractString; limit, keepempty) @ Base strings/util.jl:608

Splitting a Command into Multiple Lines (alt-Enter)

Normally, when typing at the REPL,pressing Enterwill evaluate the typed expression(if it is a complete expression).Sometimes, however,we just want to insert a new line.Pressing alt-Enter(or alt-Shift-Enter on Windows)will do just that.

Using a Text Editor (alt-e)

Instead of typing commandsat the REPL directly,we can type commandsin a text editor of our choice(e.g., specified by the EDITORenvironment variable on Linux)by pressing alt-e.After saving and exiting the text editor,the contents will be pastedinto the REPL.

Halting Execution (ctrl-c)

If we want to stop a command,we can press ctrl-cto send an interrupt signaland return to the Julia prompt.

julia> sleep(100)^CERROR: InterruptException:julia>

Note that ctrl-c displays as ^Cin the REPL.

Pressing ctrl-c can also bean effective wayto get an empty prompt(even if no code is running).

julia> I've typed a lot and don't feel like pressing Backspace^Cjulia>

Terminating the REPL (ctrl-d)

Finally,pressing ctrl-dis a quick wayto terminate the REPL.

Summary

In this post,we learned about the Julia REPL,including the different prompt modesand some useful keybindings.

How has your experience beenwith the Julia REPL?Let us know in the comments below!

Comfortable with the Julia REPL?Move on to thenext post to learn about vectorizing, or broadcasting, functions!Or,feel free to take a lookat our other Julia tutorial posts!

Additional Links

Understanding Variables and Functions

By: Steven Whitaker

Re-posted from: https://blog.glcs.io/variables-and-functions

Variables and functions
are the building blocks
of any programmer’s code.
Variables allow computations to be reused,
and functions help keep code organized.

In this post,
we will cover some of the basics
of variables and functions
in Julia,
a relatively new,
free, and open-source programming language.
In particular,
we will discuss what a variable is,
what sorts of data
can be assigned to a variable,
and
how to define and use functions.

Variables

A variable is a label
used to refer to an object.

julia> a = 1
1

In the above code snippet,
we assigned a value of 1
to a variable called a.
Now we can use a in other expressions,
and the value of a (1 in this case)
will be used.

julia> a + 2
3

We can also reassign variables.

julia> a = 4
4

julia> a = "Hello"
"Hello"

julia> a = [1, 2, 3]
3-element Vector{Int64}:
 1
 2
 3

We can even use Unicode characters!
We can write many math symbols
by typing the corresponding LaTeX command
and then pressing <tab>.
Here,
we assign
(a Julia constant equal to \( \pi \)
and typed with \pi<tab>)
to
(typed with \theta<tab>).

julia>  = 
 = 3.1415926535897...

Variables Are Labels

One important thing to remember about variables
is that they are labels for data,
not the data itself.
Let’s illustrate what that means.
At this point,
a refers to a Vector.
We will create another variable, b,
and assign it the value of a.

julia> b = a
3-element Vector{Int64}:
 1
 2
 3

Now let’s change one of the elements of b.

julia> b[1] = 100; b
3-element Vector{Int64}:
 100
   2
   3

We didn’t change a,
so it should be the same as before, right?
Nope!

julia> a
3-element Vector{Int64}:
 100
   2
   3

What happened?
Remember, a is just a label
for some data (a Vector).
When we created b,
we created a new label
for the same data.
Both a and b refer
to the same data,
so modifying one modifies the other.

Two labels on the same box

If you want b
to have the same values as a
but refer to different data,
use copy.

julia> b = copy(a)
3-element Vector{Int64}:
 100
   2
   3

julia> b[1] = 1; b
3-element Vector{Int64}:
 1
 2
 3

julia> a
3-element Vector{Int64}:
 100
   2
   3

Two labels on different boxes

Now that we know
how to create variables,
let’s learn about
some basic types of data
we can assign to variables.

Basic Types

Julia has many basic data types.

integer = 9000
floating_point = 3.14
boolean = true
imaginary = 1 + 2im
rational = 4//3
char = 'x'
str = "a string"
array = [1.0, 2.0]

Integers and floating-point numbers
can be expressed
with different numbers of bits.

Int64, Int32, Int16       # and more
Float64, Float32, Float16 # and more

By default,
integer numbers
(technically, literals)
are of type Int64 on 64-bit computers
or of type Int32 on 32-bit computers.
(Note that Int is shorthand for Int64 or Int32
for 64-bit or 32-bit computers, respectively.
Therefore, all integer literals are of type Int.)

On the other hand,
floating-point numbers (literals)
of the form 3.14 or 2.3e5
are of type Float64 on all computers,
while those of the form 2.3f5
are of type Float32.

To use different numbers of bits,
just use the appropriate constructor.

julia> Int16(20)
20

julia> Float16(1.2)
Float16(1.2)

Basic Operations

Now we will cover
some basic operations.
This is by no means an exhaustive list;
check out the Julia documentation
for more details.

# Math
addition = 1 + 2.0
subtraction = 1 - 1
multiplication = 3 * 4//3
division = 6 / 4
integer_division = 6  4 # Type \div<tab>
power = 2^7

# Boolean
not = !false
and = true && not
or = not || and

# Comparison
equality = addition == 1
greater = division > integer_division
chained = addition < subtraction <= power

# Strings
string_concatenation = "hi " * "there"
string_interpolation = "1 - 1 = $subtraction"
string_indexing = string_interpolation[5]
substring = string_concatenation[4:end]
parsing = parse(Int, string_indexing)

# Arrays
a = [1, 2, 3]
b = [4, 5, 6]
concat_vert = [a; b]
concat_horiz = [a b]
vector_indexing = b[2]
vector_range_indexing = b[1:2]
matrix_indexing = concat_horiz[2:3,1]
elementwise1 = a .+ 1
elementwise2 = a .- b

# Displaying
print(addition)
println(string_concatenation)
@show not
@info "some variables" power a

Function Basics

Some of the basic operations we saw above,
e.g., parse and print,
were functions.
As demonstrated above,
functions are called
using the following familiar syntax:

func()           # For no inputs
func(arg1)       # For one input
func(arg1, arg2) # For two inputs
# etc.

Note that just writing the function name
(i.e., without parentheses)
is valid syntax, but it is not a function call.
In this case,
the function name is treated essentially like a variable,
meaning, for example, it can be used as an input
to another function.

For example,
one way to compute the sum
of the absolute value
of an array of numbers
is as follows:

julia> sum(abs, [-1, 0, 1])
2

Here,
the function abs is not being called (by us)
but is used as an input to the function sum
as if it were a variable.

Function Vectorization

Often,
we have a function
that operates on a single input
that we want to apply
to every element of an array.
Julia provides a convenient syntax
to do so:
just add a dot (.).
For example,
the following takes the absolute value
of every array element:

julia> abs.([-1, 0, 1])
3-element Vector{Int64}
 1
 0
 1

There is also a function, map,
that does the same thing
in this example:

julia> map(abs, [-1, 0, 1])
3-element Vector{Int64}
 1
 0
 1

(Note, however,
that map and the dot syntax
are not always interchangeable.)

Defining Functions

When writing Julia code,
it is convenient
to place code inside of functions.
There are two main syntaxes
for creating a function.

  1. Using the function keyword:
    function myfunc(x)
        return x + 1
    end
    
  2. Using the assignment form:
    myfunc2(x, y) = x + y
    

Optional Arguments

Sometimes we want a function
to have optional inputs.
The syntax for specifying optional arguments is

function myfunc3(required, optional = "hello")
    println(required, optional)
end

Here,
optional is optional
and has a default value of "hello"
if not provided by the caller.

julia> myfunc3("say ")
say hello

julia> myfunc3("see you ", "later")
see you later

Keyword Arguments

Another way to specify optional arguments
is to use keyword arguments.
The syntax is almost the same
as regular optional arguments,
except we use a semicolon (;) instead of a comma (,).

function myfunc4(x; y = 3)
    return x * y
end

Here,
y is optional,
but to specify it
we need to use the keyword y.

julia> myfunc4(2)
6

julia> myfunc4(2; y = 10)
20

julia> myfunc4(2, 10)
ERROR: MethodError: no method matching myfunc4(::Int64, ::Int64)

When calling myfunc4
we can also use a comma
when specifying y.

julia> myfunc4(2, y = 1)
2

Returning Multiple Values

Sometimes we need a function
to return multiple values.
The way to do this in Julia
is to return a Tuple.
Here’s an example:

function plusminus1(x)
    return (x + 1, x - 1)
end

Then multiple variables can be assigned at once.

julia> (plus1, minus1) = plusminus1(1)
(2, 0)

julia> plus1
2

julia> minus1
0

Note that taking the output
of a function with multiple return values
and assigning it to a single variable
will assign that variable the whole Tuple of outputs.
The following code illustrates this
and shows how to return just one output:

julia> both = plusminus1(1);

julia> both
(2, 0)

julia> (one,) = plusminus1(1);

julia> one
2

(Note, however, that in this last case
the second output is still computed;
it is just immediately discarded,
so there are no savings in computation.)

Vectorizing a Function with Multiple Return Values

Vectorizing a function with multiple return values
requires a bit more work.
For this example,
we will use the sincos function
that computes the sine and cosine simultaneously.
We can still use the dot syntax,
but we might be tempted to try the following:

julia> (s, c) = sincos.([0, /2, ]);

julia> s
(0.0, 1.0)

julia> c
(1.0, 6.123233995736766e-17)

Here, s has the value of sincos(0),
not the value of sin.([0, /2, ])
like we might have expected.

Instead, we can do the following:

julia> sc = sincos.([0, /2, ])
3-element Vector{Tuple{Float64, Float64}}:
 (0.0, 1.0)
 (1.0, 6.123233995736766e-17)
 (1.2246467991473532e-16, -1.0)

julia> s = first.(sc)
3-element Vector{Float64}:
 0.0
 1.0
 1.2246467991473532e-16

julia> c = last.(sc)
3-element Vector{Float64}:
  1.0
  6.123233995736766e-17
 -1.0

(Note that instead of using first or last,
we could write it this way:
output_i = getindex.(sc, i).
This way also works for functions
that return more than two values.)

Summary

In this post,
we learned about what a variable is
and some basic data types.
We also learned about
how to define and use functions.

There is a lot more we could cover
about these topics,
so if you want to learn more,
check out the links below,
or write a comment below
letting us know what additional concepts or topics
you would like to see!

Understand variables and functions in Julia?
Move on to the
next post to learn how to master the Julia REPL!
Or,
feel free to take a look
at our other Julia tutorial posts!

Additional Links