Hello Class!
Introduction to Julia
February 9, 2026
Extremely new language.
Development began in 2009. Version 1.0 was launched in 2018.
Developed by a group at MIT: “Why We Created Julia”
Designed to be:
(C is very fast, but hard to read and write)
You can run a whole file of Julia code by clicking the play arrow.
Or you can run a single line or selection…
Shift+EnterBoth of these will execute the Julia code in a terminal, called a REPL
Julia uses a single = for assignment
Math is not that different:
Logic operators are written with double && or ||
Julia uses lowercase true and false for booleans, unlike R’s TRUE and FALSE.
A basic array is constructed as comma-separated elements in square brackets
Single dimension arrays are referred to as Vectors.
Arrays will default to the most general type at construction.
If even one of the elements is a float at construction:
We cannot add a float to an already made Int Array:
InexactError: Int64(9.1) Stacktrace: [1] Int64 @ ./float.jl:923 [inlined] [2] convert @ ./number.jl:7 [inlined] [3] setindex!(A::Vector{Int64}, x::Float64, i::Int64) @ Base ./array.jl:985 [4] top-level scope @ ~/GitHub/Teaching/BrownEcon2020/course-applied-economics-analysis-2026-Spring/lecture-slides/julia.qmd:216
But at construction, arrays can include any types:
Julia will default to a general type “Any” to allow an integer, float, string, and boolean to exist in the same array.
You can be explicit about the type for an array by listing it before the square brackets.
This is most useful when creating an empty array—which defaults to type Any.
Empty array with a type:
You can make…
Tuples are constructed as comma-separated elements in parentheses.
Tuples are immutable; arrays are mutable.
MethodError: no method matching setindex!(::Tuple{Int64, String, Float64, Bool}, ::Int64, ::Int64)
The function `setindex!` exists, but no method is defined for this combination of argument types.
Stacktrace:
[1] top-level scope
@ ~/GitHub/Teaching/BrownEcon2020/course-applied-economics-analysis-2026-Spring/lecture-slides/julia.qmd:293
Strings in Julia use double quotes (single quotes are for characters):
Julia can insert variables directly into strings with $:
Compare to R’s paste() or paste0().
Julia’s $ interpolation is much more concise: "Hello $name" vs paste0("Hello ", name).
Dictionaries store key-value pairs (similar to named lists in R):
Dict{String, Int64} with 3 entries:
"c" => 3
"b" => 2
"a" => 1
Julia starts indexing from 1.
We can subset arrays with square brackets:
Julia is not space sensitive.
A for loop instead ends with an end keyword
Julia also has while loops:
Just like for loops, while loops are closed with end.
Julia uses if, elseif, and else — all closed with end:
Compare to R which uses if (...) { } else if (...) { } else { }.
Julia uses elseif (one word, no space) and end instead of braces.
For simple if/else, Julia has a one-line shortcut:
This is equivalent to:
Julia functions are defined with the keyword function and end:
For one line functions, you can define them with:
Julia’s key design feature: you can define the same function for different input types.
describe (generic function with 3 methods)
Julia picks the right version of a function based on all argument types.
This is how Julia stays fast: the compiler generates optimized code for each type combination.
Julia has built in unicode support.
Unicode is a text encoding standard that supports characters from all major writing systems and emojis!
Actual use: greek letters for equations
Tidier than writing out “beta” and “gamma”,
In VS Code, to get one of these unicode symbols, you type:
\:smiley: for 😃
Once you start typing \:smi… you can use tab to autocomplete.
Similarily,
\beta for β
For a full list, see the Unicode Julia documentation.
Julia can vectorize (broadcast) any function, which is incredibly useful.
MethodError: no method matching abs(::Vector{Int64})
The function `abs` exists, but no method is defined for this combination of argument types.
Closest candidates are:
abs(::Bool)
@ Base bool.jl:155
abs(::Pkg.Resolve.VersionWeight)
@ Pkg ~/.julia/juliaup/julia-1.12.4+0.aarch64.apple.darwin14/share/julia/stdlib/v1.12/Pkg/src/Resolve/versionweights.jl:32
abs(::Missing)
@ Base missing.jl:101
...
Stacktrace:
[1] top-level scope
@ ~/GitHub/Teaching/BrownEcon2020/course-applied-economics-analysis-2026-Spring/lecture-slides/julia.qmd:609
Julia can vectorize (broadcast) any function, which is incredibly useful.
abs function to each element, add the . operator:Broadcasting with the . operator works for any functions:
By default, Julia won’t multiply two vectors element by element:
MethodError: no method matching *(::Vector{Int64}, ::Vector{Int64})
The function `*` exists, but no method is defined for this combination of argument types.
Closest candidates are:
*(::Any, ::Any, ::Any, ::Any...)
@ Base operators.jl:642
*(::LinearAlgebra.AbstractQ, ::AbstractVector)
@ LinearAlgebra ~/.julia/juliaup/julia-1.12.4+0.aarch64.apple.darwin14/share/julia/stdlib/v1.12/LinearAlgebra/src/abstractq.jl:180
*(::Dates.Period, ::AbstractArray)
@ Dates ~/.julia/juliaup/julia-1.12.4+0.aarch64.apple.darwin14/share/julia/stdlib/v1.12/Dates/src/periods.jl:93
...
Stacktrace:
[1] top-level scope
@ ~/GitHub/Teaching/BrownEcon2020/course-applied-economics-analysis-2026-Spring/lecture-slides/julia.qmd:650
By default, Julia won’t multiply two vectors element by element:
Instead, use broadcasting to get this behavior
Julia has a pipe operator |>, just like R’s |> or %>%:
Open a Julia REPL in VS Code and try the following:
Create an array of the integers 1 through 20.
Write a function is_even(x) that returns true if x is even and false otherwise.
%.Broadcast your function over the array to get a vector of true/false.
Use string interpolation to print: "There are __ even numbers in my array."
sum() a boolean vector.Julia has a built in package and environment manager: Pkg.jl
It has its own REPL, which can be launched from Julia by typing a right square bracket: ]
But all of its commands can also be run from withing Julia.
Pkg.add("DataFrames")I will show commands should be run in the Pkg REPL with: pkg>
]Then you can create and activate an environment:
This will create an environment in a new folder, “myenv”.
In Julia, you can install packages both system wide
or in an environment you have created.
Once you have a package added to your environment, you will see two files:
Project.toml: Lists the packages you have installed for this environmentManifest.toml: Lists the Julia version, installed package versions, package dependency versionsWith these two files, Julia can always recreate your environment.
In order to have your VS Code workspace automatically use the correct Julia environment, you have to connect it.
Shift+Cmd+P), then search “Julia: Change Current Environment”After selecting your environment, VS Code will add a “.vscode/settings.json” file to the folder. This file contains a path to the environment.
Once you have a package installed, you can:
. to reference functionsDataFrames is a package that implements dataframes in Julia.
First, you need to install DataFrames, then import it.
And then in your Julia code:
Constructing a dataframe by hand:
You can access a column by name with . or [:, :col]:
df.a is shorthand. df[:, :a] returns a copy; df[!, :a] returns the column without copying.
Filter rows using boolean conditions:
Combine conditions with .&& (broadcasted AND):
Notice the .> and .== — these are broadcasted comparisons, just like we saw earlier.
In Julia, functions that modify their inputs always end with a bang: !
Compare sort (returns a new array) vs. sort! (modifies in place):
Original: [3, 1, 2]
Sorted copy: [1, 2, 3]
Whenever you see a ! at the end of a function name, it is warning you: “this will change your data in place!”
Usual data science operations are possible with Julia and DataFrames.jl
For reading and writing CSVs, use the CSV.jl package.
Lots of possible plotting packages in Julia.
Plots.jl the most usedGadfly.jl is a grammar of graphics packageUnicodePLots.jl makes plots in the terminalMakie.jl is a high performance plotting package (can use GPUs for big plots)AlgebraOfGraphics.jl is a grammar of graphics package that wraps Makie.jlPlotlyJS.jl is a wrapper for PlotlyPLots.jlProgramming languages have to be compiled to machine code before they can be run.
Julia does this “just-in-time” (JIT)—i.e. right before the code is run.
This means that Julia can be very fast, but it also means that the first time you run a function, it will be slow.
The speed advantage comes from compiling code for only the specific types of the inputs.
An example of the disadvantage is the “time to first plot” problem.
|>! convention] activate .Gadfly and RDatasets