In [1]:
# this is a comment i Julia
# in Julia everything is an Expression
In [2]:
2 + 3
Out[2]:
In [3]:
# variables don't have to be explicitely typed
a = 2
typeof(a)
Out[3]:
In [4]:
# Julia supports ASCII strings
str = "Harris"
Out[4]:
In [5]:
typeof(str)
Out[5]:
In [6]:
# and UTF8 / UTF16 strings
str2 = "öäüß"
Out[6]:
In [7]:
typeof(str2)
Out[7]:
In [8]:
# both string types are immutable
# and their individual characters should not be accessed by index
# better use the iterator
for chr in str2
println(chr)
end
In [9]:
typeof(str2)
Out[9]:
In [10]:
# This is a 'tuple'
a_tuple = (1,"VALUE")
Out[10]:
In [11]:
typeof(a_tuple)
Out[11]:
In [12]:
# arrays are easy to create
array = [0,1,2,3,4]
Out[12]:
In [13]:
# and their index starts with 1!
array[1]
Out[13]:
In [14]:
# Julia can also generate arrays by following certain conditions
# Here we define a range from 1 to 20 with step 2 (this is an expression, too)
generated_array = 1:2:20
Out[14]:
In [15]:
generated_array[3]
Out[15]:
In [16]:
# this is another way to create arrays by using 'comprehensions'
another_array = [arr for arr in 1:10]
Out[16]:
In [17]:
# Crreating matrices is very easy and can be done by using semicolons as separators between rows
matrix = [1 2 3 4;
5 6 7 8;
9 10 11 12]
Out[17]:
In [18]:
# Of course, Julia supports Conditionals like if..then..else
if 2 > 3
println("WAT?")
elseif 2 < 2
println("WOOT?")
else
println("Hello, world!")
end
In [19]:
# ternary operator is also supported
a = 2 > 3 ? true : false
Out[19]:
In [20]:
# Julia's for-loop is very flexible and powerful
for x in 1:10
println("Value is $x") # here we interpolate the string value
end
In [21]:
# and while loops too
a = 1
b = 10
while a < b
a += 1
println("$a: looping over")
end
In [22]:
# Julia's structures are very easy to access.
# Here we use 'enumerate' to return not only the current value
# but also the index itself
# The returned value we call a 'tuple' and we show it via @show macro
for (i, v) in enumerate(1:10)
@show (i, v)
end
In [ ]:
# To access the Julia documentation just prepend a question mark before the term your're searching for
In [23]:
?println
Out[23]:
In [24]:
# functions are first-class objects
# Values are passed-by-reference
function doubleIt(num)
num * 2
end
Out[24]:
In [25]:
doubleIt(5)
Out[25]:
In [26]:
# you don't have to use the return statement
# because Julia automatically returns the result of the last expression in a function
# Remember: in Julia everything is an expression
function doubleItWithRet(num)
return num * 2
end
Out[26]:
In [27]:
doubleItWithRet(5)
Out[27]:
In [28]:
# a function can also be written this way
# just like a variable definition
# but this applies only to short functions containing one expression
doubleIt(num) = num * 2
Out[28]:
In [29]:
# you can be more specific and provide the parameter type information to Julia compiler
# Julia can deduce the type but it's often better to give this information in advance to
# help the compiler generate more efficient code
# Julia uses LLVM to generate native code
doubleIt(num::Float64) = num * 2
Out[29]:
In [30]:
# now our "doubleIt" function can consume Int64 and Float64 values (which, of course, are not of the same type)
doubleIt(45.5)
Out[30]:
In [31]:
# Functions can be returned
function returnAFun()
aValue = 0
return ((a) -> a += a) # we return a function that expects a single argument
end
Out[31]:
In [32]:
returned_func = returnAFun()
Out[32]:
In [33]:
value = returned_func(10)
println("Value is $value")
In [34]:
# Julia supports higher-order functions
function consumeAFun(func)
func(5)
end
Out[34]:
In [35]:
# here we define a function (it's quite similar to 'lambdas' in Python, for example)
toBeConsumed_ = (a) -> a * a
Out[35]:
In [36]:
consumeAFun(toBeConsumed_)
Out[36]:
In [37]:
# Functions can be anonymous...
# ...and they also can accept arbitrary amounts of arguments
# Just use the "splat" operator ... as a suffix
anonymous_func = function(manyargs...)
println("Argument Type is: " * string(typeof(manyargs))) # here we use 'string' to convert returned value to a string
for arg in manyargs
println("Argument: $arg")
end
end
Out[37]:
In [38]:
anonymous_func(1,2,3,4,5,6)
In [39]:
# Julia uses "mutiple dispatch" to call the most precise version of a function
# By using methods we can explore the available function definitions.
methods(doubleIt)
Out[39]:
In [ ]:
# In other languages, especially the object-oriented ones,
# a 'method' is a functions belonging to a certain instance of a class
# In Julia a 'method' belongs to a function
# Methods in Julia are different 'versions' of the same function
# which have different signatures
In [40]:
# Julia has no excessive class support like Java, C#, C++ etc.
# Instead it provides a simple type hierarchy without deep nesting
#Here we define an abstract class
# Unlike in other OO-languages abstract classes don't have fields
# and concrete types can't further be subtyped
abstract Device
# We subclass from Device by creating a new concrete type 'Computer'
type Computer <: Device
name::AbstractString
price::Float64
peripherals::Array{AbstractString}
end
# To create an immutable type we simply replace 'type' with immutable
immutable iPad <: Device
name::AbstractString
price::Float64
end
# We can set some defaults for the type constructor, too
immutable iPhone <: Device
name::AbstractString
price::Float64
iPhone(name="iPhone 6",price=700.00) = new(name,price)
end
In [41]:
iphone = iPhone()
Out[41]:
In [42]:
iphone.name
Out[42]:
In [43]:
# because we declared iPhone type to be immutable no changes are allowed
iphone.name = "iPhone 5"
In [44]:
computer = Computer("DELL",1000.00,["mice","printer"])
Out[44]:
In [45]:
# The type 'Computer' is not immutable so changes are allowed
computer.name = "Lenovo"
Out[45]:
In [46]:
# we can easily inspect the generated LLVM code
# the commands with a preceding @ are called 'macros'
@code_llvm doubleIt(45.5)
In [47]:
# or even the final, machine code
@code_native doubleIt(45.5)
In [48]:
# if you want to know how long it takes to execute a piece of code just prepend the @time macro
@time doubleIt(10)
Out[48]:
In [49]:
# We can create our own macros, too.
# We define a macro with 'macro' keyword and
# declare the code block which will be expanded later
# by using 'quote'-'end' markers
# Don't forget to prepend $ before the inserted code (variable, expression etc.)
# Without $ Julia wouldn't expand the given code
macro injectIt(func)
quote
$func
end
end
In [50]:
function addition(a::Int64,b::Int64)
a + b
end
@injectIt addition(2,3)
Out[50]:
In [51]:
# Julia is a 'homoiconic' language
# this means that it treats its code and data the same way
# With Julia one can access the AST (abstract syntax tree) directly
# This provides powerful instruments for metaprogramming (e.g. code that generates code)
# Here we define a function that will act as a "function generator".
# We iterate over a loop and generate a new piece of code that will be immediately
# inserted into our running code. This means that during the execution of "funcgen"
# the same program will get a few more functions "injected". Therefore the
# 'return value' of 'funcgen' is the 'expansion' of our running program: it expands into
# new functions prefixed with 'mult_'. The amount of these new function depends on the
# argument 'num' we provide to 'funcgen'
#
# The important part here is the macro @eval which reads the following code
function funcgen(num::Int64)
for count in 1:num
println("Generating function no. $count")
@eval function $(symbol(string("mult_",count)))(par::Int64)
par * $count
end
end
end
Out[51]:
In [52]:
# Here, our function generator creates 10 new mult_-functions.
funcgen(10)
In [53]:
# we execute one of them to check if the newly generated code is OK
mult_2(5)
Out[53]:
In [54]:
# Julia's ecosystem contains many useful packages
# Here we load some of them
using DataFrames # A Julia implementation of DataFrames similar to R or Python
using RDatasets # this package is a port from R
using PyPlot # this one is from Python
In [ ]:
# to update local package list use:
# Pkg.update()
# to initialize a new local package repository use:
# Pkg.init() # this is automatically done when calling Pkg.update() for the first time
# to add a new package use:
# Pkg.add(PACKAGE_NAME_IN_DOUBLE_QUOTES)
# to build a new package from source use:
# Pkg.build(PACKAGE_NAME_IN_DOUBLE_QUOTES)
In [55]:
# This is how we load a dataset from RDatasets package
# RDatasets brings many predefined datasets
iris = dataset("datasets", "iris")
Out[55]:
In [56]:
# We get the complete list by calling 'datasets'
RDatasets.datasets()
Out[56]:
In [57]:
# With RDatasets we can work almost like in R environment
RDatasets.head(iris)
Out[57]:
In [58]:
# Here we group the species by their name
# We use the 5-th row from the original dataset and count them by 'nrow'
by(iris, 5, nrow)
Out[58]:
In [59]:
# Here's another well-known dataset: titanic
titanic = dataset("datasets","titanic")
Out[59]:
In [60]:
by(titanic,3,nrow)
Out[60]:
In [61]:
groupby(titanic,[1,2])
Out[61]:
In [62]:
# DataArrays are similar to standard arrays
# Additionally they accept NA values
da = @data [1,2,3,4,5,6,7,NA,8,9,10]
Out[62]:
In [63]:
# DataFrames represent tabular structures and behave like their counterparts in R and Python
df = DataFrame(ID = 1:4,
FirstName = ["John","Mary","Christopher","Max"],
LastName = ["Doe","Clarkson","Wishbone","Reynolds"],
EMail = ["john.doe@email.com","mary.clarkson@email.com","chris.wishbone@email.com","max.reynolds@email.com"])
Out[63]:
In [64]:
# Like in R and Python we can easily get out some useful information about the data structure
df.columns
Out[64]:
In [65]:
describe(df)
In [66]:
# Just like with any other "standard" Julia type we can use 'show' to list the internals
show(df)
In [67]:
# Gadfly is Julia's own implementation for handling graphics
using Gadfly
In [68]:
X = [1,7,23,5,0]
Y = [11,62,3,14,15]
Labels = ["one", "two", "three", "four", "five"]
Gadfly.plot(x=X, y=Y, label=Labels,Geom.point, Geom.label)
Out[68]:
In [69]:
#PyPlot is a wrapper for Python's matplotlib
x = iris[1][1:100]
y = iris[3][1:100]
p = PyPlot.scatter(x,y, c=collect(x))
xlabel("Sepal Length")
ylabel("Petal Width")
title("Iris")
grid("on")
In [ ]: