cv.cm

Pemrograman · Bahasa pemrograman

Tutorial Julia untuk pemula

6 menit baca

Jawaban singkat

Julia adalah bahasa tingkat tinggi bertipe dinamis yang dirancang untuk komputasi numerik dan ilmiah yang cepat. Terbaca seperti Python atau MATLAB tetapi mengompilasi setiap fungsi ke kode native saat pertama kali dipanggil, sehingga perulangan dapat berjalan dengan kecepatan mendekati C. Gagasan utamanya adalah multiple dispatch: sebuah fungsi memilih method berdasarkan tipe semua argumennya. Pasang dengan juliaup dan jalankan file dengan julia hello.jl.

Apa itu Julia dan siapa yang memakainya

Julia dibuat oleh Jeff Bezanson, Stefan Karpinski, Viral Shah, dan Alan Edelman, dan dipublikasikan pada 2012. Versi 1.0 hadir pada 2018, dan seri 1.x menjaga kompatibilitas mundur. Julia bertujuan menyelesaikan "masalah dua bahasa": membuat prototipe dalam bahasa yang lambat tetapi mudah, lalu menulis ulang bagian yang berat dalam C atau Fortran.

Julia dipakai oleh ilmuwan, insinyur, dan analis data untuk simulasi, persamaan diferensial, optimasi, statistika, machine learning, dan komputasi performa tinggi. Ekosistem paketnya mencakup data frame, plotting, komputasi GPU, dan automatic differentiation.

Memasang Julia dan menjalankan Hello, world

Installer yang direkomendasikan adalah juliaup, yang memasang dan memperbarui versi Julia di Windows, macOS, dan Linux (lihat julialang.org/downloads). Setelah instalasi, julia memulai REPL dan julia file.jl menjalankan script.

# hello.jl
println("Hello, world!")
julia hello.jl
# Hello, world!
julia
# julia> 1 + 2
# 3

Di REPL, tekan ] untuk masuk ke mode paket (misalnya add DataFrames), ? untuk bantuan tentang sebuah nama, dan ; untuk shell. Tekan Backspace untuk kembali ke prompt normal.

Variabel dan tipe dasar

Variabel tidak perlu dideklarasikan, tetapi setiap nilai punya tipe konkret yang dapat Anda periksa dengan typeof. Anda dapat menambahkan anotasi tipe pada argumen fungsi dan field struct bila diinginkan.

TipeContohCatatan
Int6442Integer default pada sistem 64-bit; overflow berputar kembali (wrap around)
Float643.14, 1e-3Floating point default
Rational1//3Pecahan eksak
String"hello"UTF-8; interpolasi dengan "$name"
Char'a'Satu karakter Unicode
Booltrue, falseNilai logika
Symbol:nameNama yang di-intern, sering dipakai sebagai key atau opsi
Nothingnothing"Tanpa nilai", dikembalikan oleh fungsi yang tidak menghasilkan apa pun
name = "Ana"
age = 30
println("$name is $age, next year $(age + 1)")
# Ana is 30, next year 31
typeof(age)   # Int64
7 / 2         # 3.5  (always a float)
7 ÷ 2         # 3    (integer division, also div(7, 2))
2^10          # 1024

Julia menerima nama Unicode seperti π atau α; di REPL dan sebagian besar editor Anda mengetik \pi lalu menekan Tab untuk mendapatkan π.

Alur kontrol

Blok diakhiri dengan kata kunci end; indentasi hanya demi keterbacaan. if, for, dan while bekerja seperti di kebanyakan bahasa, dan comprehension membangun array dalam satu baris.

function sign_name(n)
    if n > 0
        "positive"
    elseif n < 0
        "negative"
    else
        "zero"
    end
end
for i in 1:3
    println("$i squared is $(i^2)")
end
squares = [x^2 for x in 1:5 if isodd(x)]   # [1, 9, 25]
x = 5
result = x > 3 ? "big" : "small"           # "big"

1:3 adalah range yang menyertakan kedua ujungnya. Ekspresi terakhir dalam fungsi atau blok if adalah nilainya, jadi sign_name(-2) mengembalikan "negative" tanpa return eksplisit.

Fungsi

add(x, y) = x + y                 # one-line definition
function greet(name = "world"; punctuation = "!")
    return "Hello, $name$punctuation"
end
greet()                           # "Hello, world!"
greet("Ana", punctuation = ".")   # "Hello, Ana."
square = x -> x^2                 # anonymous function
map(square, [1, 2, 3])            # [1, 4, 9]
v = [3, 1, 2]
sort!(v)                          # v is now [1, 2, 3]

Argumen posisional ditulis sebelum titik koma dan argumen keyword setelahnya. Menurut konvensi, fungsi yang namanya berakhiran ! mengubah salah satu argumennya, seperti sort! atau push!, sedangkan sort mengembalikan array baru.

Array, tuple, dan dictionary

StrukturLiteralCatatan
Vector[1, 2, 3]Berindeks 1, mutable, bertambah dengan push!
Matrix[1 2; 3 4]Spasi memisahkan kolom, ; memisahkan baris
Tuple(1, "a")Immutable, panjang tetap
Named tuple(name = "Ana", age = 30)Field diakses dengan .name
DictDict("a" => 1)Hash map mutable
SetSet([1, 2, 2])Nilai unik
v = [10, 20, 30]
v[1]          # 10   (first element)
v[end]        # 30
push!(v, 40)
A = [1 2; 3 4]
A * A         # matrix product: [7 10; 15 22]
A .* A        # element-wise:   [1 4; 9 16]
v .+ 1        # broadcasting:   [11, 21, 31, 41]
sqrt.([1, 4, 9])   # [1.0, 2.0, 3.0]

Sintaks titik disebut broadcasting: f.(x) menerapkan f pada setiap elemen, dan .+, .* bekerja elemen demi elemen. Julia menggabungkan rangkaian operasi bertitik menjadi satu perulangan.

Fitur khas: multiple dispatch

Sebuah fungsi Julia dapat punya banyak method. Saat dipanggil, Julia memilih method yang paling spesifik untuk tipe semua argumen. Ini menggantikan method kelas: tipe menyimpan data, dan perilaku ditambahkan dengan mendefinisikan method untuk tipe tersebut, bahkan dari paket lain.

abstract type Shape end
struct Circle <: Shape
    r::Float64
end
struct Rect <: Shape
    w::Float64
    h::Float64
end
area(c::Circle) = π * c.r^2
area(r::Rect) = r.w * r.h
shapes = [Circle(1.0), Rect(2.0, 3.0)]
println(round.(area.(shapes), digits = 2))   # [3.14, 6.0]

Karena Julia mengompilasi versi terspesialisasi dari sebuah fungsi untuk tipe argumen yang ditemuinya, panggilan pertama sebuah fungsi lebih lambat (karena termasuk kompilasi) dan panggilan berikutnya cepat. Gunakan mutable struct bila field harus berubah setelah dibuat.

Penanganan error

Julia memakai exception. Lempar tipe exception bawaan seperti ArgumentError atau DomainError, atau definisikan sendiri sebagai struct yang merupakan subtipe Exception. tryparse mengembalikan nothing alih-alih melempar exception.

function parse_age(s)
    n = tryparse(Int, s)
    n === nothing && throw(ArgumentError("not a number: $s"))
    n < 0 && throw(DomainError(n, "age must not be negative"))
    return n
end
try
    parse_age("abc")
catch e
    if e isa ArgumentError
        println("Error: ", e.msg)
    else
        rethrow()
    end
end
# Error: not a number: abc

Program lengkap kecil: frekuensi kata

text = "the cat and the hat and the bat"
counts = Dict{String,Int}()
for w in split(text)
    counts[w] = get(counts, w, 0) + 1
end
top = sort(collect(counts), by = last, rev = true)
for (word, n) in first(top, 2)
    println(word, " ", n)
end
# the 3
# and 2

split memecah string pada spasi, get mengembalikan default 0 untuk kata baru, collect mengubah dictionary menjadi vector berisi pasangan word => count, dan by = last mengurutkan berdasarkan jumlah.

Langkah selanjutnya

  • Manual resmi Julia di docs.julialang.org, mulai dari "Getting Started".
  • Halaman belajar di julialang.org, yang mendaftar tutorial, buku, dan kursus.
  • Baca bab "Performance Tips" dalam manual sebelum mengoptimalkan kode.
  • Jelajahi paket seperti DataFrames.jl, Plots.jl, dan DifferentialEquations.jl.

FAQ

Apakah Julia lebih cepat daripada Python?

Untuk kode dengan banyak perulangan dan pekerjaan numerik, Julia biasanya jauh lebih cepat daripada Python murni karena dikompilasi ke kode native. Python dengan library seperti NumPy bisa cepat untuk operasi vektor, jadi perbedaannya bergantung pada tugasnya.

Mengapa Julia mulai menghitung dari 1?

Julia mengikuti konvensi matematika dan bahasa seperti MATLAB, R, dan Fortran, di mana elemen pertama array berindeks 1.

Mengapa eksekusi pertama kode Julia saya lambat?

Julia mengompilasi setiap fungsi untuk tipe argumen saat pertama kali dipanggil. Panggilan berikutnya memakai ulang kode yang sudah dikompilasi, jadi ukurlah performa setelah panggilan pemanasan atau dengan paket benchmarking.

Apakah Julia gratis?

Ya. Julia adalah open source dengan lisensi MIT, dan hampir semua paketnya juga open source.

Semua tutorial pemrograman