Apa itu Odin ?

Bahasa berorientasi data dengan memori dan alur kendali eksplisit.

Daftar isi

Topik ini memperkenalkan identitas bahasa pemrograman Odin beserta prinsip desain yang menopangnya. Pembahasan mencakup arti orientasi data, kebijakan memori dan alur kendali yang eksplisit, sistem context untuk alokator, serta defer untuk pembersihan deterministik. Topik ditutup dengan program kecil yang benar-benar dijalankan, sehingga setiap prinsip dapat dilihat bekerja pada kode dan keluaran nyata.

Bahasa berorientasi data#

Odin adalah bahasa pemrograman tujuan umum yang didesain berorientasi data (data-oriented), yakni tata letak data dirancang lebih dahulu sebelum kode yang mengolahnya. README resmi proyek menyebut Odin sebagai general-purpose programming language dengan penekanan pada performa tinggi serta tipe data berorientasi data yang tersedia langsung di dalam bahasa. Moto resminya, The Data-Oriented Language for Sane Software Development, merangkum posisi tersebut. Di dalam bahasa ini, struct dan array bukan pelengkap melainkan bahan bangunan utama karena keduanya menyatakan tata letak memori secara langsung.

Odin diciptakan oleh Ginger Bill dan dikembangkan secara terbuka di GitHub sejak 2016. Arah desainnya mengejar bahasa yang kecil dan konsisten, dan FAQ resmi proyek menyatakan bahwa spesifikasi bahasa seutuhnya harus mampu dihafal oleh manusia biasa. Konsistensi ini terlihat pada aturan deklarasi, alur kendali, dan pengelolaan memori yang mengikuti satu kaidah dari awal hingga akhir.

Dari sisi kecepatan dan interop, yaitu kemudahan menggabungkan kode dengan pustaka lain, Odin berada dekat dengan C, sedangkan dari sisi ergonomi, Odin jauh dari rasa C. Sintaksnya ringkas, tipenya berbeda dengan jelas (distinct typing), dan pustaka standarnya terbawa bersama compiler tanpa langkah pemasangan tambahan. Profil semacam ini menjadikan Odin kandidat untuk program yang menuntut performa penuh dan kendali memori yang terbuka.

Orientasi data paling mudah dilihat pada tata letak array. Diagram berikut menampilkan empat nilai struct berdampingan dalam satu blok memori, dan setiap struct pada diagram terdiri atas dua field.

Empat nilai struct berdampingan dalam memoriSuhu_Kota 0kota : stringcelsius : f640Suhu_Kota 1kota : stringcelsius : f6424Suhu_Kota 2kota : stringcelsius : f6448Suhu_Kota 3kota : stringcelsius : f6472byte ke- (96 byte total)
Empat nilai Suhu_Kota berdampingan dalam satu blok memori

Setiap kotak pada diagram adalah satu nilai struct yang menempati 24 byte berurutan. Karena ukurannya tetap, alamat awal setiap nilai struct berjarak sama, sehingga perulangan pada array berjalan lurus melalui memori tanpa melompat. Data yang berdampingan seperti ini lebih cepat dilalui daripada data yang tersebar melalui rantai pointer, dan pola inilah inti dari pemikiran berorientasi data.

Memori dan alur kendali yang eksplisit#

Odin tidak memiliki exception, tidak memiliki garbage collector, dan tidak menyembunyikan alur kendali. Tiga ketiadaan ini bukan kekurangan yang menunggu diisi, melainkan pilihan desain yang menuntut segala keputusan dinyatakan secara terbuka. Kode yang terbaca dari atas ke bawah adalah kode yang dieksekusi, sehingga tidak ada langkah otomatis yang disembunyikan compiler.

Kesalahan yang dapat dipulihkan ditangani tanpa exception. Proc, kependekan dari procedure, adalah padanan fungsi pada Odin, dan error dikembalikan sebagai bagian dari nilai kembalian berganda (multiple return values), sehingga jalur error terlihat jelas di tempat pemanggilannya. Tidak ada konstruk try-catch yang memindahkan kendali program ke tempat lain secara diam-diam.

Memori dikelola secara manual sebagaimana dinyatakan dalam dokumentasi resmi, yaitu alokasi, pelacakan, dan pelepasan memori menjadi tanggung jawab penulis program. Odin membantu lewat alokator yang dapat diganti-ganti dan pemeriksaan tipe yang ketat, tetapi tidak ada garbage collector yang menyapu memori diam-diam. Perulangan, percabangan, dan penangguhan eksekusi menjadi perangkat lengkap alur kendalinya, dan setiap perubahan arah eksekusi selalu terlihat di tempat ia ditulis.

Alokator eksplisit melalui context#

Alokasi memori di Odin mengalir melalui sebuah variabel khusus bernama context. Setiap pemanggilan proc membawa context secara implisit, dan field context.allocator menjadi alokator (allocator) default untuk make, new, serta tipe data dinamis seperti [dynamic]u8. Penulis program dapat mengalihkan field tersebut ke alokator lain, misalnya alokator arena, dan seluruh alokasi setelah titik itu mengikuti alokator yang dipilih.

odin Contoh: mengalihkan alokator default
// tidak-dijalankan
context.allocator = arena_allocator(&arena)
data := make([dynamic]u8, 16) // dialokasikan oleh alokator arena

Mekanisme ini menjaga tanda tangan proc tetap bersih karena alokator tidak diteruskan dari proc ke proc secara manual. Penggantian strategi memori dilakukan di satu titik, dan proc-proc di bawahnya tidak perlu disunting. Alokator arena, misalnya, tidak melepaskan alokasi satu per satu, melainkan mengosongkan seluruh buffer-nya sekaligus, sehingga cocok untuk data yang hanya hidup selama satu putaran kerja (frame).

defer untuk pembersihan deterministik#

Pernyataan defer menangguhkan eksekusi sebuah pernyataan sampai lingkup (scope) yang memuatnya berakhir. Pembersihan memori dapat ditulis tepat di bawah alokasinya, lalu dieksekusi tepat sebelum lingkup selesai. Pola ini menempatkan alokasi dan pelepasan berdampingan, sehingga kesalahan pembersihan lebih mudah terlihat saat ditinjau.

odin Contoh: defer dieksekusi saat lingkup berakhir
// tidak-dijalankan
{
	data := make([dynamic]u8, 64)
	defer delete(data)
	// data dipakai di dalam lingkup ini
} // delete(data) dieksekusi di sini, tepat sebelum lingkup berakhir

Blok defer dieksekusi dalam urutan terbalik dari deklarasinya, sehingga pembersihan yang ditulis paling akhir justru berjalan paling dahulu. Karena pembersihan bergantung pada lingkup dan bukan pada garbage collector, masa hidup setiap alokasi dapat dibaca langsung dari batas blok {} yang memuatnya. Prinsip yang sama berlaku untuk penutupan berkas, pelepasan kunci, dan pengembalian memori ke arena.

Program kecil pertama#

Prinsip-prinsip di atas dapat dilihat pada program berikut. Program menyimpan pengukuran suhu empat kota dalam satu array, menampilkan setiap pengukuran, lalu menghitung rata-ratanya. Definisi struct diletakkan di tingkat package dan proc main menjadi titik masuknya.

odin main.odin
package main

import "core:fmt"

Suhu_Kota :: struct {
	kota:    string,
	celsius: f64,
}

main :: proc() {
	pengukuran := [4]Suhu_Kota{
		{"Bandung", 24.5},
		{"Denpasar", 30.2},
		{"Jayapura", 31.5},
		{"Medan", 29.0},
	}

	fmt.println("Pengukuran suhu empat kota:")
	for p, i in pengukuran {
		fmt.printf("%d. %-9s %.1f derajat\n", i + 1, p.kota, p.celsius)
	}

	jumlah := 0.0
	for p in pengukuran {
		jumlah += p.celsius
	}
	fmt.printf("Rata-rata: %.2f derajat\n", jumlah / f64(len(pengukuran)))
}
bash
# jalankan program dari direktori topik
odin run main.odin -file
text Keluaran
Pengukuran suhu empat kota:
1. Bandung   24.5 derajat
2. Denpasar  30.2 derajat
3. Jayapura  31.5 derajat
4. Medan     29.0 derajat
Rata-rata: 28.80 derajat

Deklarasi Suhu_Kota menyatakan tata letak setiap anggota secara eksplisit, yaitu string untuk nama kota dan f64 untuk suhunya. Empat nilai disusun dalam satu array yang menempati memori secara berdampingan, dan perulangan for p, i in pengukuran memberikan nilai beserta indeks setiap anggota secara berurutan. Konversi f64(len(pengukuran)) menggambarkan kebijakan bahasanya, yaitu konversi antartipe harus ditulis dan tidak dilakukan diam-diam. Keluaran di atas adalah keluaran asli program pada compiler dev-2026-10, dan setiap angkanya dapat dihitung ulang dari datanya.

Ringkasan#

  • Odin adalah bahasa tujuan umum yang berorientasi data, diciptakan oleh Ginger Bill, dan dikembangkan secara terbuka sejak 2016.
  • Bahasa ini tidak memiliki exception dan garbage collector, sehingga error ditangani melalui nilai kembalian berganda dan memori dikelola secara manual dengan alokator yang jelas.
  • Alokasi mengalir melalui context dengan context.allocator sebagai alokator default, dan defer menjamin pembersihan dijalankan saat lingkup berakhir dalam urutan terbalik dari deklarasinya.

Referensi#