Pernahkah mendengar istilah polyglot programming? Istilah ini sudah menjadi istilah yang umum dan barangkali banyak didengar oleh para developer yang sehari-hari memang berkutat dengan bahasa pemrograman dan peranti pengembangan. Polyglot programming merupakan penggunaan lebih dari satu bahasa pemrograman untuk menyelesaikan suatu masalah pemrograman. Kategori polyglot programming antara lain adalah:
- Penggunaan binding yang dibuat menggunakan suatu bahasa pemrograman tertentu (biasanya bahasa pemrograman aras sistem — atau aras rendah seperti C/C++, Assembly, Rust) ke suatu bahasa yang berada pada aras tinggi seperti Ruby, Python, dan lain-lain. Cara ini biasanya ditempuh untuk optimasi atau memang memerlukan function / procedure / library yang tidak ada di bahasa yang bersangkutan. Contoh: wxPython merupakan binding wxwidgets untuk Python untuk keperluan pembuatan aplikasi GUI.
- Fasilitas untuk mengeksekusi script / source code pada suatu bahasa tertentu. Contoh dari hal ini adalah Julia yang memungkinkan mengeksekusi source code Python sehingga memungkinkan akses terhadap banyak pustaka Python. Eksekusi ini biasanya dilakukan pada execution context yang berbeda.
- Penggunaan virtual machine bytecode yang bisa di-share oleh berbagai bahasa yang mendukung virtual machine tersebut. Contoh dari hal ini adalah JVM (Java Virtual Machine) yang secara default memerlukan bahasa pemrograman Java untuk menghasilkan bytecode .class. File-file bytecode tersebut bisa dibaca dan digunakan oleh bahasa lainnya yang dibuat pada JVM (misalnya Kotlin, Scala, Eta, Frege, dan lain-lain). Contoh lainnya ada pada CLR di dunia .NET yang bisa digunakan oleh berbagai bahasa seperti C#, F#, dan lain-lain. Jadi, dengan cara ini, bytecode merupakan tujuan akhir dan antar bahasa pemrograman bisa terjadi interoperabilitas karena memang berjalan pada VM yang sama dan bisa mengenali bytecode tersebut: source code harus dikompilasi terlebih dahulu untuk menghasilkan bytecode yang bisa memungkinkan interoperabilitas (sebagai contoh, Kotlin bisa mengakses berbagai file .jar di repo Maven yang dihasilkan oleh Java).
GraalVM merupakan hasil riset dari Oracle (berbasis JDK) yang bertujuan untuk memungkinkan menggunakan berbagai bahasa dalam satu execution context di atas VM tanpa melalui proses kompilasi ke bytecode. Jadi, bisa saja menggunakan Python (salah satu bahasa yang didukung oleh GraalVM) dan source code Python kita mengakses pustaka standar di NodeJS. Lebih lanjut, hasil dari source code bisa dikompilasi menjadi native images yang mempunyai waktu eksekusi lebih cepat daripada bytecode VM. Menarik? mari kita coba.
Saat ini GraalVM semakin mature dan saat tulisan ini dibuat, GraalVM memasuki versi 22.3.1. Instalasi GraalVM sangat mudah, hanya perlu mengambil binary di https://github.com/graalvm/graalvm-ce-builds/releases dan kemudian mengekstrak serta menambahkan path bin ke dalam env variable PATH (contoh berikut menggunakan fish):
set -x PATH /opt/software/graalvm/graalvm/bin $PATH
Anda bisa mengambil sesuai versi JDK yang anda pilih (saat ini: 11, 17, dan 19). Setelah itu, beberapa executable file untuk beberapa bahasa pemrograman / tools sudah tersedia. Default bahasa pemrograman yang tersedia adalah Java dan JavaScript. Selain itu, bisa digunakan gu (GraalVM Component Updater) untuk menginstall bahasa pemrograman lain (misalnya Python).
$ gu list
ComponentId Version Component name Stability Origin
---------------------------------------------------------------------------------------------------------------------------------
graalvm 22.3.1 GraalVM Core Supported
$ gu available
Downloading: Component catalog from www.graalvm.org
ComponentId Version Component name Stability Origin
---------------------------------------------------------------------------------------------------------------------------------
espresso 22.3.1 Java on Truffle Supported github.com
espresso-llvm 22.3.1 Java on Truffle LLVM Java librSupported github.com
js 22.3.1 Graal.js Supported github.com
llvm 22.3.1 LLVM Runtime Core Supported github.com
llvm-toolchain 22.3.1 LLVM.org toolchain Supported github.com
native-image 22.3.1 Native Image Early adopter github.com
native-image-llvm-backend22.3.1 Native Image LLVM Backend Early adopter (experimental) github.com
nodejs 22.3.1 Graal.nodejs Supported github.com
python 22.3.1 GraalVM Python Experimental github.com
R 22.3.1 FastR Experimental github.com
ruby 22.3.1 TruffleRuby Experimental github.com
visualvm 22.3.1 VisualVM Experimental github.com
wasm 22.3.1 GraalWasm Experimental github.com
Berikut adalah versi GraalVM dengan menggunakan JDK 11:
$ java -version
openjdk version "11.0.18" 2023-01-17
OpenJDK Runtime Environment GraalVM CE 22.3.1 (build 11.0.18+10-jvmci-22.3-b13)
OpenJDK 64-Bit Server VM GraalVM CE 22.3.1 (build 11.0.18+10-jvmci-22.3-b13, mixed mode, sharing)
$ javac -version
javac 11.0.18
$
Mari install js
, python
, dan nodejs
:
$ gu install js nodejs python
Downloading: Component catalog from www.graalvm.org
Processing Component: Graal.js
Processing Component: Graal.nodejs
Processing Component: GraalVM Python
Processing Component: Graal.js
Processing Component: LLVM.org toolchain
Processing Component: LLVM Runtime Core
Additional Components are required:
Graal.js (org.graalvm.js, version 22.3.1), required by: Graal.nodejs (org.graalvm.nodejs)
LLVM.org toolchain (org.graalvm.llvm-toolchain, version 22.3.1), required by: GraalVM Python (org.graalvm.python)
LLVM Runtime Core (org.graalvm.llvm, version 22.3.1), required by: GraalVM Python (org.graalvm.python)
Downloading: Component js: Graal.js from github.com
Downloading: Component nodejs: Graal.nodejs from github.com
Downloading: Component python: GraalVM Python from github.com
Downloading: Component org.graalvm.llvm-toolchain: LLVM.org toolchain from github.com
Downloading: Component org.graalvm.llvm: LLVM Runtime Core from github.com
Installing new component: LLVM Runtime Core (org.graalvm.llvm, version 22.3.1)
Installing new component: LLVM.org toolchain (org.graalvm.llvm-toolchain, version 22.3.1)
Installing new component: Graal.js (org.graalvm.js, version 22.3.1)
Installing new component: Graal.nodejs (org.graalvm.nodejs, version 22.3.1)
Installing new component: GraalVM Python (org.graalvm.python, version 22.3.1)
$ gu list
ComponentId Version Component name Stability Origin
---------------------------------------------------------------------------------------------------------------------------------
graalvm 22.3.1 GraalVM Core Supported
js 22.3.1 Graal.js Supported github.com
llvm 22.3.1 LLVM Runtime Core Supported github.com
llvm-toolchain 22.3.1 LLVM.org toolchain Supported github.com
nodejs 22.3.1 Graal.nodejs Supported github.com
python 22.3.1 GraalVM Python Experimental github.com
$
Hasil instalasi adalah sebagai berikut:
$ js --version
GraalVM JavaScript (GraalVM CE Native 22.3.1)
$ node -v
v16.18.1
$ python --version
GraalVM Python 3.8.5 (GraalVM CE Native 22.3.1)
$
Catatan:
python
juga bisa dieksekusi menggunakangraalpy
Mari kita coba Python.
$ graalpy
Python 3.8.5 (Thu Jan 19 19:16:44 UTC 2023)
[Graal, GraalVM CE, Java 11.0.18] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.platform
'linux'
>>> import os
>>> os.name
'posix'
>>> sys.platform
'linux'
>>> sys.copyright
'Copyright (c) Oracle and/or its affiliates. Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl.'
>>> import platform
>>> platform.python_version()
'3.8.5'
>>>
Sekarang mari mencoba Python dan R pada satu source code. Install R dengan perintah gu berikut:
$ gu install R
Downloading: Component catalog from www.graalvm.org
Processing Component: FastR
Downloading: Component R: FastR from github.com
Installing new component: FastR (org.graalvm.R, version 22.3.1)
NOTES:
---------------
FastR should work out of the box on most Linux distributions and recent MacOS versions. Run the following script to check FastR requirements and create a personal R packages library directory:
/home/bpdp/software/java-dev-tools/graalvm-ce-java11-22.3.1/languages/R/bin/configure_fastr
The R component comes without native image by default. If you wish to build the native image, which provides faster startup, but slightly slower peak performance, then run the following:
gu rebuild-images R
The native image is then used by default. Pass '--jvm' flag to the R or Rscript launcher to use JVM instead of the native image. Note that the native image is not stable yet and is intended for evaluation and experiments for curious users. Some features may not work in the native image mode. Most notably, the --polyglot switch works only in JVM mode (when --jvm is used).
See http://www.graalvm.org/docs/reference-manual/languages/r for more.
$
Kita akan mencoba menggabungkan source code Python dengan R. Buat file testgraal.py yang memanfaatkan R sebagai berikut:
import polyglot
array = polyglot.eval(language="R", string="c(1,2,42,4)")
print(array[2])
Setelah itu jalankan:
$ graalpy --polyglot --jvm testgraal.py
42.0
$
Tentu jika sudah melibatkan banyak libraries, ada kemungkinan proses dan source code akan lebih kompleks. Hal ini tentu tidak mudah, tapi pada fase ini, kita sudah mengetahui bahwa kita bisa menggunakan lebih dari satu bahasa pemrograman pada satu masalah pemrograman.
The next adventure should be exciting. Happy hacking!