Jenis Bahasa Pemrograman dalam Software Engineering
Sat. Oct 28th, 2023 10:29 PM12 mins read
Jenis Bahasa Pemrograman dalam Software Engineering
Source: Bing Image Creator - Programming Languages

“Bahasa” dalam software engineering adalah perantara antara manusia dengan mesin agar dapat berkomunikasi mengirimkan instruksi yang diinginkan terhadap program yang dibuat. Dalam software engineering, pemilihan penggunaan bahasa cukup penting saat memulai project. Pilihan bahasa yang ingin digunakan perlu disesuaikan dengan produk yang ingin dikembangkan. Right tools for the right jobs. Ibaratnya kalau dari Jakarta mau ke Bandung paling enak ya naik mobil. Kalau dari Jakarta mau ke Bali enaknya ya naik pesawat. Dari Jakarta ke Bandung naik pesawat juga bisa, tapi terlalu berlebihan. Dari Jakarta ke Bali naik mobil juga bisa, tapi ga worth it. Masing-masing bahasa punya keunikan dan keunggulan tersendiri. Bahasa tersebut dibagi ke dalam beberapa kategori seperti Interaction Level, Paradigm, Typing System, dan Execution System.

Interaction Level

Kategori pertama adalah berdasarkan level interaksi pemrograman antara manusia dengan mesin. Setidaknya ada 3 level interaksi, yaitu Low-Level, High-Level, dan Intermediary.

Low-Level Languages

Bahasa Low-Level adalah bahasa yang ditulis dalam bahasa mesin dan dieksekusi langsung oleh mesin. Ini adalah jenis bahasa paling cepat dibanding jenis lainnya karena tidak perlu translate, melainkan instruksinya langsung dimengerti oleh mesin dan punya akses langsung ke hardware dan memory. Tapi bahasa Low-Level adalah bahasa yang paling kompleks, sulit dibaca, manual memory management, dan sulit untuk dikembangkan. Makanya bahasa Low-Level jarang kita temukan di industri komersil. Bahasa seperti ini biasanya digunakan untuk develop aplikasi super cepat di mana performa adalah hal yang super kritikal. Contohnya pada aplikasi driver yang mengoneksikan antara hardware dengan software. Contoh bahasa Low-Level adalah Assembly dan Machine Code.

High-Level Languages

Bahasa High-Level adalah bahasa yang didesain agar mudah dimengerti manusia. Ini kebalikan dari bahasa Low-Level. Bahasanya lebih user-friendly, maintainable, dan gampang dipelajari. Memory management di-handle otomatis, walau ada juga yang memiliki opsi handle memory secara manual. Ini adalah jenis bahasa yang paling sering dijumpai di industri. Contoh bahasa High-Level adalah Java, JavaScript, Go, PHP, C#, Python, dan hampir semua bahasa pemrograman yang kita kenal.

Intermediate Languages

Contoh bahasa Intermediate atau Mid-Level adalah C dan C++. Menurut sebagian expert jaman dulu, bahasa C dan C++ itu termasuk High-Level karena bukan bahasa mesin dan memiliki abstraksi yang ga bisa dimengerti langsung oleh mesin. Menurut sebagian lagi bahasa C dan C++ termasuk Low-Level karena punya akses langsung ke memory dan di-handle manual. Perbedaan pendapat itu terjadi karena terdapat pergeseran makna High-Level dan Low-Level. Jadinya ada sebagian lagi yang mengategorikan C dan C++ sebagai Bahasa Intermediate. Implementasinya cukup kompleks dibanding bahasa High-Level, namun masih lebih mudah dibaca dibanding bahasa Low-Level. Secara performa lebih cepat dari bahasa High-Level, tapi ga secepat bahasa Low-Level. Bahasa seperti ini biasanya digunakan untuk mengembangkan aplikasi di mana performa sangat kritikal, tapi instruksinya masih bisa dimengerti manusia. Aplikasi yang umumnya menggunakan bahasa ini adalah sistem database dan sistem operasi.

Paradigm

Paradigm adalah kategori berdasarkan pendekatan struktur dari sebuah code. Paradigma bahasa umumnya terdiri dari Procedural Programming, Object Oriented Programming, Functional Programming, dan Multi-Paradigm Programming.

Procedural Programming

Procedural Programming adalah bahasa yang ditulis secara step-by-step. Konsepnya seperti stack atau tumpukan instruksi. Isinya kumpulan instruksi yang ditulis secara berurutan. Contoh bahasa yang menggunakan paradigma ini adalah C, PHP versi 5 ke bawah, Pascal, Assembly, dan lainnya. Berikut contoh prosedur membuat hello world menggunakan Assembly yang gw copy-paste dari google🫣:

Copy
section .data
	hello:     db 'Hello, World!',10    ; 'Hello, World!' plus a linefeed character
	helloLen:  equ $-hello             ; Length of the 'Hello world!' string

section .text
	global _start

_start:
	mov eax,4            ; The system call for write (sys_write)
	mov ebx,1            ; File descriptor 1 - standard output
	mov ecx,hello        ; Put the offset of hello in ecx
	mov edx,helloLen     ; helloLen is a constant, so we don't need to say
	                     ;  mov edx,[helloLen] to get it's actual value
	int 80h              ; Call the kernel
	mov eax,1            ; The system call for exit (sys_exit)
	mov ebx,0            ; Exit with return "code" of 0 (no error)
	int 80h;

Instruksinya ditulis dari awal sampai akhir secara berurutan.

Object Oriented Programming (OOP)

Object Oriented Programming (OOP) adalah bahasa pemrograman yang strukturnya menggunakan konsep object. Semua komponen dalam bahasa tersebut dibungkus dalam bentuk object yang nantinya bisa digunakan oleh komponen object lainnya. Struktur data dan function disimpan ke dalam sebuah class yang nantinya akan dibuatkan object untuk dieksekusi. Ini yang membedakannya dengan paradigma lainnya. Contoh bahasa yang menggunakan paradigma OOP adalah C++, C#, Java, dan lain-lain. Contoh OOP di Java seperti ini:

Copy
public class Addition {
    void sum(int x, int y){
        Sytem.out.println(x + y);
    }

    public static void main(String[] args) {
        Addition addition = new Addition();
        addition.sum(1, 3);
    }
}

Kita define dulu classnya, trus dibungkus logic penambahan di dalamnya. Lalu bikin objectnya dan execute sum().

Functional Programming (FP)

Functional Programming (FP) adalah bahasa pemrograman yang strukturnya menggunakan konsep function. Berbeda dengan OOP, di sini semua komponen dalam bahasa tersebut dibungkus ke dalam bentuk function yang nantinya dapat digunakan oleh komponen function lainnya. Kita juga bisa menggunakan function sebagai parameter pada function lain atau sebagai return value sebuah function (Higher-Order Function), inilah yang paling membedakan antara function pada FP dengan function di paradigma lain. Contoh bahasa yang menggunakan paradigma FP yang terkenal adalah Clojure, Haskell dan Lisp. Contoh FP seperti ini di Clojure:

Copy
(defn sum [x y myfunction]
    (myfunction (+ x y))
)

(sum 10 15 println)

Di sini kita define function logic penambahan dan membungkus function println sebagai parameter argument.

Multi-Paradigm Programming

Ini adalah bahasa pemrograman yang memiliki paradigma lebih dari satu. Jadi kita bisa bebas menggunakan paradigma Procedural, OOP, maupun FP, atau bahkan gabungannya. Beberapa bahasa pemrograman modern jaman sekarang menggunakan Multi-Paradigm karena lebih variatif. Ada beberapa hal yang enak di-handle menggunakan OOP, dan ada sebagian lagi yang enaknya di-handle menggunakan FP. Contoh bahasa yang menggunakan Multi-Paradigm adalah JavaScript, Go, Java sejak versi 8, dan beberapa bahasa modern lainnya. Pada JavaScript contohnya seperti ini:

Copy
let sum = (x, y, myFunction) => myFunction(x + y);

class Multiplier{
  multiply(x, y){
    console.log(x * y);
  }
}

let multiplier = new Multiplier();
multiplier.multiply(7, 8);

sum(3, 7, console.log);

Kita define logic penambahan dan membungkus function console.log() sebagai parameter argument seperti FP dan logic perkalian didefine seperti OOP.

Execution System

Kategori selanjutnya adalah berdasarkan cara code tersebut dieksekusi. Cara code dieksekusi dikategorikan menjadi Compiled, Interpreted, Just in Time Compiled, dan Transpiled.

Compiled Language

Compiled Language adalah bahasa yang instruksinya di-translate ke bahasa mesin secara keseluruhan. Bahasa tersebut tidak langsung dimengerti mesin, melainkan ada proses compile terlebih dahulu. Jika ada kesalahan syntax maka compile akan gagal, errornya bisa segera diketahui. Setelah di-compile baru lah instruksinya bisa dimengerti oleh mesin. Analoginya seperti saat kita menulis instruksi dalam Bahasa Indonesia untuk dieksekusi oleh orang yang cuma ngerti Bahasa Arab. Jadi kita tulis dulu seluruh instruksinya panjang lebar ke dalam Bahasa Indonesia, lalu dicek lagi apakah kata-katanya udah benar, abis itu baru kita translate pakai Google Translate ke Bahasa Arab dan diberikan ke orang tersebut. Si penerima langsung paham apa aja instruksi yang kita tulis karena udah full Bahasa Arab. Walaupun hasil akhirnya adalah bahasa mesin, tapi tetap saja bahasa tersebut tidak secepat bahasa Low-Level karena terdapat beberapa fitur dari bahasa tersebut yang bisa membatasi kinerja aplikasi seperti handle memori otomatis dan beberapa level abstraksi. Analoginya sama seperti hasil terjemahan Google Translate yang kadang kurang pas, jadi yang ngebaca perlu waktu memproses makna instruksi tersebut. Tapi Compiled Language masih cenderung lebih cepat performanya dibanding Interpreted Language karena hasil akhirnya dalam bentuk bahasa mesin. Banyak perusahaan komersil yang membutuhkan produk dengan performa tinggi menggunakan Compiled Language seperti e-commerce, bank, dan sebagainya. Contoh Compiled Language adalah C, C++, C#, Java, Go, Erlang, Rust, dan masih banyak lagi.

Interpreted Language

Interpreted Language adalah bahasa yang instruksinya di-translate tiap kalimat satu per satu, bukan secara keseluruhan. Analoginya seperti saat kita ngasih instruksi dalam Bahasa Indonesia untuk dieksekusi oleh orang yang cuma ngerti Bahasa Arab. Kita ngomong dulu satu kalimat untuk instruksi pertama, trus di-translate ke Bahasa Arab. Lalu setelah orang tersebut melakukan instruksi pertama, kita ngomong lagi untuk instruksi kedua dan di-translate lagi ke Bahasa Arab, begitu seterusnya. Jadi tiap kita ngomong di-translate dulu satu per satu. Makanya secara performa Interpreted Language itu tidak secepat Compiled Language. Kalau ada syntax error ketahuannya saat code dieksekusi karena ga ada proses compile yang menvalidasi keseluruhan syntax seperti Compiled Language. Tapi bukan berarti Interpreted Language ini jelek. Kelebihan Interpreted Language adalah bisa dijalankan langsung tanpa compile. Ibaratnya kita ga perlu cek ulang instruksi tersebut sebelum disampaikan, tapi langsung tinggal ngomong -> translate -> eksekusi. Gitu aja terus. Proses develop aplikasinya lebih simple dibanding Compiled Language. Saat ada perubahan ketika develop aplikasi yang sedang dijalankan, perubahan tersebut biasanya bisa langsung dieksekusi. Berbeda dengan Compiled Language, ketika terjadi perubahan code maka harus di-compile ulang. Interpreted Language biasanya digunakan oleh aplikasi yang kebutuhan performa eksekusinya tidak terlalu kritikal namun butuh proses develop yang cepat seperti Sistem Informasi Sekolah, Aplikasi Perkantoran, Blog, Data Modelling, dan sebagainya. Contoh Interpreted Language adalah PHP, JavaScript, Python, Perl, Ruby, dan semacamnya.

Just in Time (JIT) Compiled Language

Karena Interpreted Language itu cenderung lambat dan Compiled Language itu cederung ribet, maka muncul jalan tengah, yaitu Just In Time (JIT) Compiled Language. Ini sebenarnya engine khusus sebagai penengah dari kedua masalah di atas. Di sini bahasa tersebut masih di-translate satu per satu seperti Interpreted Language, tapi saat eksekusi selanjutnya untuk hal yang sama tidak perlu translate lagi. Analoginya seperti kita ngasih instruksi pertama pakai Bahasa Indonesia ke orang yang cuma ngerti Bahasa Arab: “Cari orang dengan nama Obama!”, itu akan di-translate ke Bahasa Arab. Lalu setelah instruksi tersebut dilaksanakan, lanjut ke instruksi kedua: “Cari negara dengan nama Brunei!”, itu juga akan di-translate ke Bahasa Arab. Setelah instruksi kedua dilakukan, kita kembali menginstruksikan: “Cari orang dengan nama Obama!”. Nah, di sini ga perlu translate ulang, karena si orang Arab udah ngerti, bahwa itu artinya dia disuruh nyari orang bernama Obama sebab sebelumnya udah pernah dapat instruksi yang sama💡. Makanya secara performa lebih cepat dari Interpreted Language karena tidak perlu translate ulang untuk hal yang sama, tapi tetap saja ga secepat Compiled Language karena masih di-translate satu per satu di awal. Beberapa Interpreted Language yang lebih modern biasanya memiliki engine ini, seperti JavaScript V8 engine yang didevelop oleh Chrome dan Python Cinder yang didevelop oleh Instagram. Di Java ada 2x proses compile, yaitu dari source code ke JVM byte code secara Compiled saat build package, dan dari JVM byte code ke bahasa mesin secara JIT Compiled saat dijalankan di Virtual Machine. Makanya di Java itu ada pemanasan dulu saat pertama kali dijalankan sehingga di awal agak lambat karena menggunakan JIT Compiled di JVM. Namun setelah itu dia akan berjalan cepat layaknya bahasa Compiled.

Transpiled Language

Transpiled Language adalah bahasa yang di-translate ke bahasa High Level lainnya, bukan ke bahasa mesin. Ini karena dia ga ada runtime sendiri pada suatu platform sehingga butuh di-translate ke bahasa lain sebagai perantara. Analoginya seperti saat kita menulis instruksi dalam Bahasa Minangkabau untuk dieksekusi oleh orang yang cuma ngerti Bahasa Arab. Karena translator Bahasa Minangkabau ke Bahasa Arab langsung ga ada, maka perlu translate dulu ke Bahasa Indonesia, baru setelah itu translate lagi ke Bahasa Arab. Contoh yang paling terkenal adalah TypeScript. Browser ga bisa menerjemahkan TypeScript ke bahasa mesinnya sehingga perlu di-transpiled dulu ke JavaScript. Setelah di-transpiled, codenya akan jadi full JavaScript. Kelebihannya, bahasa ini biasanya punya fitur yang dianggap lebih baik daripada bahasa perantaranya. Orang-orang lebih suka ngoding di TypeScript daripada JavaScript langsung karena maintain code di TypeScript dianggap lebih baik berkat fitur type-check agar bisa mendeteksi bugs tipe data dari awal.

Typing System

Kategori ini berdasarkan cara handle tipe data. Secara umum terbagi dari Static Type, Dynamic Type, Inferred Type, Duck Type, dan Structural Type.

Static Type

Static Type adalah bahasa pemrograman yang tipe datanya harus ditulis dan ga bisa diubah saat runtime. Keunggulannya, secara performa lebih baik dibanding Dynamic Type karena compiler memberitahu mesin tipe datanya sehingga dapat dioptimasi. Selain itu, Static Type dapat mempermudah development. Misalnya ada function dengan return value, kita bisa tahu tipe data value tersebut sehingga mengurangi human error saat development. Contoh bahasa yang menggunakan Static Type adalah Java, C, C++, C#, dan sebagian besar Compiled Language menggunakan Static Type. Contohnya pada C# seperti berikut:

Copy
class Program{
	int myInteger = 5;
	bool myBool = true;
	string myText = "Hello";

	int Sum(int x, int y){
		return x + y;
	}
}

Dynamic Type

Dynamic Type atau Loosely Type adalah bahasa pemrograman yang tipe datanya ga ditulis dan bisa diubah saat runtime. Keunggulannya, code jadi lebih simple dibanding Static Type. Tapi di sisi lain juga bisa mempersulit development karena kita ga tau suatu function itu valuenya apa, sehingga bisa mengakibatkan human error. Mayoritas Interpreted Language menggunakan Dynamic Type. Bahasa yang menggunakan Dynamic Type yang paling simple adalah PHP. Contohnya seperti ini:

Copy
<?php
$word = "hello world";
$myNumber = 6;

function sum($x, $y){
	return $x + $y;
}
?>

Untungnya sejak PHP 7 ada fitur deklarasi tipe data untuk mempermudah development😃.

Inferred Type

Inferred Type adalah Static Type yang mirip Dynamic Type. Ini sebenarnya Compiled Language dengan Static Type, tapi bisa ditulis tanpa tipe data. Compiler akan menebak tipe datanya saat compile berdasarkan value yang ditulis. Hasil akhirnya nanti sama seperti Static Type. Contoh bahasa yang menggunakan Inferred Type adalah Kotlin, Groovy, Java sejak versi 11, dan beberapa bahasa lain. Contohnya pada Kotlin kita bisa menulis seperti ini saat develop:

Copy
fun main() {
	val contoh = "hello world!"
	val angka = 2
	println(contoh.split(" "))
}

Saat compile, compiler akan menerjemahkan itu masing-masing sebagai tipe data String dan int karena saat assign value menggunakan string literal dan integer number. Compiler akan mendeteksi method split dari tipe data String pada variable contoh. Jika variable contoh dideklarasi pakai angka dan kita memanggil method split, maka akan compile error.

Duck Type

Duck Type didefinisikan sebagai: “Jika dia berjalan seperti bebek, bersuara seperti Bebek, maka dia adalah Bebek!”. Jadi tipe data yang punya behavior yang sama, walaupun secara struktur tidak semuanya sama, maka itu bisa compatible saat runtime. Contoh bahasa yang paling terkenal menggunakan Duck Type adalah JavaScript dan Python. Contoh codenya seperti ini pada Python:

Copy
class Bird:
    def fly(self):
        print("I'm a Bird, because I can fly!")
    def egg(self):
        print("I have a eggs")

class Superman:
    def fly(self):
        print("I can fly too! Am I a Bird?")
    def power(self):
        print("I have superpower")

def execute(bird):
    bird.fly()

execute(Bird())
execute(Superman())

Meskipun secara tipe & struktur keduanya beda, Bird ada behavior egg() dan Superman ada behavior power(), tapi keduanya compatible pada execute(bird) karena sama-sama memiliki behavior fly().

Structural Type

Structural Type merupakan Static Type yang mirip dengan Duck Type. Perbedaannya dengan Duck Type adalah pada Structural Type hanya tipe data yang memiliki struktur sama persis yang compatible. Contoh bahasa yang menggunakan Structural Type adalah TypeScript dan Go. Contohnya pada TypeScript seperti ini:

Copy
interface Bird {
  fly(): void;
  egg(): void;
}

interface Chicken {
  fly(): void;
  egg(): void;
}

interface Superman {
  fly(): void;
}

let bird: Bird = {
  fly(): void {
    console.log("I can fly!");
  },
  egg(): void {
    console.log("I have eggs!");
  },
};

let chicken: Chicken = {
  fly(): void {
    console.log("I can fly too!?");
  },
  egg(): void {
    console.log("I also have eggs!");
  },
};

let superman: Superman = {
  fly(): void {
    console.log("I can fly! Am I a Bird?");
  },
};

function execute(bird: Bird){
  bird.fly();
};

execute(chicken);
execute(bird);

Meskipun Chicken beda tipe dengan Bird dan tidak mengimplementasi interface Bird, tapi Chicken compatible pada function execute(bird) karena strukturnya sama persis, yaitu memiliki behavior fly() dan egg(). Sedangkan Superman tidak compatible karena hanya ada behavior fly() tanpa behavior egg().

Best Programming Language

Stop Designing Your Apps for Millions of Users When You Don't Even Have 100.

Anonymous

Seringkali orang-orang over-engineering dan mengikuti suatu hype padahal belum tentu permasalahan yang mereka miliki butuh itu. Bahasa pemrograman terbaik adalah bahasa yang menyelesaikan permasalahan client apa pun jenisnya. Client ga peduli kita bikin aplikasi pake bahasa apa, yang penting masalahnya selesai sesuai requirement. Jika bahasa yang paling dipahami adalah Python dan system yang diinginkan client bukan system yang membutuhkan komputasi cepat, maka lebih baik develop dengan bahasa itu daripada belajar bahasa baru. Atau jika client memiliki requirement yang sederhana dengan deadline yang ketat, dan kita memiliki pengalaman membangun aplikasi menggunakan JavaScript dengan cepat, maka itu lebih worth it daripada deadline ga kekejar. Atau jika client memang membutuhkan aplikasi dengan komputasi cepat, maka pada kasus ini memang lebih baik menggunakan bahasa seperti Rust, Go, Java, C#, dan sebagainya. Tentunya masing-masing pendekatan punya kelebihan dan kekurangan. Contohnya dengan JavaScript kita bisa develop lebih cepat karena ga perlu mikirin data type, tapi dengan konsekuensi tiap ada maintenance kita perlu cek lagi value tersebut apa. Sedangkan pada Rust meskipun developmentnya lebih ribet, tapi dengan benefit dapat mengurangi celah bugs dari awal. Beberapa bahasa jadi andalan industri tertentu karena dukungan dari bahasanya. Kayak AI rata-rata dibuat pakai Python karena library AI di sana lebih lengkap dibanding bahasa lainnya. Perbankan rata-rata pakai Java karena butuh ekosistem yang matang dan performa yang bisa diandalkan. Database rata-rata pakai C atau C++ karena pengelolaan memorinya lebih advanced.

Verdict

Itulah kumpulan jenis bahasa pemrograman berdasarkan Interaction Level, Paradigm, Typing System, dan Execution System. Secara umum Compiled Language & Static Type lebih cepat daripada Interpreted Language & Dynamic Type karena menjadi bahasa mesin seutuhnya dan dioptimasi oleh mesin sebab tipe datanya diketahui mesin. Tapi Interpreted Language & Dynamic Language menawarkan proses development yang simple dibanding Compiled Language & Static Type. Jadi sebelum memilih bahasa pemrograman perlu dipertimbangkan beberapa hal di atas. Ga jarang beberapa produk yang sebelumnya menggunakan Interpreted Language migrasi ke Compiled Language karena alasan performa eksekusi yang menjadi kritikal. Seperti Facebook yang dulunya pakai PHP migrasi dengan cara menciptakan bahasa pemrograman sendiri, yaitu Hack dengan syntax mirip PHP tapi dengan metode eksekusi compile. Spotify saat awal dibangun menggunakan Python, tapi sekarang hampir semua servicenya migrasi ke Java. Shopify dari Ruby saat masih monolith, migrasi ke Rust saat jadi microservices. Di Indonesia ada e-commerce yang dulu menggunakan Perl, sekarang migrasi ke Go. Ada lagi aplikasi pemesanan tiket yang dulunya PHP lalu migrasi ke Java. Untuk instansi pemerintahan atau swasta non-IT mereka cenderung menggunakan Interpreted Language karena kebutuhan systemnya emang ga sekompleks perusahaan IT. Jadi ga ada yang salah antara Interpreted Language dan Compiled Language, balik lagi tergantung kebutuhan, bukan soal keren atau adu canggih. Beberapa produk yang menggunakan microservices kadang memiliki lebih dari satu bahasa yang digunakan tergantung spesifik kebutuhannya. Contohnya Instagram yang menggunakan Python sebagai backend karena fitur utamanya kurang lebih seperti blog, tapi untuk fitur yang lebih kritikal seperti DM Instagram yang didesain untuk mengirim pesan secara real time menggunakan Erlang. Youtube juga sama, sebagian besar mereka menggunakan Python, tapi untuk hal kritikal seperti streaming menggunakan C++, dan untuk transcoding & encoding video ke berbagai format menggunakan Go.

© 2026 · Ferry Suhandri